Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym temacie omówiono kod do obsługi przeciągania i upuszczania elementów widoku drzewa. Przykładowy kod składa się z trzech funkcji. Pierwsza funkcja rozpoczyna operację przeciągania, druga funkcja przeciąga obraz, a trzecia funkcja kończy operację przeciągania.
Notatka
Przeciąganie elementu widoku drzewa zwykle obejmuje przetwarzanie kodu powiadomienia TVN_BEGINDRAG (lub TVN_BEGINRDRAG), komunikatu WM_MOUSEMOVE oraz komunikatu WM_LBUTTONUP (lub WM_RBUTTONUP). Obejmuje również użycie funkcji Image Lists do rysowania elementu w trakcie jego przeciągania.
Co musisz wiedzieć
Technologie
Warunki wstępne
- C/C++
- Programowanie interfejsu użytkownika systemu Windows
Instrukcje
Krok 1. Rozpoczęcie operacji przeciągania widoku drzewa
Kontrolka widoku drzewa wysyła w oknie nadrzędnym kod powiadomienia TVN_BEGINDRAG (lub TVN_BEGINRDRAG) za każdym razem, gdy użytkownik zacznie przeciągać element. Okno nadrzędne odbiera powiadomienie w postaci komunikatu WM_NOTIFY, którego parametr lParam jest adresem struktury NMTREEVIEW. Elementy członkowskie tej struktury obejmują współrzędne ekranu wskaźnika myszy oraz strukturę TVITEM, która zawiera informacje o elemencie do przeciągnięcia.
W poniższym przykładzie pokazano, jak przetworzyć komunikat WM_NOTIFY w celu uzyskania 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;
Rozpoczęcie operacji przeciągania obejmuje użycie funkcji ImageList_BeginDrag. Parametry funkcji obejmują dojście do listy obrazów zawierającej obraz do użycia podczas operacji przeciągania i indeks obrazu. Możesz podać własną listę obrazów i obraz albo pozwolić, aby kontrolka widoku drzewa utworzyła je za Ciebie za pomocą komunikatu TVM_CREATEDRAGIMAGE.
Ponieważ obraz przeciągania zastępuje wskaźnik myszy na czas trwania operacji przeciągania, ImageList_BeginDrag wymaga określenia punktu gorącego na obrazie. Współrzędne punktu gorącego są względem lewego górnego rogu obrazu. ImageList_BeginDrag wymaga również określenia początkowej pozycji obrazu przeciągania. Aplikacja zazwyczaj ustawia początkową lokalizację, tak aby punkt gorący obrazu przeciągania odpowiadał temu wskaźnikowi myszy w momencie rozpoczęcia operacji przeciągania przez użytkownika.
Poniższa funkcja pokazuje, jak rozpocząć przeciąganie elementu widoku drzewa. Używa obrazu przeciągania dostarczonego przez kontrolkę widoku drzewa i uzyskuje prostokąt obramowania elementu w celu określenia odpowiedniego punktu odniesienia. Wymiary prostokąta ograniczającego są takie same jak wymiary obrazu.
Funkcja przechwytuje dane wejściowe myszy, powodując wysyłanie komunikatów myszy do okna nadrzędnego. Okno nadrzędne potrzebuje kolejnych komunikatów WM_MOUSEMOVE, aby określić miejsce do przeciągnięcia obrazu oraz komunikatu WM_LBUTTONUP, aby ustalić moment zakończenia operacji przeciągania.
// 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;
}
Krok 2. Przeciąganie elementu widoku drzewa
Przeciągnij element widoku drzewa, wywołując funkcję ImageList_DragMove, gdy okno nadrzędne odbiera komunikat WM_MOUSEMOVE, jak pokazano w poniższym przykładzie. W przykładzie pokazano również, jak przeprowadzić testowanie trafień podczas operacji przeciągania, aby określić, czy wyróżnić inne elementy w widoku drzewa jako obiekty docelowe operacji przeciągania i upuszczania.
// 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;
}
Krok 3. Zakończenie operacji przeciągania widoku drzewa
W poniższym przykładzie pokazano, jak zakończyć operację przeciągania. Funkcja ImageList_EndDrag jest wywoływana, gdy okno nadrzędne odbiera komunikat WM_LBUTTONUP. Uchwyt kontrolki widoku drzewa jest przekazywany do funkcji.
// 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;
}