mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 11:43:31 +00:00
Implemented scrolling during drag&drop for the shellview class.
This commit is contained in:
parent
356174019e
commit
08a2a60993
1 changed files with 67 additions and 2 deletions
|
@ -103,6 +103,7 @@ typedef struct
|
|||
IDropTarget* pCurDropTarget; /* The sub-item, which is currently dragged over */
|
||||
IDataObject* pCurDataObject; /* The dragged data-object */
|
||||
LONG iDragOverItem; /* Dragged over item's index, iff pCurDropTarget != NULL */
|
||||
UINT iActiveTimersMask; /* Bookkeeping of activated timers for drag scrolling */
|
||||
} IShellViewImpl;
|
||||
|
||||
static const IShellViewVtbl svvt;
|
||||
|
@ -196,6 +197,7 @@ IShellView * IShellView_Constructor( IShellFolder * pFolder)
|
|||
sv->pCurDropTarget = NULL;
|
||||
sv->pCurDataObject = NULL;
|
||||
sv->iDragOverItem = 0;
|
||||
sv->iActiveTimersMask = 0;
|
||||
|
||||
TRACE("(%p)->(%p)\n",sv, pFolder);
|
||||
return (IShellView *) sv;
|
||||
|
@ -2176,12 +2178,57 @@ static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
|
|||
return IShellFolder_Release((IShellFolder*)This);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* scroll_timer_proc [Internal]
|
||||
*
|
||||
* Timer callback function for drag&drop scrolling
|
||||
*/
|
||||
|
||||
#define IDT_UP 0x1u
|
||||
#define IDT_DOWN 0x2u
|
||||
#define IDT_LEFT 0x4u
|
||||
#define IDT_RIGHT 0x8u
|
||||
|
||||
VOID CALLBACK scroll_timer_proc(HWND hwnd, UINT uMsg, UINT_PTR idTimer, DWORD dwTimer) {
|
||||
switch (idTimer) {
|
||||
case IDT_UP:
|
||||
SendMessageW(hwnd, WM_VSCROLL, SB_LINEUP, 0);
|
||||
break;
|
||||
case IDT_DOWN:
|
||||
SendMessageW(hwnd, WM_VSCROLL, SB_LINEDOWN, 0);
|
||||
break;
|
||||
case IDT_LEFT:
|
||||
SendMessageW(hwnd, WM_HSCROLL, SB_LINEUP, 0);
|
||||
break;
|
||||
case IDT_RIGHT:
|
||||
SendMessageW(hwnd, WM_HSCROLL, SB_LINEDOWN, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* start_stop_timer [Internal]
|
||||
*/
|
||||
static inline void start_stop_timer(IShellViewImpl *This, UINT_PTR idTimer, BOOL fStart) {
|
||||
if (fStart && !(This->iActiveTimersMask & idTimer)) {
|
||||
SetTimer(This->hWndList, idTimer, 200, scroll_timer_proc);
|
||||
This->iActiveTimersMask |= idTimer;
|
||||
}
|
||||
if (!fStart && This->iActiveTimersMask & idTimer) {
|
||||
KillTimer(This->hWndList, idTimer);
|
||||
This->iActiveTimersMask &= ~idTimer;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* drag_notify_subitem [Internal]
|
||||
*
|
||||
* Figure out the shellfolder object, which is currently under the mouse cursor
|
||||
* and notify it via the IDropTarget interface.
|
||||
*/
|
||||
|
||||
#define SCROLLAREAWIDTH 20
|
||||
|
||||
static HRESULT drag_notify_subitem(IShellViewImpl *This, DWORD grfKeyState, POINTL pt,
|
||||
DWORD *pdwEffect)
|
||||
{
|
||||
|
@ -2189,15 +2236,23 @@ static HRESULT drag_notify_subitem(IShellViewImpl *This, DWORD grfKeyState, POIN
|
|||
LVITEMA lvItem;
|
||||
LONG lResult;
|
||||
HRESULT hr;
|
||||
RECT clientRect;
|
||||
|
||||
/* Map from global to client coordinates and query the index of the listview-item, which is
|
||||
* currently under the mouse cursor. */
|
||||
htinfo.pt.x = pt.x;
|
||||
htinfo.pt.y = pt.y;
|
||||
htinfo.flags = LVHT_ONITEM;
|
||||
MapWindowPoints(NULL, This->hWndList, &htinfo.pt, 1);
|
||||
ScreenToClient(This->hWndList, &htinfo.pt);
|
||||
lResult = SendMessageW(This->hWndList, LVM_HITTEST, 0, (LPARAM)&htinfo);
|
||||
|
||||
/* Start or stop the drag scrolling timers */
|
||||
GetClientRect(This->hWndList, &clientRect);
|
||||
start_stop_timer(This, IDT_LEFT, htinfo.pt.x < SCROLLAREAWIDTH);
|
||||
start_stop_timer(This, IDT_RIGHT, htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH);
|
||||
start_stop_timer(This, IDT_UP, htinfo.pt.y < SCROLLAREAWIDTH);
|
||||
start_stop_timer(This, IDT_DOWN, htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH);
|
||||
|
||||
/* If we are still over the previous sub-item, notify it via DragOver and return. */
|
||||
if (This->pCurDropTarget && lResult == This->iDragOverItem)
|
||||
return IDropTarget_DragOver(This->pCurDropTarget, grfKeyState, pt, pdwEffect);
|
||||
|
@ -2265,7 +2320,12 @@ static HRESULT WINAPI ISVDropTarget_DragLeave(IDropTarget *iface) {
|
|||
This->pCurDataObject = NULL;
|
||||
This->pCurDropTarget = NULL;
|
||||
This->iDragOverItem = 0;
|
||||
|
||||
|
||||
start_stop_timer(This, IDT_LEFT, FALSE);
|
||||
start_stop_timer(This, IDT_RIGHT, FALSE);
|
||||
start_stop_timer(This, IDT_UP, FALSE);
|
||||
start_stop_timer(This, IDT_DOWN, FALSE);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -2282,6 +2342,11 @@ static HRESULT WINAPI ISVDropTarget_Drop(IDropTarget *iface, IDataObject* pDataO
|
|||
This->pCurDropTarget = NULL;
|
||||
This->iDragOverItem = 0;
|
||||
|
||||
start_stop_timer(This, IDT_LEFT, FALSE);
|
||||
start_stop_timer(This, IDT_RIGHT, FALSE);
|
||||
start_stop_timer(This, IDT_UP, FALSE);
|
||||
start_stop_timer(This, IDT_DOWN, FALSE);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue