Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Toto téma ukazuje kód pro zpracování přetahování položek v zobrazení stromu. Vzorový kód se skládá ze tří funkcí. První funkce zahájí operaci přetažení, druhá funkce přetáhne obrázek a třetí funkce ukončí operaci přetažení.
Poznámka:
Přetažení položky stromového zobrazení obvykle zahrnuje zpracování kódu oznámení TVN_BEGINDRAG (nebo TVN_BEGINRDRAG), zprávy WM_MOUSEMOVE a WM_LBUTTONUP (neboWM_RBUTTONUP). Zahrnuje také použití funkcí Seznamy obrázků k vykreslení položky při přetahování.
Co potřebujete vědět
Technologie
Požadavky
- C/C++
- Programování uživatelského rozhraní systému Windows
Instrukce
Krok 1: Zahájení operace přetažení stromového zobrazení
Ovládací prvek stromového zobrazení odešle nadřazené okno kód oznámení TVN_BEGINDRAG (nebo TVN_BEGINRDRAG), kdykoli uživatel začne přetahovat položku. Nadřazené okno obdrží oznámení ve formě WM_NOTIFY zprávy, jejíž lParam parametr je adresa NMTREEVIEW struktury. Členy této struktury zahrnují souřadnice obrazovky ukazatele myši a strukturu TVITEM , která obsahuje informace o položce, kterou chcete přetáhnout.
Následující příklad ukazuje, jak zpracovat zprávu WM_NOTIFY získat 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;
Zahájení operace přetažení zahrnuje použití funkce ImageList_BeginDrag . Parametry funkce zahrnují popisovač do seznamu obrázků, který obsahuje obrázek, který se má použít během operace přetažení a index obrázku. Můžete buď zadat vlastní seznam obrázků a obrázek, nebo můžete mít ovládací prvek stromového zobrazení vytvořený za vás pomocí zprávy TVM_CREATEDRAGIMAGE .
Vzhledem k tomu, že obrázek přetažení nahradí ukazatel myši po dobu trvání operace přetažení, ImageList_BeginDrag vyžaduje, abyste v obrázku zadali horké místo. Souřadnice horkého místa jsou relativní vzhledem k levému hornímu rohu obrázku. ImageList_BeginDrag také vyžaduje, abyste zadali počáteční umístění obrázku přetažení. Aplikace obvykle nastavuje počáteční umístění tak, aby aktivní místo obrázku přetažení odpovídalo ukazateli myši v době, kdy uživatel zahájil operaci přetažení.
Následující funkce ukazuje, jak začít přetahovat položku stromového zobrazení. Používá obrázek přetažení poskytnutý ovládacím prvkem stromového zobrazení a získá ohraničující obdélník položky k určení vhodného bodu pro aktivní místo. Rozměry ohraničujícího obdélníku jsou stejné jako rozměry obrázku.
Funkce zachytí vstup myši, což způsobí odeslání zpráv myši do nadřazeného okna. Nadřazené okno potřebuje následující WM_MOUSEMOVE zprávy k určení umístění přetažení obrázku a WM_LBUTTONUP zprávy, aby bylo možné určit, kdy má operace přetažení ukončit.
// 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: Přetažení položky stromového zobrazení
Položku stromového zobrazení přetáhnete voláním funkce ImageList_DragMove , když nadřazené okno obdrží WM_MOUSEMOVE zprávu, jak ukazuje následující příklad. Příklad také ukazuje, jak provést testování hit během operace přetažení určit, zda se mají zvýraznit další položky ve stromovém zobrazení jako cíle operace přetažení.
// 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: Ukončení operace přetažení stromového zobrazení
Následující příklad ukazuje, jak ukončit operaci přetažení. Funkce ImageList_EndDrag je volána, když nadřazené okno obdrží WM_LBUTTONUP zprávu. Popisovač ovládacího prvku stromového zobrazení se předá funkci.
// 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;
}