Reputation: 3031
I am implementing rearranging of listview items without using OLE drag and drop.
I have successfully solved most of this task, except scrolling up/down when user wants to drop items at the position that is not currently visible.
I am able to scroll up/down listview by using following messages:
SendMessage(hwndListView, WM_VSCROLL, (WPARAM)SB_LINEUP, (LPARAM)0);
SendMessage(hwndListView, WM_VSCROLL, (WPARAM)SB_LINEDOWN, (LPARAM)0);
I need your advice in figuring out when and where I need to send those messages ( I suppose it should be done on WM_MOUSEHOVER or something like that? ).
I just do not know on which message, and how, I should check if scrolling is needed.
I am interested in implementing default scrolling behavior for drag and drop.
I have tried to use listview hit testing so I can examine LVHITTESTINFO for LVHT_ABOVE
and LVHT_BELOW
but that did not work for me.
I was never able to get those values when clicking on listview...
I have found some examples in other programming languages that use timers to implement this. I am studying them as I write this post.
Listview is in report mode and supports multiselection.
I am handling following messages:
LVN_BEGINDRAG // I create drag image here
WM_MOUSEMOVE // I update drag image here
WM_LBUTTONUP // I rearrange items here and perform cleanup
I have omitted SSCCE to keep this post short. If needed I can post it. If further info is required please leave a comment.
Upvotes: 3
Views: 1546
Reputation: 37192
Presumably your drag and drop loop uses SetCapture
to capture mouse input.
All you have to do is watch for WM_MOUSEMOVE
messages. When the mouse moves above the top or below the bottom of the listview, set a flag to indicate you are scrolling and start a timer using SetTimer
.
Every time the timer goes off, scroll one line in the appropriate direction, by sending the listview a WM_VSCROLL
message.
If the mouse moves back inside the listview, or the capture is lost (i.e. you get WM_CAPTURECHANGED
), kill your timer and stop scrolling.
Upvotes: 3