winapi - 将文件/文本拖放到托盘图标(C#、Windows 窗体)

标签 winapi dll drag-and-drop hook system-tray

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

我知道是impossible使用更高级别的 C# WindowsForms API 来执行此操作,因为 NotifyIcon 不支持拖动事件。

因此,在一位更有 Windows 经验的 friend 的帮助下,我开始通过 Win32 API 进行尝试。这个想法是在托盘窗口处理程序中注册一个钩子(Hook)(在“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,但无济于事),但它开始感觉对于这样一个“简单”的用例来说,太过分了。

所以百万美元的问题是:

  1. 真的有必要将 Hook 卸载到 DLL 吗?
  2. 我真的需要借助共享内存来完成此任务吗?
  3. (额外问题)WM_DROPFILES 仅适用于文件;如何为文本触发放置事件?

请记住,这是我第一次使用 .NET、C# 和 Win32(不到一周);解释原因的详细答案 - 而不仅仅是陈述 - 将不胜感激!

谢谢。

最佳答案

是的,您确实需要执行这些操作,因为该窗口由另一个进程拥有。全局钩子(Hook)需要一个可以注入(inject)的 DLL。完整的 D+D 支持需要 RegisterDragDrop 和 COM 代码。令人讨厌的 COM 代码。

不,你真的不应该这样做,因为其他人可能已经有与你相同的想法。并首先交付了他的程序。 MSFT 的 appcompat 团队肯定对此做了一场噩梦。小心雷蒙·陈,他脾气很坏。

关于winapi - 将文件/文本拖放到托盘图标(C#、Windows 窗体),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3926728/

相关文章:

c++ - 通过 MS RPC 发送 wstring 和 ptime

windows - 令人沮丧的处理窗口消息(WM_XX)

python - 没有名为 '_pywrap_tensorflow_internal' 的模块

python - cx_freeze:ImportError:DLL加载失败:找不到此指定的模块

java - 不接受来自外部资源管理器的 Eclipse RCP 放置文件

c# - WPF - DragOver 事件没有在我的列表框上触发

.net - 解释一下这个功能可能会出现什么问题(如果有的话)

c++ - 提取文件的高分辨率图标或缩略图

c# - 将结构数组 ByRef 从 C# 传递到 C++ 并将其取回

c# - 如何在按钮上触发 "DragStarting"事件?