Hi
Where is decided if I release the mouse button if a mouse up or a mouse click is generated? Is this time dependent? Or generally the same?
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.
Thankful for any hints.
bye Fabi
On Fri, 2003-12-19 at 14:01, Fabian Cenedese wrote:
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.
+event,+message is useful, look in dlls/x11drv/event.c for the translation from X events to Win32 messages.
I think I might have a similar bug to this in AVImark. Basically the bug is to do with mouse events on context menus - in normal context menus you get RMB down, RMB up, context menu appears. In this RichEdit derivative, it goes: RMB down, context menu appears, user picks an option, context menu disappears, RMB up, context menu appears again.
Puzzling....
At 14:15 19.12.2003 +0000, Mike Hearn wrote:
On Fri, 2003-12-19 at 14:01, Fabian Cenedese wrote:
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.
+event,+message is useful, look in dlls/x11drv/event.c for the translation from X events to Win32 messages.
The log messages were not that helpful, I know try to have a look at the source, but I need more knowledge.
I think I might have a similar bug to this in AVImark. Basically the bug is to do with mouse events on context menus - in normal context menus you get RMB down, RMB up, context menu appears. In this RichEdit derivative, it goes: RMB down, context menu appears, user picks an option, context menu disappears, RMB up, context menu appears again.
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.
Thanks
bye Fabi
On Thu, 08 Jan 2004 11:23:56 +0100, you wrote:
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.
Rein.
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
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.
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 second column (doesn't work). Note the additional BeginPaint in the middle and the different paint flags:
(snip)
As nobody is participating I need to reply to my own posts :)
I may be getting closer. My assumptions about mouse handling or focus seem both wrong. The cell gets activated and stays like that, it's just not visible. But when I move with cursor keys the (invisible) selection moves from the clicked cell to the next cell (and is now visible). So for me it looks like this: When I click in a cell it gets invalidated and painted selected. But if the cell is not in the first row the first column (or the whole line) gets invalidated and repainted too, therefore erasing the already painted selection.
From my code of the derived list control:
void CMyListCtrl::OnLButtonDown(UINT nFlags, CPoint point) { LVHITTESTINFO ht; ht.pt = point; SubItemHitTest(&ht);
m_CurSubItem = IndexToOrder(ht.iSubItem);
if(ht.iItem!=-1) { CHeaderCtrl* pHeader = GetHeaderCtrl();
//set first selected and focus state SetItem(ht.iItem, 0, LVIF_STATE, NULL, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED, 0);
//update row anyway for selection bar CRect rc; GetItemRect(ht.iItem, rc, LVIR_BOUNDS); InvalidateRect(rc); UpdateWindow(); }
//following line is used for drag&drop support. I don't know why!! Do it at the //end of this function because it hangs until mouse up message has proceed. CListCtrl::OnLButtonDown(nFlags, point); // test AfxMessageBox("Released"); }
The comment in the end is not from me but it really is like that. The call stays in there until I release the mouse button, no matter if on the same cell or somewhere else (as it says, for drag'n'drop). The test message box after the call only comes up when I release the button. But on wine it immediately pops up while still holding down the mouse button. I don't know how the hanging is down on Windows but I think this is what mixes up my events and why my cell doesn't stay painted selected. I'm still wondering though why this isn't the same on the first column.
Does anybody know about the handling of mouse events in the listview? Is this a bug or just not implemented yet (I've seen the comment in the beginning of listview.c :) ?
Thanks
bye Fabi
On January 29, 2004 06:27 am, Fabian Cenedese wrote:
Does anybody know about the handling of mouse events in the listview? Is this a bug or just not implemented yet (I've seen the comment in the beginning of listview.c :) ?
The comment is wrong and needs updating. Huw Davies added drag&drop support some time ago (2003/11/03). I'd love to be more helpful on this matter, but I'm out of bandwidth at the moment...
At 07:54 29.01.2004 -0500, Dimitrie O. Paun wrote:
On January 29, 2004 06:27 am, Fabian Cenedese wrote:
Does anybody know about the handling of mouse events in the listview? Is this a bug or just not implemented yet (I've seen the comment in the beginning of listview.c :) ?
The comment is wrong and needs updating. Huw Davies added drag&drop support some time ago (2003/11/03). I'd love to be more helpful on this matter, but I'm out of bandwidth at the moment...
Understandable. Any hints how I could continue? Where to look at?
Thanks
bye Fabi
On January 29, 2004 08:08 am, Fabian Cenedese wrote:
Understandable. Any hints how I could continue? Where to look at?
I don't think I understand this bit. Care to explain it again?
"So for me it looks like this: When I click in a cell it gets invalidated and painted selected. But if the cell is not in the first row the first column (or the whole line) gets invalidated and repainted too, therefore erasing the already painted selection."
At 08:27 29.01.2004 -0500, Dimitrie O. Paun wrote:
On January 29, 2004 08:08 am, Fabian Cenedese wrote:
Understandable. Any hints how I could continue? Where to look at?
I don't think I understand this bit. Care to explain it again?
"So for me it looks like this: When I click in a cell it gets invalidated and painted selected. But if the cell is not in the first row the first column (or the whole line) gets invalidated and repainted too, therefore erasing the already painted selection."
That was my weak try to explain what I see :) Ok, again in short what happens: I can click on a cell in the first column, it gets selected, I can release the mouse button, everything fine. But when I press on a cell in another column it shortly gets selected and immediately the selection again disappears, even while still holding the mouse button. The logical selection seems to be ok as I can move it to another cell with the cursor keys (and it strangely stays there unlike if done so with the mouse). So if only the visual display is wrong I was looking for an explanation with the paint events. The cell is set selected and then the whole line invalidated (as it is ownerdrawn). Maybe in Windows only the Invalidate/Update cause the line to be repainted whereas in wine already the SetItem will cause a first Update and then the Invalidate a second one. But then again it should just flicker a bit but not completely disappear... Btw, the hanging in the CListCtrl::OnLButtonDown I mentioned is also in wine for the first column (maybe that's why this works). But for the other columns it just rushes through.
bye Fabi
On Thu, 29 Jan 2004, Fabian Cenedese wrote:
That was my weak try to explain what I see :) Ok, again in short what happens: I can click on a cell in the first column, it gets selected, I can release the mouse button, everything fine. But when I press on a cell in another column it shortly gets selected and immediately the selection again disappears, even while still holding the mouse button. The logical selection seems to be ok as I can move it to another cell with the cursor keys (and it strangely stays there unlike if done so with the mouse).
OK, so it seems that your app uses the listview in LVS_REPORT mode, and that it wants to make it bahave like a spreadsheet (that is, you want to be able to individually select any cell from the row/column matrix of the listview). Hence the OWNERDRAW, as by default a listview in REPORT more can either select the cell in the first column or the entire row.
Now, I haven't used MFC before, so I don't know if this behaviour is done in your app or in MFC code. If it's in your app, it should be simple enough to add some print statements to figure out the paint order and to confirm/ruleout this theory. If it's done in MFC, I'm afraid you'll need to get creative, 'cause I can't help.
But the problem seems to be in the order of events (or some missing notifications). Print statements are what you want: they'll help you figure out (1) if you get all required notifications, and (2) if they arrive in the right order.
That was my weak try to explain what I see :) Ok, again in short what happens: I can click on a cell in the first column, it gets selected, I can release the mouse button, everything fine. But when I press on a cell in another column it shortly gets selected and immediately the selection again disappears, even while still holding the mouse button. The logical selection seems to be ok as I can move it to another cell with the cursor keys (and it strangely stays there unlike if done so with the mouse).
OK, so it seems that your app uses the listview in LVS_REPORT mode, and that it wants to make it bahave like a spreadsheet (that is, you want to be able to individually select any cell from the row/column matrix of the listview). Hence the OWNERDRAW, as by default a listview in REPORT more can either select the cell in the first column or the entire row.
Hmm... that might be a thing to try too as it works for the first column. That would be LVS_EX_FULLROWSELECT... Nah, didn't change anything except some flicker.
Now, I haven't used MFC before, so I don't know if this behaviour is done in your app or in MFC code. If it's in your app, it should be simple enough to add some print statements to figure out the paint order and to confirm/ruleout this theory. If it's done in MFC, I'm afraid you'll need to get creative, 'cause I can't help.
Of course some is application code as the listcontrol doesn't behave like that. But it doesn't need that much as there are already a lot of useful functions (SubItemHitTest, DrawItem...) I just need to keep an index of the selected column in addition to the already exisiting SelectedRow. And the painting of just this one cell instead of the whole line. The bigger stuff is to include other controls (text, combo) in the cells.
But the problem seems to be in the order of events (or some missing notifications). Print statements are what you want: they'll help you figure out (1) if you get all required notifications, and (2) if they arrive in the right order.
I think I already found the (apparent) difference in the events, the (not) hanging in the OnLButtonDown. I need to find out why it doesn't stay in there and if it's in listview, message, events...
Thanks
bye Fabi
On January 30, 2004 07:55 am, Fabian Cenedese wrote:
I think I already found the (apparent) difference in the events, the (not) hanging in the OnLButtonDown. I need to find out why it doesn't stay in there and if it's in listview, message, events...
The mouse tracking in listview happens in the LISTVIEW_TrackMouse() function, which seems correct. It is getting called from only one place (in LISTVIEW_LButtonDown()) so a few print statements there would be nice to see that (1) it is being called, and (2) that it doesn't exit prematurely.
In this case a PE build of the comctl32 would be priceless: you could just replace the native comctl32 DLL on a real Windows installation with our own implementation, and see if the problem persists. Is so, the error is in our comctl32 DLL. If not, it is in the lower layers (message, events, etc.).
In fact, a PE build of the comctl32 would be so useful that I'm a bit surprised nobody attempted it thus far... We should offer a full PE build on SourceForge, together with the other downloads. Any takers?
On January 30, 2004 07:55 am, Fabian Cenedese wrote:
I think I already found the (apparent) difference in the events, the (not) hanging in the OnLButtonDown. I need to find out why it doesn't stay in there and if it's in listview, message, events...
The mouse tracking in listview happens in the LISTVIEW_TrackMouse() function, which seems correct. It is getting called from only one place (in LISTVIEW_LButtonDown()) so a few print statements there would be nice to see that (1) it is being called, and (2) that it doesn't exit prematurely.
I made a test and added a printf message in the loop of TrackMouse. When I hold the mouse button in the first column I see hundreds of these message pass by. But when I press on another column I don't even see it enter the whole function TrackMouse, not to mention the message from the loop. In LISTVIEW_LButtonDown the nItem is -1, so it thinks that no item is selected and skips most of the code.
I'm still looking at logs. But I also thought that LISTVIEW_HitTest gave wrong results for other columns (LVHT_NOWHERE) but I still need to look further. But that might go along with the listview thinking that no item is selected.
Thanks for your hints, give me new ideas.
bye Fabi
The mouse tracking in listview happens in the LISTVIEW_TrackMouse() function, which seems correct. It is getting called from only one place (in LISTVIEW_LButtonDown()) so a few print statements there would be nice to see that (1) it is being called, and (2) that it doesn't exit prematurely.
I made a test and added a printf message in the loop of TrackMouse. When I hold the mouse button in the first column I see hundreds of these message pass by. But when I press on another column I don't even see it enter the whole function TrackMouse, not to mention the message from the loop. In LISTVIEW_LButtonDown the nItem is -1, so it thinks that no item is selected and skips most of the code.
I'm still looking at logs. But I also thought that LISTVIEW_HitTest gave wrong results for other columns (LVHT_NOWHERE) but I still need to look further. But that might go along with the listview thinking that no item is selected.
Getting closer. I now know where the problem is though I don't know the solution. It's in this function:
static INT LISTVIEW_HitTest(LISTVIEW_INFO *infoPtr, LPLVHITTESTINFO lpht, BOOL subitem, BOOL select) { -- snip--
if (select && !(uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))) { if (uView == LVS_REPORT) { UnionRect(&rcBounds, &rcIcon, &rcLabel); UnionRect(&rcBounds, &rcBounds, &rcState); }
if (!PtInRect(&rcBounds, opt)) iItem = -1; }
return lpht->iItem = iItem; }
In the end is this piece of code. What's the intention of it? If my ListCtrl is LVS_EX_FULLROWSELECT it never enters this code, if my ListCtrl is not then it enters here but does wrong stuff. If I comment out this code completely all works fine because right before this the item and subitem are found correctly.
I have made a little test program I could mail to anyone who's interested in this. It's just a simple dialog with a list control where you can switch on and off the OWNERDRAWFIXED and FULLROWSELECT. With the current wine implementation and FULLROWSELECT set it works ok (with and without ownerdraw). Without fullrow but with ownerdraw it gives the errors I've been looking at for weeks. Commenting out the above code makes it work but then the normal mode (both flags off) has repainting issues, the items in second or more column stay selected when moving to another row. But then even the current implementation is alike. It could also be that some other places need changes to make all variations work. But that's again above my head. I tried adding the ownerdraw flag to this code. Works in my case.
bye Fabi
Index: wine/dlls/comctl32/listview.c =================================================================== RCS file: /home/wine/wine/dlls/comctl32/listview.c,v retrieving revision 1.380 diff -u -r1.380 listview.c --- wine/dlls/comctl32/listview.c 10 Dec 2003 00:37:14 -0000 1.380 +++ wine/dlls/comctl32/listview.c 2 Feb 2004 14:09:16 -0000 @@ -5980,7 +5980,8 @@ } }
- if (select && !(uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))) + if (select && !(uView == LVS_REPORT && ((infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT) + || (infoPtr->dwStyle & LVS_OWNERDRAWFIXED)))) { if (uView == LVS_REPORT) {
On Mon, 2 Feb 2004, Fabian Cenedese wrote:
static INT LISTVIEW_HitTest(LISTVIEW_INFO *infoPtr, LPLVHITTESTINFO lpht, BOOL subitem, BOOL select) { -- snip--
if (select && !(uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))) { if (uView == LVS_REPORT) { UnionRect(&rcBounds, &rcIcon, &rcLabel); UnionRect(&rcBounds, &rcBounds, &rcState); } if (!PtInRect(&rcBounds, opt)) iItem = -1; } return lpht->iItem = iItem;
}
In the end is this piece of code. What's the intention of it?
OK, the idea of LISTVIEW_HitTest() is to figure out where a specific point falls: what item/subitem/label/etc. As you said correctly, it does that OK up to this piece of code at the end.
The reason we have this is that for _selecting_ items (hence the test for select), we have slighly different behaviour: -- we 'hit' an item if we click anywhere in the union of the icon and label rectangles. -- the above rule works in all cases _except_ for full row select in REPORT mode, where we have to consider the entire row, and regular REPORT mode where we have to consider the first column only
Index: wine/dlls/comctl32/listview.c
RCS file: /home/wine/wine/dlls/comctl32/listview.c,v retrieving revision 1.380 diff -u -r1.380 listview.c --- wine/dlls/comctl32/listview.c 10 Dec 2003 00:37:14 -0000 1.380 +++ wine/dlls/comctl32/listview.c 2 Feb 2004 14:09:16 -0000 @@ -5980,7 +5980,8 @@ } }
- if (select && !(uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)))
- if (select && !(uView == LVS_REPORT && ((infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)
{ if (uView == LVS_REPORT) {|| (infoPtr->dwStyle & LVS_OWNERDRAWFIXED))))
I don't think behaviour in the LVS_OWNERDRAWFIXED case is explicitly documented, but I think it should behave as in the LVS_EX_FULLROWSELECT case. In other words, I think your patch is correct, please submit it to wine-patches.
At 10:12 02.02.2004 -0500, Dimitrie O. Paun wrote:
I don't think behaviour in the LVS_OWNERDRAWFIXED case is explicitly documented, but I think it should behave as in the LVS_EX_FULLROWSELECT case. In other words, I think your patch is correct, please submit it to wine-patches.
Done. Thanks :)
bye Fabi
I think there are still problems with that patch because, in emule when I change the size of a column, the selected row is not repainted correctly, only some area of it are. The style is fullrowselect and ownerdraw.
Only the new space of the column whose size has increased is repainted correctly.
Max
On Mon, 2004-02-02 at 16:35, Fabian Cenedese wrote:
At 10:12 02.02.2004 -0500, Dimitrie O. Paun wrote:
I don't think behaviour in the LVS_OWNERDRAWFIXED case is explicitly documented, but I think it should behave as in the LVS_EX_FULLROWSELECT case. In other words, I think your patch is correct, please submit it to wine-patches.
Done. Thanks :)
bye Fabi
I think there are still problems with that patch because, in emule when I change the size of a column, the selected row is not repainted correctly, only some area of it are. The style is fullrowselect and ownerdraw.
Only the new space of the column whose size has increased is repainted correctly.
Do you already had that error before this patch? Because this was in the function HitTest, used e.g. when you click with the mouse on the list. But I don't think that has anything to do with resizing. But I didn't try it. I also saw that the repainting of the other columns isn't always correct, even without these styles. But that was not the goal of this patch.
bye Fabi
On Tue, 03 Feb 2004 20:53:17 +0100, you wrote:
I think there are still problems with that patch because, in emule when I change the size of a column, the selected row is not repainted correctly, only some area of it are. The style is fullrowselect and ownerdraw.
Only the new space of the column whose size has increased is repainted correctly.
FWIW, Fabian's patch fixes newsbin pro. Selecting a message for download with the mouse did not work since the drag&drop patch but is fixed now (and d&d still works).
Column resizing still has it repaint problems, but it had this in some form forever.
Rein.
On February 4, 2004 03:39 am, Rein Klazes wrote:
Column resizing still has it repaint problems, but it had this in some form forever.
Can you please file a bug in bugzilla, and assign it to me?
On Wed, 4 Feb 2004 08:20:46 -0500, you wrote:
On February 4, 2004 03:39 am, Rein Klazes wrote:
Column resizing still has it repaint problems, but it had this in some form forever.
Can you please file a bug in bugzilla, and assign it to me?
Done, bug #1992
Rein.
At 08:27 29.01.2004 -0500, Dimitrie O. Paun wrote:
On January 29, 2004 08:08 am, Fabian Cenedese wrote:
Understandable. Any hints how I could continue? Where to look at?
I don't think I understand this bit. Care to explain it again?
"So for me it looks like this: When I click in a cell it gets invalidated and painted selected. But if the cell is not in the first row the first column (or the whole line) gets invalidated and repainted too, therefore erasing the already painted selection."
Another idea: When a line changes it is completely invalidated and repainted without any selection. The the new cell is painted again with selection. So what if these two events are in wrong order? My cell gets selected and immediately loses it again. And that's maybe what happens as "it" (main thread?) doesn't wait in the OnLButtonDown as it does for the first column cells. Of course it's not just that simple as I made a test with a simple ownerdrawn listcontrol which of course worked. So it must be more in my app that interferes. Could it be that the listview is inside a ocx? Different event handling?
bye Fabi