如何拖曳樹視圖專案
本主題示範用來處理樹檢視專案的拖放程序代碼。 範例程式代碼包含三個函式。 第一個函式會開始拖曳作業、第二個函式拖曳影像,而第三個函式結束拖曳作業。
注意
拖曳樹視圖專案通常涉及處理 TVN_BEGINDRAG (或 TVN_BEGINRDRAG)通知程式代碼、 WM_MOUSEMOVE 訊息,以及 WM_LBUTTONUP (或 WM_RBUTTONUP) 訊息。 它也牽涉到使用 影像清單 函式在拖曳專案時繪製專案。
您需要知道的事項
技術
必要條件
- C/C++
- Windows 使用者介面程序設計
指示
步驟 1:開始樹視圖拖曳作業
每當用戶開始拖曳專案時,樹視圖控件會將TVN_BEGINDRAG(或TVN_BEGINRDRAG)通知碼傳送給父視窗。 父視窗會以WM_NOTIFY訊息的形式接收通知,其 lParam 參數是 NMTREEVIEW 結構的位址。 這個結構的成員包括滑鼠指標的螢幕座標,以及 包含要拖曳之專案相關信息的TVITEM 結構。
下列範例示範如何處理 WM_NOTIFY 訊息以取得 TVN_BEGINDRAG。
case WM_NOTIFY:
switch (((LPNMHDR)lParam)->code)
{
case TVN_BEGINDRAG:
Main_OnBeginDrag(((LPNMHDR)lParam)->hwndFrom, (LPNMTREEVIEW)lParam);
break;
// Handle other cases here.
}
break;
開始拖曳作業牽涉到使用 ImageList_BeginDrag 函式。 函式的參數包含影像清單的句柄,其中包含在拖曳作業期間要使用的影像,以及影像的索引。 您可以提供自己的影像清單和影像,或者您可以使用TVM_CREATEDRAGIMAGE訊息為您建立樹視圖控件。
因為拖曳影像會取代拖曳作業期間內的滑鼠指標, 因此ImageList_BeginDrag 需要您在影像中指定作用點。 熱點的座標相對於影像左上角。 ImageList_BeginDrag也需要指定拖曳影像的初始位置。 應用程式通常會設定初始位置,讓拖曳影像的熱點對應至用戶開始拖曳作業時滑鼠指標的點。
下列函式示範如何開始拖曳樹視圖專案。 它會使用樹視圖控件提供的拖曳影像,並取得專案的周框矩形,以判斷作用點的適當點。 周框的維度與影像的維度相同。
函式會擷取滑鼠輸入,導致滑鼠訊息傳送至父視窗。 父視窗需要後續的WM_MOUSEMOVE訊息,以判斷要拖曳影像的位置,以及WM_LBUTTONUP訊息,以判斷何時結束拖曳作業。
// Begin dragging an item in a tree-view control.
// hwndTV - handle to the image list.
// lpnmtv - address of information about the item being dragged.
//
// g_fDragging -- global BOOL that specifies whether dragging is underway.
void Main_OnBeginDrag(HWND hwndTV, LPNMTREEVIEW lpnmtv)
{
HIMAGELIST himl; // handle to image list
RECT rcItem; // bounding rectangle of item
// Tell the tree-view control to create an image to use
// for dragging.
himl = TreeView_CreateDragImage(hwndTV, lpnmtv->itemNew.hItem);
// Get the bounding rectangle of the item being dragged.
TreeView_GetItemRect(hwndTV, lpnmtv->itemNew.hItem, &rcItem, TRUE);
// Start the drag operation.
ImageList_BeginDrag(himl, 0, 0, 0);
ImageList_DragEnter(hwndTV, lpnmtv->ptDrag.x, lpnmtv->ptDrag.x);
// Hide the mouse pointer, and direct mouse input to the
// parent window.
ShowCursor(FALSE);
SetCapture(GetParent(hwndTV));
g_fDragging = TRUE;
return;
}
步驟 2:拖曳樹視圖專案
當父視窗收到WM_MOUSEMOVE訊息時,您可以呼叫 ImageList_DragMove 函式來拖曳樹視圖專案,如下列範例所示。 此範例也會示範如何在拖曳作業期間執行點擊測試,以判斷是否要將樹視圖中的其他專案反白顯示為拖放作業的目標。
// Drag an item in a tree-view control,
// highlighting the item that is the target.
// hwndParent - handle to the parent window.
// hwndTV - handle to the tree-view control.
// xCur and yCur - coordinates of the mouse pointer,
// relative to the parent window.
//
// g_fDragging - global BOOL that specifies whether dragging is underway.
void Main_OnMouseMove(HWND hwndParent, HWND hwndTV, LONG xCur, LONG yCur)
{
HTREEITEM htiTarget; // Handle to target item.
TVHITTESTINFO tvht; // Hit test information.
if (g_fDragging)
{
// Drag the item to the current position of the mouse pointer.
// First convert the dialog coordinates to control coordinates.
POINT point;
point.x = xCur;
point.y = yCur;
ClientToScreen(hwndParent, &point);
ScreenToClient(hwndTV, &point);
ImageList_DragMove(point.x, point.y);
// Turn off the dragged image so the background can be refreshed.
ImageList_DragShowNolock(FALSE);
// Find out if the pointer is on the item. If it is,
// highlight the item as a drop target.
tvht.pt.x = point.x;
tvht.pt.y = point.y;
if ((htiTarget = TreeView_HitTest(hwndTV, &tvht)) != NULL)
{
TreeView_SelectDropTarget(hwndTV, htiTarget);
}
ImageList_DragShowNolock(TRUE);
}
return;
}
步驟 3:結束樹視圖拖曳作業
下列範例示範如何結束拖曳作業。 當父視窗收到WM_LBUTTONUP訊息時,會呼叫ImageList_EndDrag函式。 樹視圖控件的句柄會傳遞至 函式。
// Stops dragging a tree-view item, releases the
// mouse capture, and shows the mouse pointer.
//
// g_fDragging - global BOOL that specifies whether dragging is underway.
void Main_OnLButtonUp(HWND hwndTV)
{
if (g_fDragging)
{
// Get destination item.
HTREEITEM htiDest = TreeView_GetDropHilight(hwndTV);
if (htiDest != NULL)
{
// To do: handle the actual moving of the dragged node.
}
ImageList_EndDrag();
TreeView_SelectDropTarget(hwndTV, NULL);
ReleaseCapture();
ShowCursor(TRUE);
g_fDragging = FALSE;
}
return;
}
相關主題