2

我使用 WTL 创建了一个对话框,继承自 CDialogImpl 类,在主对话框中我创建了另一个对话框,在第二个子对话框中创建了一个列表控件。我想向列表控件添加拖放功能,我在网上阅读了有关 WM_DROPFILES 方法和 Ole Drop Target 的信息,我选择了后者。我已经按照 这个实现了 IDropTarget 接口方法。我已在所有对话中将接受文件选项设置为 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. RegisterDragDrop 用于主对话框和它的通知。

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

4

1 回答 1

3

因为你WM_DROPFILES是你唯一需要处理的事情。无需摆弄之类的IDropTarget

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

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

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

您可能还想使用更新的功能:ChangeWindowMessageFilterEx

请注意,如果您的应用程序必须以管理员身份运行,并且您需要使用 动态定位这些功能之一GetProcAddress,以便您的应用程序可以在没有此功能的操作系统上运行(例如 Windows XP)。

于 2012-11-27T15:46:42.253 回答