diff --git a/PowerEditor/src/WinControls/DockingWnd/DockingManager.cpp b/PowerEditor/src/WinControls/DockingWnd/DockingManager.cpp index e41851e8..12100237 100644 --- a/PowerEditor/src/WinControls/DockingWnd/DockingManager.cpp +++ b/PowerEditor/src/WinControls/DockingWnd/DockingManager.cpp @@ -57,7 +57,7 @@ DockingManager::DockingManager() { _isInitialized = FALSE; _hImageList = NULL; - memset(_iContMap, -1, CONT_MAP_MAX); + memset(_iContMap, -1, CONT_MAP_MAX * sizeof(int)); _iContMap[0] = CONT_LEFT; _iContMap[1] = CONT_RIGHT; diff --git a/PowerEditor/src/WinControls/ProjectPanel/ProjectPanel.cpp b/PowerEditor/src/WinControls/ProjectPanel/ProjectPanel.cpp index 85f2130f..13245ab6 100644 --- a/PowerEditor/src/WinControls/ProjectPanel/ProjectPanel.cpp +++ b/PowerEditor/src/WinControls/ProjectPanel/ProjectPanel.cpp @@ -85,6 +85,16 @@ BOOL CALLBACK ProjectPanel::run_dlgProc(UINT message, WPARAM wParam, LPARAM lPar return TRUE; } + + case WM_MOUSEMOVE: + if (_treeView.isDragging()) + _treeView.dragItem(_hSelf, LOWORD(lParam), HIWORD(lParam)); + break; + case WM_LBUTTONUP: + if (_treeView.isDragging()) + _treeView.dropItem(); + break; + case WM_NOTIFY: { notified((LPNMHDR)lParam); @@ -624,6 +634,7 @@ void ProjectPanel::notified(LPNMHDR notification) case TVN_BEGINDRAG: { //printStr(TEXT("hello")); + _treeView.beginDrag((LPNMTREEVIEW)notification); } break; @@ -1099,7 +1110,6 @@ BOOL CALLBACK FileRelocalizerDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARA ::SetDlgItemText(_hSelf, IDC_EDIT_FILEFULLPATHNAME, _fullFilePath.c_str()); return TRUE; } - case WM_COMMAND : { switch (wParam) diff --git a/PowerEditor/src/WinControls/ProjectPanel/TreeView.cpp b/PowerEditor/src/WinControls/ProjectPanel/TreeView.cpp index e1e632ae..74b110b0 100644 --- a/PowerEditor/src/WinControls/ProjectPanel/TreeView.cpp +++ b/PowerEditor/src/WinControls/ProjectPanel/TreeView.cpp @@ -52,16 +52,10 @@ void TreeView::destroy() } LRESULT TreeView::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) -{/* +{ switch(Message) { - case WM_MOUSEMOVE: - //::MessageBoxA(NULL, "WM_MOUSEMOVE", "", MB_OK); - break; - case WM_LBUTTONUP: - //::MessageBoxA(NULL, "WM_LBUTTONUP", "", MB_OK); - //SendMessage to parent - break; + case WM_KEYDOWN: if (wParam == VK_F2) ::MessageBoxA(NULL, "VK_F2", "", MB_OK); @@ -69,7 +63,7 @@ LRESULT TreeView::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) default: return ::CallWindowProc(_defaultProc, hwnd, Message, wParam, lParam); } - */ + return ::CallWindowProc(_defaultProc, hwnd, Message, wParam, lParam); } @@ -142,12 +136,136 @@ void TreeView::cleanSubEntries(HTREEITEM hTreeItem) } void TreeView::setItemImage(HTREEITEM hTreeItem, int iImage, int iSelectedImage) - { - TVITEM tvItem; - tvItem.hItem = hTreeItem; - tvItem.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; - tvItem.iImage = iImage; - tvItem.iSelectedImage = iSelectedImage; - TreeView_SetItem(_hSelf, &tvItem); +{ + TVITEM tvItem; + tvItem.hItem = hTreeItem; + tvItem.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvItem.iImage = iImage; + tvItem.iSelectedImage = iSelectedImage; + TreeView_SetItem(_hSelf, &tvItem); } +// pass LPARAM of WM_NOTIFY here after casted to NMTREEVIEW* +void TreeView::beginDrag(NMTREEVIEW* tv) +{ + // create dragging image for you using TVM_CREATEDRAGIMAGE + // You have to delete it after drop operation, so remember it. + _draggedItem = tv->itemNew.hItem; + _draggedImageList = (HIMAGELIST)::SendMessage(_hSelf, TVM_CREATEDRAGIMAGE, (WPARAM)0, (LPARAM)_draggedItem); + + // start dragging operation + // PARAMS: HIMAGELIST, imageIndex, xHotspot, yHotspot + ::ImageList_BeginDrag(_draggedImageList, 0, 0, 0); + ::ImageList_DragEnter(_hSelf, tv->ptDrag.x, tv->ptDrag.y); + + // redirect mouse input to the parent window + ::SetCapture(::GetParent(_hSelf)); + ::ShowCursor(false); // hide the cursor + + _isItemDragged = true; +} + +void TreeView::dragItem(HWND parentHandle, int x, int y) +{ + // convert the dialog coords to control coords + POINT point; + point.x = (SHORT)x; + point.y = (SHORT)y; + ::ClientToScreen(parentHandle, &point); + ::ScreenToClient(_hSelf, &point); + + // drag the item to the current the cursor position + ::ImageList_DragMove(point.x, point.y); + + // hide the dragged image, so the background can be refreshed + ::ImageList_DragShowNolock(false); + + // find out if the pointer is on an item + // If so, highlight the item as a drop target. + TVHITTESTINFO hitTestInfo; + hitTestInfo.pt.x = point.x; + hitTestInfo.pt.y = point.y; + HTREEITEM targetItem = (HTREEITEM)::SendMessage(_hSelf, TVM_HITTEST, (WPARAM)0, (LPARAM)&hitTestInfo); + if(targetItem) + { + // highlight the target of drag-and-drop operation + ::SendMessage(_hSelf, TVM_SELECTITEM, (WPARAM)(TVGN_DROPHILITE), (LPARAM)targetItem); + } + + // show the dragged image + ::ImageList_DragShowNolock(true); + +/* + ImageList_DragMove(x-32, y-25); // where to draw the drag from + + ImageList_DragShowNolock(FALSE); + // the highlight items should be as + + // the same points as the drag +TVHITTESTINFO tvht; + tvht.pt.x = x-20; + tvht.pt.y = y-20; // +HTREEITEM hitTarget=(HTREEITEM)SendMessage(parentHandle,TVM_HITTEST,NULL,(LPARAM)&tvht); + if (hitTarget) // if there is a hit + SendMessage(parentHandle,TVM_SELECTITEM,TVGN_DROPHILITE,(LPARAM)hitTarget); // highlight it + + ImageList_DragShowNolock(TRUE); +*/ +} + +void TreeView::dropItem() +{ + // get the target item + HTREEITEM targetItem = (HTREEITEM)::SendMessage(_hSelf, TVM_GETNEXTITEM, (WPARAM)TVGN_DROPHILITE, (LPARAM)0); + + // make a copy of the dragged item and insert the clone under + // the target item, then, delete the original dragged item + // Note that the dragged item may have children. In this case, + // you have to move (copy and delete) for every child items, too. + moveTreeViewItem(_draggedItem, targetItem); + + // finish drag-and-drop operation + ::ImageList_EndDrag(); + ::ImageList_Destroy(_draggedImageList); + ::ReleaseCapture(); + ::ShowCursor(true); + + SendMessage(_hSelf,TVM_SELECTITEM,TVGN_CARET,(LPARAM)targetItem); + SendMessage(_hSelf,TVM_SELECTITEM,TVGN_DROPHILITE,0); + + // clear global variables + _draggedItem = 0; + _draggedImageList = 0; + _isItemDragged = false; + + /* + ImageList_DragLeave(_hSelf); + ImageList_EndDrag(); + HTREEITEM Selected=(HTREEITEM)SendMessage(_hSelf,TVM_GETNEXTITEM,TVGN_DROPHILITE,0); + SendMessage(_hSelf,TVM_SELECTITEM,TVGN_CARET,(LPARAM)Selected); + SendMessage(_hSelf,TVM_SELECTITEM,TVGN_DROPHILITE,0); + ReleaseCapture(); + ShowCursor(TRUE); + _isItemDragged = FALSE; + */ +} + +void TreeView::moveTreeViewItem(HTREEITEM draggedItem, HTREEITEM targetItem) +{ + + TCHAR textBuffer[MAX_PATH]; + TVITEM tvItem; + tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvItem.pszText = textBuffer; + tvItem.cchTextMax = MAX_PATH; + tvItem.hItem = draggedItem; + SendMessage(_hSelf, TVM_GETITEM, 0,(LPARAM)&tvItem); + + TVINSERTSTRUCT tvInsertStruct; + tvInsertStruct.item = tvItem; + tvInsertStruct.hInsertAfter = (HTREEITEM)TVI_LAST; + tvInsertStruct.hParent = targetItem; + + ::SendMessage(_hSelf, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvInsertStruct); + +} \ No newline at end of file diff --git a/PowerEditor/src/WinControls/ProjectPanel/TreeView.h b/PowerEditor/src/WinControls/ProjectPanel/TreeView.h index f106ad90..f79e81ac 100644 --- a/PowerEditor/src/WinControls/ProjectPanel/TreeView.h +++ b/PowerEditor/src/WinControls/ProjectPanel/TreeView.h @@ -23,7 +23,7 @@ class TreeView : public Window { public: - TreeView() : Window() {}; + TreeView() : Window(), _isItemDragged(false) {}; virtual ~TreeView() {}; virtual void init(HINSTANCE hInst, HWND parent, int treeViewID); @@ -52,6 +52,14 @@ public: }; void setItemImage(HTREEITEM hTreeItem, int iImage, int iSelectedImage); + void beginDrag(NMTREEVIEW* tv); + void dragItem(HWND parentHandle, int x, int y); + void dropItem(); + bool isDragging() const { + return _isItemDragged; + }; + void moveTreeViewItem(HTREEITEM draggedItem, HTREEITEM targetItem); + protected: WNDPROC _defaultProc; LRESULT runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); @@ -59,6 +67,13 @@ protected: static LRESULT CALLBACK staticProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { return (((TreeView *)(::GetWindowLongPtr(hwnd, GWL_USERDATA)))->runProc(hwnd, Message, wParam, lParam)); }; + +private: + // Drag and drop + HTREEITEM _draggedItem; + HIMAGELIST _draggedImageList; + bool _isItemDragged; + };