Come trascinare un elemento "Tree-View"
In questo argomento viene illustrato il codice per la gestione del trascinamento e del rilascio di elementi della visualizzazione ad albero. Il codice di esempio è costituito da tre funzioni. La prima funzione avvia l'operazione di trascinamento, la seconda funzione trascina l'immagine e la terza funzione termina l'operazione di trascinamento.
Nota
Il trascinamento di un elemento della visualizzazione albero comporta in genere l'elaborazione del codice di notifica TVN_BEGINDRAG (o TVN_BEGINRDRAG), il messaggio di WM_MOUSEMOVE e il messaggio WM_LBUTTONUP (o WM_RBUTTONUP). Implica anche l'uso delle funzioni degli elenchi di immagini per disegnare l'elemento mentre viene trascinato.
Cosa è necessario sapere
Tecnologie
Prerequisiti
- C/C++
- Programmazione dell'interfaccia utente di Windows
Disposizioni
Passaggio 1: Inizio dell'operazione di trascinamento della visualizzazione albero
Un controllo ad albero invia alla finestra padre un codice di notifica TVN_BEGINDRAG (o TVN_BEGINRDRAG) ogni volta che l'utente inizia a trascinare un elemento. La finestra padre riceve la notifica sotto forma di un messaggio WM_NOTIFY, il cui parametro lParam è l'indirizzo di una struttura NMTREEVIEW. I membri di questa struttura includono le coordinate dello schermo del puntatore del mouse e una struttura TVITEM che contiene informazioni sull'elemento da trascinare.
Nell'esempio seguente viene illustrato come elaborare il messaggio di WM_NOTIFY per ottenere 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;
L'inizio dell'operazione di trascinamento comporta l'uso della funzione ImageList_BeginDrag. I parametri della funzione includono l'handle del listato delle immagini, che contiene l'immagine da utilizzare durante l'operazione di trascinamento, e l'indice dell'immagine. È possibile fornire un proprio elenco di immagini e un'immagine oppure lasciare che il controllo visualizzazione albero li crei utilizzando il messaggio TVM_CREATEDRAGIMAGE.
Poiché l'immagine di trascinamento sostituisce il puntatore del mouse per la durata dell'operazione di trascinamento, ImageList_BeginDrag richiede di specificare un punto critico all'interno dell'immagine. Le coordinate del punto critico sono relative all'angolo superiore sinistro dell'immagine. ImageList_BeginDrag richiede anche di specificare la posizione iniziale dell'immagine di trascinamento. Un'applicazione imposta in genere la posizione iniziale in modo che il punto critico dell'immagine di trascinamento corrisponda a quello del puntatore del mouse al momento in cui l'utente ha iniziato l'operazione di trascinamento.
La funzione seguente illustra come iniziare a trascinare un elemento della visualizzazione albero. Usa l'immagine di trascinamento fornita dal controllo a struttura ad albero e ottiene il rettangolo di delimitazione dell'elemento per determinare il punto appropriato per il punto focale. Le dimensioni del rettangolo di delimitazione sono uguali a quelle dell'immagine.
La funzione acquisisce l'input del mouse, causando l'invio dei messaggi del mouse alla finestra padre. La finestra padre richiede i messaggi successivi WM_MOUSEMOVE per determinare dove trascinare l'immagine e il messaggio WM_LBUTTONUP per determinare quando terminare l'operazione di trascinamento.
// 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;
}
Passaggio 2: Trascinamento dell'elemento della visualizzazione albero
Trascini un elemento nell'albero chiamando la funzione ImageList_DragMove quando la finestra padre riceve un messaggio WM_MOUSEMOVE, come illustrato nell'esempio seguente. Nell'esempio viene inoltre illustrato come eseguire il controllo di collisione durante l'operazione di trascinamento per determinare se evidenziare altri elementi nell'albero come destinazioni per il drag-and-drop.
// 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;
}
Passaggio 3: Terminare l'operazione di trascinamento della visualizzazione albero
Nell'esempio seguente viene illustrato come terminare un'operazione di trascinamento. La funzione ImageList_EndDrag viene chiamata quando la finestra padre riceve un messaggio di WM_LBUTTONUP. L'handle del controllo albero di visualizzazione viene passato alla funzione.
// 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;
}
Argomenti correlati