Passing WPARAM into DragQueryFile not compatible?

主宰稳场 提交于 2021-02-10 09:24:25

问题


I'm kinda confused. When a file is dragged onto a window with WS_EX_ACCEPTFILES flagged it places a PostMessage into the WndProc function, which sets UINT message to WM_DROPFILES and, according to

https://msdn.microsoft.com/en-us/library/windows/desktop/bb774303(v=vs.85).aspx

the WPARAM = (WPARAM) (HDROP) hDrop; So am I wrong to assume that I can use the WPARAM to initialize the HDROP or just pass it into the DragQueryFile ??

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_CREATE:
    return 0;

case WM_DROPFILES:
    TCHAR* FilePath;
    HDROP hDrop = wParam; //wParam cannot be used to ini. an entity of type HDROP
    //HDROP hdrop = (HDROP)wParam; initialization of hDrop is skipped by case label
    DragQueryFile(wParam, 0, FilePath, 0); //wParam not compatible
    return 0;

case WM_DESTROY:
    PostQuitMessage(0);
    return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}

Every kind of help is appreciated.


回答1:


You need to cast wparam to HDROP and then iterate over dropped file paths supplying buffer.

case WM_DROPFILES:
{
    auto const drop_handle{reinterpret_cast< ::HDROP >(wParam)};
    auto const dropped_files_count
    {
        ::DragQueryFileW(drop_handle, 0xFFFFFFFF, nullptr, 0)
    };
    ::std::vector< wchar_t > buffer;
    for(::UINT dropped_file_index{0}; dropped_files_count != dropped_file_index; ++dropped_file_index)
    {
        auto const file_path_symbols_count_excluding_terminating_null
        {
            ::DragQueryFileW(drop_handle, dropped_file_index, nullptr, 0)
        };
        if(0 < file_path_symbols_count_excluding_terminating_null)
        {
            auto const buffer_size{file_path_symbols_count_excluding_terminating_null + 1};
            buffer.resize(buffer_size);
            auto const copied_symbols_count_excluding_terminating_null
            {
                ::DragQueryFileW(drop_handle, dropped_file_index, buffer.data(), buffer_size)
            };
            if(copied_symbols_count_excluding_terminating_null == file_path_symbols_count_excluding_terminating_null)
            {
                buffer.back() = L'\0'; // just in case....
                // buffer now contains file path...
            }
        }
    }
    break;
}

However note that even though handling WM_DROPFILES should work, the preffered way to handle drag-and drop is to implement IDropTarget interface and register it as drop target handler for your application.




回答2:


You're nearly there. You had the right answer, but you commented it out, due to a different error relating to your use of case labels. Instead of going backwards with your HDROP and WPARAM, you should just have fixed that different error ;)

The cast is correct, but you need to scope your case "body" (because, in fact, a case has no body, or scope of its own), and that's what the error's telling you:

case WM_DROPFILES: {
    TCHAR FilePath[MAX_PATH];
    HDROP hdrop = (HDROP)wParam; 
    DragQueryFile(hdrop, 0, FilePath, 0);
    return 0;
 }

Here I've added { and } to introduce a block scope.




回答3:


add VTT answered.

you can replace ::std::vector< wchar_t > buffer; with std::wstring buffer

code

case WM_DROPFILES:
{
    auto const drop_handle{ reinterpret_cast<::HDROP>(wParam) };
    auto const dropped_files_count
    {
        ::DragQueryFileW(drop_handle, 0xFFFFFFFF, nullptr, 0)
    };
    ::std::wstring buffer;
    for (::UINT dropped_file_index{ 0 }; dropped_files_count != dropped_file_index; ++dropped_file_index)
    {
        auto const file_path_symbols_count_excluding_terminating_null
        {
            ::DragQueryFileW(drop_handle, dropped_file_index, nullptr, 0)
        };
        if (0 < file_path_symbols_count_excluding_terminating_null)
        {
            auto const buffer_size{ file_path_symbols_count_excluding_terminating_null + 1 };
            buffer.resize(buffer_size);
            auto const copied_symbols_count_excluding_terminating_null
            {
                ::DragQueryFileW(drop_handle, dropped_file_index, &buffer[0], buffer_size)
            };
            if (copied_symbols_count_excluding_terminating_null == file_path_symbols_count_excluding_terminating_null)
            {
                buffer.back() = L'\0'; // just in case....
                // buffer now contains file path...
                MessageBox(0, buffer.c_str(), buffer.c_str(), MB_OK);
            }
        }
    }
    break;
}


来源:https://stackoverflow.com/questions/43823771/passing-wparam-into-dragqueryfile-not-compatible

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!