From fb35282eb36bf1a2c9873a548c326f2dc1da2c84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Thu, 12 May 2016 22:36:05 +0000 Subject: [PATCH] [PROGMAN] Implement drag&drop support for program items. A similar functionality can be implemented later in our shell32/explorer, based on this code. We do here better than Windows' progman since we can select and move more than one icon. Note that if you test it on ReactOS you will see nice bugs coming from our (well, Wine's) comctl32.dll xD :P svn path=/trunk/; revision=71329 --- reactos/base/shell/progman/group.c | 93 ++++++++++++++++++++++++++++ reactos/base/shell/progman/progman.h | 2 + 2 files changed, 95 insertions(+) diff --git a/reactos/base/shell/progman/group.c b/reactos/base/shell/progman/group.c index a6aef822df2..253c85a34b2 100644 --- a/reactos/base/shell/progman/group.c +++ b/reactos/base/shell/progman/group.c @@ -119,6 +119,7 @@ GROUP_GroupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) PROGGROUP* group; INT iItem; LVITEMW lvItem; + POINT pt; group = (PROGGROUP*)GetWindowLongPtrW(hWnd, 0); @@ -261,6 +262,98 @@ GROUP_GroupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) PROGRAM_ExecuteProgram((PROGRAM*)lvItem.lParam); break; } + + case LVN_BEGINDRAG: + { + POINT ptMin; + + BOOL bFirst = TRUE; + for (iItem = SendMessageA(group->hListView, LVM_GETNEXTITEM, -1, LVNI_SELECTED); + iItem != -1; + iItem = SendMessageA(group->hListView, LVM_GETNEXTITEM, iItem, LVNI_SELECTED)) + { + if (bFirst) + { + group->hDragImageList = (HIMAGELIST)SendMessageA(group->hListView, + LVM_CREATEDRAGIMAGE, + iItem, + (LPARAM)&pt); + ptMin = pt; + bFirst = FALSE; + } + else + { + HIMAGELIST hOneImageList, hTempImageList; + + hOneImageList = (HIMAGELIST)SendMessageA(group->hListView, + LVM_CREATEDRAGIMAGE, + iItem, + (LPARAM)&pt); + hTempImageList = ImageList_Merge(group->hDragImageList, + 0, + hOneImageList, + 0, + pt.x - ptMin.x, + pt.y - ptMin.y); + ImageList_Destroy(group->hDragImageList); + ImageList_Destroy(hOneImageList); + group->hDragImageList = hTempImageList; + ptMin.x = min(ptMin.x, pt.x); + ptMin.y = min(ptMin.y, pt.y); + } + } + // pt = ((LPNMLISTVIEW)lParam)->ptAction; + pt.x = ((LPNMLISTVIEW)lParam)->ptAction.x; + pt.y = ((LPNMLISTVIEW)lParam)->ptAction.y; + group->ptStart = pt; + pt.x -= ptMin.x; + pt.y -= ptMin.y; + ImageList_BeginDrag(group->hDragImageList, 0, pt.x, pt.y); + MapWindowPoints(group->hListView, Globals.hMDIWnd, &pt, 1); + ImageList_DragEnter(Globals.hMDIWnd, pt.x, pt.y); + group->bDragging = TRUE; + group->hOldCursor = GetCursor(); + SetCapture(group->hWnd); + + break; + } + } + break; + + case WM_MOUSEMOVE: + if (group->bDragging) + { + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); + MapWindowPoints(group->hWnd, Globals.hMDIWnd, &pt, 1); + ImageList_DragMove(pt.x, pt.y); + } + break; + + case WM_LBUTTONUP: + if (group->bDragging) + { + // LVHITTESTINFO lvhti; + POINT ptHit; + + group->bDragging = FALSE; + ImageList_DragLeave(Globals.hMDIWnd); + ImageList_EndDrag(); + ImageList_Destroy(group->hDragImageList); + ReleaseCapture(); + SetCursor(group->hOldCursor); + ptHit.x = GET_X_LPARAM(lParam); + ptHit.y = GET_Y_LPARAM(lParam); + MapWindowPoints(group->hWnd, group->hListView, &ptHit, 1); + for (iItem = SendMessageA(group->hListView, LVM_GETNEXTITEM, -1, LVNI_SELECTED); + iItem != -1; + iItem = SendMessageA(group->hListView, LVM_GETNEXTITEM, iItem, LVNI_SELECTED)) + { + SendMessageA(group->hListView, LVM_GETITEMPOSITION, iItem, (LPARAM)&pt); + pt.x += ptHit.x - group->ptStart.x; + pt.y += ptHit.y - group->ptStart.y; + SendMessageA(group->hListView, LVM_SETITEMPOSITION, iItem, MAKELPARAM(pt.x, pt.y)); + } } break; } diff --git a/reactos/base/shell/progman/progman.h b/reactos/base/shell/progman/progman.h index fea60ab70c7..d0757d49ea3 100644 --- a/reactos/base/shell/progman/progman.h +++ b/reactos/base/shell/progman/progman.h @@ -47,6 +47,8 @@ #include #include +#include + #define MAX_STRING_LEN 255 #define MAX_PATHNAME_LEN 1024 #define MAX_LANGUAGE_NUMBER (PM_LAST_LANGUAGE - PM_FIRST_LANGUAGE)