将WPARAM传递给DragQueryFile不兼容?

时间:2017-05-06 18:05:00

标签: c++ windows winapi

我有点困惑。当文件被拖动到WS_EX_ACCEPTFILES标记的窗口上时,它将PostMessage放入WndProc函数,该函数将UINT消息设置为WM_DROPFILES,并根据

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

WPARAM =(WPARAM)(HDROP)hDrop;所以我错误地假设我可以使用WPARAM来初始化HDROP或者只是将它传递给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);
}

感谢各种帮助。

3 个答案:

答案 0 :(得分:1)

您需要将wparam转换为HDROP,然后迭代提供缓冲区的已删除文件路径。

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;
}

但请注意,即使处理WM_DROPFILES应该有效,处理拖放的优先方法是为您的应用程序实施IDropTarget interfaceregister it as drop target handler

答案 1 :(得分:0)

你快到了。您有正确的答案,但由于与您使用case标签有关的不同错误,您对其进行了评论。不应该使用HDROPWPARAM向后移动,而应该修复不同的错误;)

演员阵容是正确的,但你需要确定你的案例范围&#34; body&#34; (因为,事实上,案件没有任何主体或自己的范围),这就是错误告诉你的:

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

此处我添加了{}来介绍块范围。

答案 2 :(得分:0)

添加已回答的VTT。

您可以将::std::vector< wchar_t > buffer;替换为std::wstring buffer

代码

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;
}