C++ GUI 中的拖放事件 (WM_DROPFILES)
Posted
技术标签:
【中文标题】C++ GUI 中的拖放事件 (WM_DROPFILES)【英文标题】:Drag&drop event (WM_DROPFILES) in C++ GUI 【发布时间】:2018-07-06 07:10:05 【问题描述】:我正在尝试创建一个简单的应用程序,用户可以在其中将文件从窗口(通常是资源管理器)外部拖放到窗口内部的区域中。我的最终目的是获取文件路径以供以后处理。
目前我可以将文件拖放到该区域,但我从未收到 WM_DROPFILES 事件。我尝试了一些相关的函数(DoDragDrop、RegisterDragDrop、CDropSource),但它们要么无法编译,要么编译不成功。
谁能告诉我是否缺少设置任何属性?
在此先感谢
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
switch (Message)
case WM_CREATE:
CreateWindowEx(
WS_EX_ACCEPTFILES,
TEXT("static"),
TEXT("Drag and drop your file to this area"),
WS_VISIBLE | WS_CHILD,
20, // x
20, // y
120, // w
60, // h
hwnd, // parent window
(HMENU) 1, // unique label
NULL, NULL);
case WM_DROPFILES:
MessageBox(hwnd, "Dragged!", "Title", MB_OK | MB_ICONINFORMATION);
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
return 0;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
memset(&wc,0,sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = "WindowClass";
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return 0;
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
"WindowClass",
"MySimpleApp",
WS_VISIBLE | WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
WINDOW_W,
WINDOW_H,
NULL,NULL,hInstance,NULL);
if (hwnd == NULL)
MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return 0;
while (GetMessage(&msg, NULL, 0, 0) > 0)
TranslateMessage(&msg);
DispatchMessage(&msg);
return msg.wParam;
【问题讨论】:
【参考方案1】:您没有收到WM_DROPFILES
消息,因为您没有继承您创建的 STATIC 控件来接收发送给它的消息。您假设您可以在控件的 parent 窗口中捕获消息,但这不是消息所在的位置。它被发送到您实际放置的窗口 - STATIC 控件。
试试这个:
LRESULT CALLBACK StaticWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
if (uMsg == WM_DROPFILES)
MessageBox(hwnd, "Dragged!", "Title", MB_OK | MB_ICONINFORMATION);
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
switch (uMsg)
case WM_CREATE:
HWND hStatic = CreateWindowEx(
WS_EX_ACCEPTFILES,
TEXT("static"),
TEXT("Drag and drop your file to this area"),
WS_VISIBLE | WS_CHILD,
20, // x
20, // y
120, // w
60, // h
hwnd, // parent window
(HMENU) 1, // unique label
NULL, NULL);
SetWindowSubclass(hStatic, &StaticWndProc, 0, 0);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
return 0;
DoDragDrop()
和RegisterDragDrop()
(您应该使用它们而不是WM_DROPFILES
)与接收WM_DROPFILES
无关。
【讨论】:
【参考方案2】:你不见了
DragAcceptFiles( hwnd, TRUE );
把它放在消息循环之前。
WM_DROPFILES
无法正确地将数据从 32 位应用程序传输到 64 位应用程序。可以通过实施IDropTarget
并删除WM_DROPFILES
处理来补救。
【讨论】:
以上是关于C++ GUI 中的拖放事件 (WM_DROPFILES)的主要内容,如果未能解决你的问题,请参考以下文章
HTML5 拖放 getData() 仅适用于 Chrome 中的拖放事件?
HTML5 拖放 getData() 仅适用于 Chrome 中的拖放事件?