간단히 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 를 줄일 수 있는 요소가 되지 않을까 합니다.


Posted by 견족자K rageworx