本程序实现 不使用 OLE 直接拖放 ListBox Items(Drag and Drop Listbox Items Without OLE), 如图:
作者 Ali Rafiee 的描述:
MFC has a CDragListBox that virtually does the same thing. The advantage of this class over MFC's CDragListBox is that it allows the user to insert the item at the end of the list, whereas CDragListBox does not. The concept is very simple: Keep track of the item that is being dragged, indicate where the drop will be when the user is dragging the item around, and finally, insert the item in its new location once the user releases the mouse button.
To accomplish this task, you will need to catch three messages for your listbox window: WM_LBUTTONDOWN, WM_MOUSEMOVE, and WM_LBUTTONUP. The WM_LBUTTONDOWN handler method simply initializes the drag and drop process by finding the item that the user clicked on.
示例代码:
void CDragAndDropListBox::OnLButtonDown(UINT nFlags, CPoint point) { CListBox::OnLButtonDown(nFlags, point); //clear all the flags m_MovingIndex = LB_ERR; m_MoveToIndex = LB_ERR; m_Captured = FALSE; m_Interval = 0; BOOL Outside; //Find the item that they want to drag and keep track of it. //Later in the mouse move, we will capture the mouse if this //value is set. int Index = ItemFromPoint(point,Outside); if (Index != LB_ERR && !Outside) { m_MovingIndex = Index; SetCurSel(Index); } }
void CDragAndDropListBox::OnMouseMove(UINT nFlags, CPoint point) { CListBox::OnMouseMove(nFlags, point); if (nFlags & MK_LBUTTON) { if (m_MovingIndex != LB_ERR && !m_Captured) { SetCapture(); m_Captured = TRUE; } BOOL Outside; int Index = ItemFromPoint(point,Outside); //if they our not on a particular item if (Outside) { CRect ClientRect; GetClientRect(&ClientRect); //If they are still within the listbox window, simply //select the last item as the drop point; else, if //they are outside the window, scroll the items. if (ClientRect.PtInRect(point)) { KillTimer(TID_SCROLLDOWN); KillTimer(TID_SCROLLUP); m_Interval = 0; //indicates that the user wants to drop the item //at the end of the list Index = LB_ERR; Outside = FALSE; } else { DoTheScrolling(point,ClientRect); } } else { KillTimer(TID_SCROLLDOWN); KillTimer(TID_SCROLLUP); m_Interval = 0; } if (Index != m_MoveToIndex && !Outside) { DrawTheLines(Index); } } }
void CDragAndDropListBox::OnLButtonUp(UINT nFlags, CPoint point) { if (m_MovingIndex != LB_ERR && m_Captured) { KillTimer(TID_SCROLLDOWN); KillTimer(TID_SCROLLUP); m_Interval = 0; m_Captured = FALSE; ReleaseCapture(); CRect Rect; GetClientRect(&Rect); //if they are still within the listbox window if (Rect.PtInRect(point)) { InsertDraggedItem(); } else { Invalidate(); UpdateWindow(); } m_MovingIndex = LB_ERR; m_MoveToIndex = LB_ERR; } CListBox::OnLButtonUp(nFlags, point); }
// CDragDropListBoxSampleDlg dialog class CDragDropListBoxSampleDlg : public CDialog { ...... // Implementation protected: CDragAndDropListBox m_ListBox; ...... };
下载地址: 点此下载源代码及演示程序