|
: 안녕하세요?
: 윈도우 탐색기의 메뉴중에 보기->큰아이콘
: 아이콘정렬->자동정렬(체크제거)
: 이렇게 설정을 하고 나서 탐색기의 리스트부분에 나타나있는
: 파일을 드래그 하여 리스트뷰내의 아무곳이나 놓을수 있습니다.
: 저도 이렇게 만들어 보고 싶습니다.
: 씨빌더의 리스트뷰 속성중 vsIcon형식으로 하고 컴파일후
: 아이템을 움직일려면 전혀 움직이지 안습니다.
: 이 문제를 해결할려면 어떻게 해야 하나요?
: 가르쳐 주셔요^^
:
: 박세율올림
임펠리테리입니다.
리스트뷰 컨트롤에서 아이템이 전혀 움직이지 않는 것은 당연합니다. vcl 컨트롤의 기본적인
개념에서는, 드래그 처리는 프로그래머가 직접 해주어야 합니다. 만약 리스트박스 등의
아이템을 드래그해서 움직이는 예제를 보신 적이 있다면 쉽게 이해하실 수 있으실 겁니다.
vcl 컨트롤의 드래그 처리의 기본은 하나의 프로퍼티와 두개의 이벤트가 관련되어 있습니다.
가장 먼저 컨트롤의 DragMode 프로퍼티가 dmAutomatic으로 설정되어 있어야 합니다.
일단 이렇게만 하면 컨트롤의 아이템은 드래그할 수 있습니다.
하지만, 드래그해도 마우스 커서가 담배없는 금연 커서(동그라미에 사선)으로 바뀌면서 드래그할 수
없다고 나타납니다. 드래그했을 때 드래그한 아이템을 리스트뷰가 다시 받아들일 수 있게 하려면
그 컨트롤의 OnDragOver 이벤트 핸들러를 만들고, 인자로 넘어오는 Accept를 true로
세팅해주면 됩니다. 하지만, 이렇게만 하면 파일이든 뭐든 다 받을 수 있다고 표시되므로,
드래그된 소스가 적절한지를 검사해야 합니다. 여기까지 하면 커서는 드래그된 아이템을 받을 수
있다는 표시(아래에 사각형이 있는 커서)로 바뀝니다.
하지만 이정도만 가지고는 실제로 드래그된 아이템을 드랍해도 아이템이 움직이지 않습니다.
역시 또 하나의 이벤트 핸들러를 작성해야 하는데, 이번엔 OnDragDrop 이벤트에서 작업합니다.
여기까지가 vcl 컨트롤 드래그/드랍의 기본 메커니즘입니다. 이것을 리스트뷰에 적용한 실제
코드를 보여드립니다.
void __fastcall TForm1::ListView1DragOver(TObject *Sender, TObject *Source,
int X, int Y, TDragState State, bool &Accept)
{
if(dynamic_cast<TListView *>(Source) == NULL) return;
Accept = true;
}
void __fastcall TForm1::ListView1DragDrop(TObject *Sender, TObject *Source,
int X, int Y)
{
if(dynamic_cast<TListView *>(Source) == NULL) return;
SendMessage(ListView1->Handle, LVM_SETITEMPOSITION, ListView1->ItemFocused->Index, MAKELPARAM(X, Y));
}
물론, 앞에서 말씀드렸다시피 리스트뷰의 DragMode 프로퍼티는 dmAutomatic으로 설정되어
있어야 합니다. 또한 위의 두 함수는 그냥 작성하는 게 아니라, 각각 OnDragOver와 OnDragDrop
이벤트를 더블클릭해서 만든 이벤트 핸들러라는 것을 잊지 마세요.
두번째 핸들러인 ListView1DragDrop()을 보시면 리스트뷰에 LVM_SETITEMPOSITION 메시지를
보내는 것을 볼 수 있는데, 이 메시지가 실제로 아이템의 위치를 옮기는 역할을 합니다.
그럼 참고하시길...
|