Search code examples
c++winapidrag-and-drop

How do i extract dragged & dropped filenames from a DROPFILES struct


I have a window with no controls with WS_EX_ACCEPTFILES enabled and the event triggers successfully when dragging files from explorer. What I need to do is extract the files to a vector. From what I've read, the wParam is supposed to contain the location of the files within a DROPFILES struct but I don't know how to access them.

LRESULT CALLBACK StaticWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR 
uIdSubclass, DWORD_PTR dwRefData)
{
    if (uMsg == WM_DROPFILES)
    {
       // extract files here
       vector<string> files;

    }

    return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}

I don't need to send them to any controls since my window is for an openGL application, I just need to retain them in a list, how can it be done?


Solution

  • Per the WM_DROPFILES documentation:

    Parameters

    hDrop

    A handle to an internal structure describing the dropped files. Pass this handle to DragFinish, DragQueryFile, or DragQueryPoint() to retrieve information about the dropped files.

    lParam

    Must be zero.

    Simply type-cast the wParam to HDROP and call the drag-drop functions as needed, eg:

    LRESULT CALLBACK StaticWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
    {
        if (uMsg == WM_DROPFILES)
        {
           HDROP hDrop = reinterpret_cast<HDROP>(wParam);
    
           // extract files here
           vector<string> files;
           char filename[MAX_PATH];
    
           UINT count = DragQueryFileA(hDrop, -1, NULL, 0);
           for(UINT i = 0; i < count; ++i)
           {
              if (DragQueryFileA(hDrop, i, filename, MAX_PATH))
                  files.push_back(filename);
           }
    
           DragFinish(hDrop);
           return 0;
        }
    
        return DefSubclassProc(hwnd, uMsg, wParam, lParam);
    }
    

    Alternatively:

    LRESULT CALLBACK StaticWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
    {
        if (uMsg == WM_DROPFILES)
        {
           HDROP hDrop = reinterpret_cast<HDROP>(wParam);
    
           // extract files here
           vector<string> files;
           string filename;
    
           UINT count = DragQueryFileA(hDrop, -1, NULL, 0);
           for(UINT i = 0; i < count; ++i)
           {
              UINT size = DragQueryFileA(hDrop, i, NULL, 0);
              if (size > 0)
              {
                  filename.resize(size);
                  DragQueryFileA(hDrop, i, &filename[0], size+1);
                  files.push_back(filename);
              }
           }
    
           DragFinish(hDrop);
           return 0;
        }
    
        return DefSubclassProc(hwnd, uMsg, wParam, lParam);
    }