간단히 Windows 에서 파일을 Drag&Drop 으로 받는 방법들을 쓰는 프로그램들이 더러 있습니다. 이를 Windows API 로만 처리 하려면 다음과 같은 코드가 필요 합니다.
먼저, DragAcceptFiles() API 로 이벤트를 받을 Windows Handle 을 등록 합니다.
DragAcceptFiles( hWindow, TRUE );
이는 최초 WM_CREATE 부분에서 처리하는 방법을 써도 되나, 부분적으로 해당 이벤트를 받지 않고 싶을때 FALSE 대입으로 처리 할 수도 있습니다.
해당 이벤트는 WinMain() 에서 WM_DROPFILES 로 넘어 오게 됩니다. 이때 취해야 하는 인자는 wParam 으로 다음과 같이 처리 할 수 있습니다.
BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_DROPFILES: { HDROP hDrop = (HDROP)wParam; } break; } return FALSE; }
hDrop 이벤트를 받아 파일 목록을 간단히 만드는 예제는 다음과 같습니다.
DragAcceptFiles( hWindow, FALSE );
vector<TSTRING> dragFiles;
TCHAR* refFiles;
UINT refFilesLen;
POINT refPoint;
UINT dropCount = DragQueryFile( hDrop, 0xFFFFFFFF, refFiles, refFilesLen );
if ( dropCount > 0 )
{
for( int cnt=0; cnt<dropCount; cnt++)
{
int fLen = DragQueryFile( hDrop, cnt, NULL, 0 ) + 1;
TCHAR* newFName = new TCHAR[fLen];
memset( newFName, 0, sizeof(TCHAR)*fLen );
DragQueryFile( hDrop, cnt, newFName, fLen );
if ( checkFileExists( newFName ) == true )
{
TSTRING newFile = newFName;
dragFiles.push_back( newFile );
}
delete[] newFName;
}
}
DragAcceptFiles( hWindow, TRUE );
여기서 TSTRING 은 UNICODE 사용일 경우 std::wstring 을 지정하고, MBCS 의 경우는 std::string 을 지정 하도록 되어 있습니다.
이 방법을 사용하면 일일히 파일을 열도록 하는 버튼과 같은 UX 를 줄일 수 있는 요소가 되지 않을까 합니다.