트리 보기 항목을 끄는 방법
이 항목에서는 트리 보기 항목의 끌어서 놓기 처리를 위한 코드를 보여 줍니다. 샘플은 세 함수로 구성되어 있습니다. 첫 번째 함수는 끌기 작업을 시작하고, 두 번째 함수는 이미지를 끌고, 세 번째 함수는 끌기 작업을 종료합니다.
참고
일반적으로 트리 보기 항목을 끌려면 TVN_BEGINDRAG(또는 TVN_BEGINRDRAG) 알림 코드, WM_MOUSEMOVE 메시지 및 WM_LBUTTONUP(또는 WM_RBUTTONUP) 메시지를 처리하는 작업이 포함됩니다. 또한 Image Lists 함수를 사용하여 항목을 끌 때 그립니다.
알아야 하는 작업
기술
필수 구성 요소
- C/C++
- Windows 사용자 인터페이스 프로그래밍
지침
1단계: 트리 보기 끌기 작업 시작
트리 보기 컨트롤은 사용자가 항목을 끌기 시작할 때마다 부모 창에 TVN_BEGINDRAG(또는 TVN_BEGINRDRAG) 알림 코드를 보냅니다. 부모 창은 lParam 매개 변수가 NMTREEVIEW 구조체의 주소인 WM_NOTIFY 메시지 형식으로 알림을 받습니다. 이 구조체의 멤버에는 마우스 포인터의 화면 좌표와 끌 항목에 대한 정보가 포함된 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;
}
관련 항목