AlwaysLearningNewStuff
AlwaysLearningNewStuff

Reputation: 3031

Detect when scrolling is necessary while user drags listview items

INTRODUCTION:

I am implementing rearranging of listview items without using OLE drag and drop.

PROBLEM:

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.

QUESTION:

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.

MY EFFORTS TO SOLVE THIS:

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.

ADDITIONAL INFO:

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

Answers (1)

Jonathan Potter
Jonathan Potter

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

Related Questions