c++ - Ole 拖放故障排除

标签 c++ winapi atl wtl

我使用 WTL 创建了一个对话框,继承自 CDialogImpl 类,在主对话框中我创建了另一个对话框,并在第二个子对话框中创建了一个列表控件。我想向列表控件添加拖放功能,我在网上阅读了有关 WM_DROPFILES 方法和 Ole Drop Target 的信息,我选择了后者。 我已经按照 this 实现了 IDropTarget 接口(interface)方法。 我已在所有对话中将接受文件选项设置为 TRUE,我已在子对话类中实例化 IDropTarget 并在其 WM_INITDIALOGUE 处理程序中调用以下方法:

//drag& drop 
        lpDropTarget = (LPDROPTARGET)new TDropTarget(m_hWnd);
        CoLockObjectExternal(lpDropTarget, true, true);

        // register the HWND as a drop target
        RegisterDragDrop(m_hWnd, lpDropTarget);

lpDropTarget 实例化如下:

LPDROPTARGET lpDropTarget;

就是这样。之前没有真正使用过 Ole,所以我尝试了以下场景来寻求运气:

  1. 我已向 List 控件 HWND 注册了 RegisterDragDrop,并将其父对话框设置为接收我发送的通知 WM_OLEDROP WM_USER + 1。好的,拖放光标已显示,但没有调用 IDataTarget 函数的实现。

  2. RegisterDragDrop 用于子对话和通知。

  3. 为主对话框及其通知注册DragDrop。

在后面的情况(2和3)中,用于拖放的光标甚至没有出现,它向我显示了不允许拖放的光标。 现在,所有对话框和列表控件都已设置为接受来自 Visual Studio 设计器的文件。 我仅限于使用ATL/WTL/WINAPI,不能使用MFC。 我做错了什么?

最佳答案

对于您来说,WM_DROPFILES 是您唯一需要处理的事情。无需摆弄 IDropTarget 等。

如果您的应用程序不需要在管理模式下运行,请不要在管理模式下运行。禁用相同的链接器设置(UAC 执行级别 = asInvoker)。另外,在非管理员模式下运行 VS,以便您的应用程序也以非管理员进程启动。这样,Explorer.exe 就能够向您的应用程序发送 WM_DROPFILES 消息。

如果您的应用程序需要以管理员模式运行,您需要允许其他应用程序向您的应用程序(窗口)发送一组消息。执行以下操作:

ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD);
ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ADD);
ChangeWindowMessageFilter(0x0049, MSGFLT_ADD);

您可能还想使用更新的函数:ChangeWindowMessageFilterEx .

请注意,如果您的应用程序必须以管理员身份运行,并且您需要使用 GetProcAddress 动态定位其中一个函数,以便您的应用程序可以在该函数不可用的操作系统上运行(例如.Windows XP)。

关于c++ - Ole 拖放故障排除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13570160/

相关文章:

c++ - CoMarshalInterThreadInterfaceInStream 为 Visual Basic 6 类返回 0x800A0062

python - 如何将 Eigen::Ref 与 pybind11 一起使用?

c++ - 写入具有 map 容器内容的文件 C++

java - 关闭从 Java 创建的资源管理器窗口

windows - C++ 将32位bmp图像转换为24位bmp和16位bmp

c++ - 自 Visual Studio 2017 15.5.1 以来,_com_ptr_t 出现 Intellisense 错误

c++ - 输出到文件 C++

c++ - 理解 C++ 代码块

c++ - 帮助异步 I/O

windows - 为 COM 接口(interface)启用编码(marshal)处理需要什么?