【发布时间】:2011-04-25 00:18:41
【问题描述】:
我正在尝试允许拖放到我的应用程序上的托盘图标。
我知道 impossible 使用更高级别的 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 仅适用于文件;如何为文本触发 drop 事件?
请记住,这是我第一次使用 .NET、C# 和 Win32(不到一周);解释原因的详细答案 - 而不仅仅是说明 - 将不胜感激!
谢谢。
【问题讨论】:
标签: winapi dll drag-and-drop hook system-tray