mirror of
				https://github.com/notepad-plus-plus/notepad-plus-plus.git
				synced 2025-11-03 21:14:08 +01:00 
			
		
		
		
	[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;
 | 
			
		||||
	_hImageList				= NULL;
 | 
			
		||||
	memset(_iContMap, -1, CONT_MAP_MAX);
 | 
			
		||||
	memset(_iContMap, -1, CONT_MAP_MAX * sizeof(int));
 | 
			
		||||
 | 
			
		||||
	_iContMap[0] = CONT_LEFT;
 | 
			
		||||
	_iContMap[1] = CONT_RIGHT;
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -151,3 +145,127 @@ void TreeView::setItemImage(HTREEITEM hTreeItem, int iImage, int 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);
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@ -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;	
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user