The misbehaving app uses a ownerdrawn, CListCtrl-derived list. When I click on a cell not in the first column the cell gets selected. But on wine I can see that the selection flashes shortly and disappears right again (Surprisingly it works when I click in the first column. As my application uses the same code for all columns it must be something else.). After putting some debug messages in my code I found that on Windows after the left-button-down event a left-button-click event is generated, no matter how long I hold the button before releasing. On wine there is no click event but a mouse up event. And the cell flashes even when I hold the button, so it's not the releasing itself that clears the selection.
The control is a bit quirky with moving focus around and handling events specially. But still it works on Windows :) Now I'm a bit lost how I can debug this. +mouse didn't show anything usefull. I guess the generating and sending of the events is done in the wineserver. Could somebody explain me (or direct me to info) how this should work in general? I mean even on Windows, when is something a click and when a down/up or down/click? I know that a too slow double-click will be two separate clicks, but I'm uncertain about the down/up events.
This is what I know of it: the translations happen in the PeekMessage/GetMessage calls. If you follow the logic in windows/message.c, you see that the raw hardware messages are processed several times, and that a simple hardware message like mouse button up or down can lead to several others. Not only clicks/double clicks but also WM_SETCURSOR, WM_PARENTNORIFY, WM_ACTIVATE* and other (especially hooks) message that may come with a mouse click are generated there.
I tried again to find this problem. I couldn't find any difference in how the mouse messages are generated/handled between the two cases (clicking on first column/not first column). I now start to think that it's more a focus problem. If the focus is immediately shifted away after getting it it might look like the flashing cell I have now. To find out more about the focus I made some traces with +win.
This is from clicking on the first column (works ok). In fact I have already clicked before on a different line in the first column so the listbox surely already has the focus:
trace:event:EVENT_ProcessEvent Got event ButtonPress for hwnd/window 0x2002c/2200016, GetFocus()=0x2002c trace:cursor:send_mouse_event (8002,485,403) trace:event:EVENT_ProcessEvent returns. trace:win:WINPOS_WindowFromPoint scope 0x20029 485,403 trace:win:GetWindowRect hwnd 0x2002c (430,367)-(730,517) trace:win:WINPOS_WindowFromPoint found child 0x2002c trace:win:WIN_SetWindowLong 0x20029 0 0 3
trace:win:WIN_SetWindowLong 0x20029 0 0 3 trace:win:RedrawWindow 0x2002c ((nil)) rect 0,17-200,31 (nil) flags=0005 trace:win:dump_rdw_flags flags: RDW_INVALIDATE RDW_ERASE trace:win:RDW_UpdateRgns hwnd 0x2002c [0x145a] -> hrgn [(nil)], flags [0005] trace:win:RDW_Paint hwnd 0x2002c [0x145a] -> hrgn [(nil)], flags [0005] trace:win:RedrawWindow 0x2002c (0x145a) rect 0,17-200,31 (nil) flags=0005 trace:win:dump_rdw_flags flags: RDW_INVALIDATE RDW_ERASE trace:win:RDW_UpdateRgns hwnd 0x2002c [0x145a] -> hrgn [0x145e], flags [0005] trace:win:RDW_Paint hwnd 0x2002c [0x145a] -> hrgn [0x145e], flags [0005] trace:win:RedrawWindow 0x2002c (0x145a) rect 0,31-200,45 (nil) flags=0005 trace:win:dump_rdw_flags flags: RDW_INVALIDATE RDW_ERASE trace:win:RDW_UpdateRgns hwnd 0x2002c [0x145a] -> hrgn [0x145e], flags [0005] trace:win:RDW_Paint hwnd 0x2002c [0x145a] -> hrgn [0x145e], flags [0005] trace:win:RedrawWindow 0x2002c (0x145a) rect 0,31-200,45 (nil) flags=0005 trace:win:dump_rdw_flags flags: RDW_INVALIDATE RDW_ERASE trace:win:RDW_UpdateRgns hwnd 0x2002c [0x145a] -> hrgn [0x145e], flags [0005] trace:win:RDW_Paint hwnd 0x2002c [0x145a] -> hrgn [0x145e], flags [0005] trace:win:RedrawWindow 0x2002c (0x145a) NULL 0,0-0,0 (nil) flags=0180 trace:win:dump_rdw_flags flags: RDW_ALLCHILDREN RDW_UPDATENOW trace:win:RDW_UpdateRgns hwnd 0x2002c [0x145a] -> hrgn [(nil)], flags [0180] trace:win:RDW_UpdateRgns hwnd 0x2002d [(nil)] -> hrgn [(nil)], flags [0180] trace:win:RDW_Paint hwnd 0x2002c [0x145a] -> hrgn [(nil)], flags [0180] trace:win:begin_ncpaint hwnd 0x2002c [0x145a] ncf 0 trace:win:BeginPaint hdc = 0x74 box = (0,17 - 200,45) trace:win:BeginPaint hdc = 0x74 box = (0,17 - 200,45), fErase = 0 trace:event:EVENT_ProcessEvent called.
trace:event:EVENT_ProcessEvent Got event ButtonRelease for hwnd/window 0x2002c/2200016, GetFocus()=0x2002c trace:cursor:send_mouse_event (8004,485,403) trace:event:EVENT_ProcessEvent returns. trace:win:WIN_SetWindowLong 0x20029 0 0 3 trace:event:EVENT_ProcessEvent called.
This is from clicking on the second column (doesn't work). Note the additional BeginPaint in the middle and the different paint flags:
trace:event:EVENT_ProcessEvent Got event ButtonPress for hwnd/window 0x2002c/2200016, GetFocus()=0x2002c trace:cursor:send_mouse_event (8002,520,406) trace:event:EVENT_ProcessEvent returns. trace:win:WINPOS_WindowFromPoint scope 0x20029 520,406 trace:win:GetWindowRect hwnd 0x2002c (430,367)-(730,517) trace:win:WINPOS_WindowFromPoint found child 0x2002c trace:win:WIN_SetWindowLong 0x20029 0 0 3
trace:win:WIN_SetWindowLong 0x20029 0 0 3 trace:win:RedrawWindow 0x2002c ((nil)) rect 0,31-200,45 (nil) flags=0005 trace:win:dump_rdw_flags flags: RDW_INVALIDATE RDW_ERASE trace:win:RDW_UpdateRgns hwnd 0x2002c [0x145a] -> hrgn [(nil)], flags [0005] trace:win:RDW_Paint hwnd 0x2002c [0x145a] -> hrgn [(nil)], flags [0005] trace:win:RedrawWindow 0x2002c (0x145a) NULL 0,0-0,0 (nil) flags=0180 trace:win:dump_rdw_flags flags: RDW_ALLCHILDREN RDW_UPDATENOW trace:win:RDW_UpdateRgns hwnd 0x2002c [0x145a] -> hrgn [(nil)], flags [0180] trace:win:RDW_UpdateRgns hwnd 0x2002d [(nil)] -> hrgn [(nil)], flags [0180] trace:win:RDW_Paint hwnd 0x2002c [0x145a] -> hrgn [(nil)], flags [0180] trace:win:begin_ncpaint hwnd 0x2002c [0x145a] ncf 0 trace:win:BeginPaint hdc = 0x74 box = (0,31 - 200,45) trace:win:BeginPaint hdc = 0x74 box = (0,31 - 200,45), fErase = 0 trace:win:RedrawWindow 0x2002c ((nil)) rect 0,31-200,45 (nil) flags=0005 trace:win:dump_rdw_flags flags: RDW_INVALIDATE RDW_ERASE trace:win:RDW_UpdateRgns hwnd 0x2002c [0x145a] -> hrgn [(nil)], flags [0005] trace:win:RDW_Paint hwnd 0x2002c [0x145a] -> hrgn [(nil)], flags [0005] trace:win:RedrawWindow 0x2002c (0x145a) NULL 0,0-0,0 (nil) flags=0050 trace:win:dump_rdw_flags flags: RDW_NOINTERNALPAINT RDW_NOCHILDREN trace:win:RDW_UpdateRgns hwnd 0x2002c [0x145a] -> hrgn [(nil)], flags [0050] trace:win:RDW_Paint hwnd 0x2002c [0x145a] -> hrgn [(nil)], flags [0050] trace:win:RedrawWindow 0x2002c (0x145a) NULL 0,0-0,0 (nil) flags=0050 trace:win:dump_rdw_flags flags: RDW_NOINTERNALPAINT RDW_NOCHILDREN trace:win:RDW_UpdateRgns hwnd 0x2002c [0x145a] -> hrgn [(nil)], flags [0050] trace:win:RDW_Paint hwnd 0x2002c [0x145a] -> hrgn [(nil)], flags [0050] trace:win:begin_ncpaint hwnd 0x2002c [0x145a] ncf 0 trace:win:BeginPaint hdc = 0x74 box = (0,31 - 200,45) trace:win:BeginPaint hdc = 0x74 box = (0,31 - 200,45), fErase = 0 trace:win:WIN_SetWindowLong 0x20029 0 0 3 trace:event:EVENT_ProcessEvent called.
trace:event:EVENT_ProcessEvent Got event ButtonRelease for hwnd/window 0x2002c/2200016, GetFocus()=0x2002c trace:cursor:send_mouse_event (8004,520,406) trace:event:EVENT_ProcessEvent returns. trace:win:WINPOS_WindowFromPoint scope 0x20029 520,406 trace:win:GetWindowRect hwnd 0x2002c (430,367)-(730,517) trace:win:WINPOS_WindowFromPoint found child 0x2002c trace:win:WIN_SetWindowLong 0x20029 0 0 3 trace:win:WIN_SetWindowLong 0x20029 0 0 3 trace:event:EVENT_ProcessEvent called.
What happens here in between? Why does this get two paint events whereas in the first column it does not? Are there some other debug channels that could help me? I already use mouse, event, listbox, listctrl, cursor, win plus my own messages in the wine code.
Thanks
bye Fabi