[NEW_FEATURE] Add drag and drop ability (in progress).
git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@839 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
parent
56a653b1a9
commit
f35cd62e88
@ -57,7 +57,7 @@ DockingManager::DockingManager()
|
|||||||
{
|
{
|
||||||
_isInitialized = FALSE;
|
_isInitialized = FALSE;
|
||||||
_hImageList = NULL;
|
_hImageList = NULL;
|
||||||
memset(_iContMap, -1, CONT_MAP_MAX);
|
memset(_iContMap, -1, CONT_MAP_MAX * sizeof(int));
|
||||||
|
|
||||||
_iContMap[0] = CONT_LEFT;
|
_iContMap[0] = CONT_LEFT;
|
||||||
_iContMap[1] = CONT_RIGHT;
|
_iContMap[1] = CONT_RIGHT;
|
||||||
|
@ -85,6 +85,16 @@ BOOL CALLBACK ProjectPanel::run_dlgProc(UINT message, WPARAM wParam, LPARAM lPar
|
|||||||
return TRUE;
|
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:
|
case WM_NOTIFY:
|
||||||
{
|
{
|
||||||
notified((LPNMHDR)lParam);
|
notified((LPNMHDR)lParam);
|
||||||
@ -624,6 +634,7 @@ void ProjectPanel::notified(LPNMHDR notification)
|
|||||||
case TVN_BEGINDRAG:
|
case TVN_BEGINDRAG:
|
||||||
{
|
{
|
||||||
//printStr(TEXT("hello"));
|
//printStr(TEXT("hello"));
|
||||||
|
_treeView.beginDrag((LPNMTREEVIEW)notification);
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1099,7 +1110,6 @@ BOOL CALLBACK FileRelocalizerDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARA
|
|||||||
::SetDlgItemText(_hSelf, IDC_EDIT_FILEFULLPATHNAME, _fullFilePath.c_str());
|
::SetDlgItemText(_hSelf, IDC_EDIT_FILEFULLPATHNAME, _fullFilePath.c_str());
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_COMMAND :
|
case WM_COMMAND :
|
||||||
{
|
{
|
||||||
switch (wParam)
|
switch (wParam)
|
||||||
|
@ -52,16 +52,10 @@ void TreeView::destroy()
|
|||||||
}
|
}
|
||||||
|
|
||||||
LRESULT TreeView::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
LRESULT TreeView::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
||||||
{/*
|
{
|
||||||
switch(Message)
|
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:
|
case WM_KEYDOWN:
|
||||||
if (wParam == VK_F2)
|
if (wParam == VK_F2)
|
||||||
::MessageBoxA(NULL, "VK_F2", "", MB_OK);
|
::MessageBoxA(NULL, "VK_F2", "", MB_OK);
|
||||||
@ -69,7 +63,7 @@ LRESULT TreeView::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
|||||||
default:
|
default:
|
||||||
return ::CallWindowProc(_defaultProc, hwnd, Message, wParam, lParam);
|
return ::CallWindowProc(_defaultProc, hwnd, Message, wParam, lParam);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
return ::CallWindowProc(_defaultProc, hwnd, Message, wParam, lParam);
|
return ::CallWindowProc(_defaultProc, hwnd, Message, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +136,7 @@ void TreeView::cleanSubEntries(HTREEITEM hTreeItem)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TreeView::setItemImage(HTREEITEM hTreeItem, int iImage, int iSelectedImage)
|
void TreeView::setItemImage(HTREEITEM hTreeItem, int iImage, int iSelectedImage)
|
||||||
{
|
{
|
||||||
TVITEM tvItem;
|
TVITEM tvItem;
|
||||||
tvItem.hItem = hTreeItem;
|
tvItem.hItem = hTreeItem;
|
||||||
tvItem.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
|
tvItem.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
|
||||||
@ -151,3 +145,127 @@ void TreeView::setItemImage(HTREEITEM hTreeItem, int iImage, int iSelectedImage)
|
|||||||
TreeView_SetItem(_hSelf, &tvItem);
|
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);
|
||||||
|
|
||||||
|
}
|
@ -23,7 +23,7 @@
|
|||||||
class TreeView : public Window
|
class TreeView : public Window
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TreeView() : Window() {};
|
TreeView() : Window(), _isItemDragged(false) {};
|
||||||
|
|
||||||
virtual ~TreeView() {};
|
virtual ~TreeView() {};
|
||||||
virtual void init(HINSTANCE hInst, HWND parent, int treeViewID);
|
virtual void init(HINSTANCE hInst, HWND parent, int treeViewID);
|
||||||
@ -52,6 +52,14 @@ public:
|
|||||||
};
|
};
|
||||||
void setItemImage(HTREEITEM hTreeItem, int iImage, int iSelectedImage);
|
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:
|
protected:
|
||||||
WNDPROC _defaultProc;
|
WNDPROC _defaultProc;
|
||||||
LRESULT runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
|
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) {
|
static LRESULT CALLBACK staticProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
|
||||||
return (((TreeView *)(::GetWindowLongPtr(hwnd, GWL_USERDATA)))->runProc(hwnd, Message, wParam, lParam));
|
return (((TreeView *)(::GetWindowLongPtr(hwnd, GWL_USERDATA)))->runProc(hwnd, Message, wParam, lParam));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Drag and drop
|
||||||
|
HTREEITEM _draggedItem;
|
||||||
|
HIMAGELIST _draggedImageList;
|
||||||
|
bool _isItemDragged;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user