탐색기로부터 드래그&드롭을 받는 방법은 이미 여러차례 소개가 되어 있어
구현하기 조금도 어렵지 않습니다. 하지만, 폼위의 특정한 컨트롤로 드래그 받을 때의 처리 방법 중
컴포넌트를 직접 수정하는 방법은 소개되지 않은 것 같아 올려 둡니다.
사실은 코드를 복사 신공으로 넣으려는데, 제 소스를 찾는 것보다 여기에 올려두는게
찾기가 더 편리한 관계로... ㅡ..ㅡ;;
일반적으로 탐색기로부터 폼으로 드래그를 받는 방법은
class TForm...
{
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, WMDropFiles) // 드롭 메시지 받아 들이기.
END_MESSAGE_MAP(inherited)
// 드래그&드롭 메시지 핸들러
//
void __fastcall WMDropFiles(TWMDropFiles &msg)
{
int nFileCount = DragQueryFile((HDROP)msg.Drop, 0xFFFFFFFF, NULL, 0);
for(int c = 0; c < nFileCount; c++)
{
char filename[MAX_PATH];
int nLength = DragQueryFile((HDROP)msg.Drop, c, filename, MAX_PATH);
if (nLength)
AddFile(filename);
}
DragFinish((HDROP)msg.Drop);
}
};
대략 이런 식으로 하고,
FormCreate 핸들러에서
{
DragAcceptFiles(Handle, true);
}
이렇게 해주면 폼으로 받는 것은 쉽게 됩니다.
그러면 폼 위의 특정한 컨트롤만 드래그를 받고 싶을때는 어떻게 할까요?
이때는 WM_DROPFILES 메시지를 받아서 처리해야 하므로 서브클래싱을 하면 되죠.
하지만 컴포넌트를 직접 수정하면 더 코드가 쉽고 깔끔해집니다.
가령 파일리스트를 나타내는 특정 TListView로 드래그를 받고 싶다면
//---------------------------------------------------------------------------
void AddFile(String filename); // 파일명이 통보될 때 처리할 전역 메소드.
//---------------------------------------------------------------------------
// TListView 에만 드래그&드롭을 받는 방법
class TListView : public Comctrls::TListView
{
typedef Comctrls::TListView inherited;
public:
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, WMDropFiles) // 드롭 메시지 받아 들이기.
END_MESSAGE_MAP(inherited)
// 드래그&드롭 메시지 핸들러
//
void __fastcall WMDropFiles(TWMDropFiles &msg)
{
int nFileCount = DragQueryFile((HDROP)msg.Drop, 0xFFFFFFFF, NULL, 0);
for(int c = 0; c < nFileCount; c++)
{
char filename[MAX_PATH];
int nLength = DragQueryFile((HDROP)msg.Drop, c, filename, MAX_PATH);
// Do something..
if (nLength)
AddFile(filename);
}
DragFinish((HDROP)msg.Drop);
}
// 드래그 받을 WinControl을 지정하는 부분. FormCreate 핸들러에서 호출하는게 좋음.
//
void InitDragAccept()
{
DragAcceptFiles(Handle, true);
}
};
#define TListView ::TListView
//---------------------------------------------------------------------------
이런식으로 코딩해주고
폼 선언 클래스 바로 위에
이 코드를 넣어주면 됩니다.
가령
class TForm1 : public TForm
{
...
}
이 클래스 선언 위에 바로 넣으면 된다는 것이죠.
그리고 폼 위의 TListView 중에 드래그 받을 ListView에 대해서만
FormCreate 핸들러에서
{
ListView1->InitDragAccept();
}
이렇게만 호출해주면 됩니다.
위의 예에서는 파일명이 통보될때 처리할 AddFile(String filename);
함수만 구현해주면 끝입니다.
복수개를 드롭 할때는 차례대로 파일명이 담긴채 AddFile 메소드를 계속 호출해주는데
순서는 OS 맘대이고, 폴더인 경우는 폴더명으로 오기 때문에
폴더인지는 DirectoryExists(filename); 함수를 호출해서 검사해 주면 됩니다.
그럼.