Condividi tramite


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; 
} 

uso di controlli Tree-View

esempio CustDTv illustra un disegno personalizzato in un controllo Tree-View