Winapi 将文件/文本拖放到任务栏图标(C#,WindowsForms)

Winapi 将文件/文本拖放到任务栏图标(C#,WindowsForms),winapi,dll,drag-and-drop,hook,system-tray,Winapi,Dll,Drag And Drop,Hook,System Tray,我正在尝试允许拖放到我的应用程序上的托盘图标 我知道这是用更高级别的C#WindowsForms API实现的,因为NotifyIcon不支持拖动事件 因此,在一位更有windows经验的朋友的帮助下,我开始尝试通过Win32 API实现这一点。这个想法是在托盘窗口处理程序中注册一个钩子(在“SysPager”窗口处理程序上设置DragAcceptFiles(hWnd,TRUE);之后) 挂钩和下降部分从托盘工作到DLL LRESULT CALLBACK myHookProc (int code

我正在尝试允许拖放到我的应用程序上的托盘图标

我知道这是用更高级别的C#WindowsForms API实现的,因为
NotifyIcon
不支持拖动事件

因此,在一位更有windows经验的朋友的帮助下,我开始尝试通过Win32 API实现这一点。这个想法是在托盘窗口处理程序中注册一个钩子(在“SysPager”窗口处理程序上设置
DragAcceptFiles(hWnd,TRUE);
之后)

挂钩和下降部分从托盘工作到DLL

LRESULT CALLBACK myHookProc (int code, WPARAM wParam, LPARAM lParam){
  if (code == HC_ACTION)
  {
    PMSG msg = (PMSG) lParam;
    switch(msg->message){
      case WM_DROPFILES:
        ::MessageBox(NULL, L"Dropped files!", L"Test", MB_OK);
        // call my app's registered hook
        break;
  }
  return CallNextHookEx(oldHookProc, code, wParam, lParam);
}
正如所料,我得到了弹出的消息框

问题是,我现在需要在C#(WindowsForms)应用程序上调用一个函数来通知此事件。这就是我撞到砖墙的地方

当我在DLL中注册应用程序的回调时,我将其存储;但是当调用
myHookProc
时,它的值为NULL

原来我误解了DLL的工作原理;我的应用程序和托盘区域之间没有共享实例(它们被复制,或者如果可以这样称呼的话,每个都有自己的“实例”),因此我不能使用任何静态变量或类似的东西将回调引用保留回我的应用程序

花了几个小时研究这个问题,唯一的解决方案似乎是共享内存(尝试了我在某个论坛上遇到的
#pragma data_seg
,但没有效果),但对于这样一个“简单”的用例来说,它开始觉得太过分了

因此,百万美元的问题是:

  • 真的有必要将挂钩卸载到DLL吗
  • 我真的需要借助共享内存来实现这一点吗
  • (奖金问题)WM_DROPFILES仅适用于文件;我如何才能让文本触发丢弃事件
  • 请记住,这是我第一次使用.NET、C#和Win32(不到一周);详细的答案解释为什么-而不是仅仅说明-将不胜感激


    谢谢。

    是的,您确实需要执行这些操作,因为该窗口属于另一个进程。全局钩子需要一个可以注入的DLL。完全的D+D支持需要RegisterDragDrop和COM代码。Icky COM代码


    不,你真的不应该这样做,因为其他人可能已经有了和你一样的想法。并先把他的程序送去了。MSFT的appcompat团队肯定会为此做噩梦。小心Raymond Chen,他脾气不好。

    我理解这是个坏主意,因为你提到的原因就是——其他人的应用程序可能会尝试这样做,然后它会变得一团糟。然而,这个项目()似乎能够找到特定的应用程序图标,如果它不是隐藏的。有了这个,这仍然是一个坏主意吗?我已经测试了它,它成功地检测到你是否把东西放在你的图标上,但是它总是在托盘上显示允许放下的标志。。。无论如何,UX对于windows应用来说有点奇怪。。。把东西拖到托盘上。奇怪的是,你通常不会在那里看到作者承认他无法完成的项目。很难看出这是在浪费你的时间。我同意你的看法。我将发布没有此功能的应用程序。如果有很多人为此哭泣,我会再给他们一次机会:)