如何在.NET中监听Windows广播消息?
我有一个想要从
Windows收听广播消息的对象(即非形式),例如:
> .NET中设置非WinForm窗口的机制是什么,可以监听广播消息? 即是否有WindowsListener类? 奖金Chatter 在过去,在其他开发环境中,框架提供了 HWND listener = AllocateHWnd(ListenerWindowProc); ListenerWindowProc是我的窗口过程方法: private void ListenerWindowProc(ref Message msg) { switch (msg.msg) { case WM_SETTINGCHANGE: { ... } break; case WM_POWERBROADCAST: { ... } break; case WM_THEMECHANGED: { ... } break; ... } DefWindowProc(msg); } 秘诀是AllocateHwnd功能: 伪代码: public static HWND AllocateHWnd(WndMethod method) { HWND result; WNDCLASS tempClass; Boolean classRegistered; UtilWindowClass.hInstance := HInstance; Boolean classRegistered = GetClassInfo(HInstance,UtilWindowClass.lpszClassName,tempClass); if (!classRegistered || (tempClass.lpfnWndProc != @DefWindowProc) { if classRegistered { UnregisterClass(utilWindowClass.lpszClassName,HInstance); RegisterClass(utilWindowClass); } result = CreateWindowEx(WS_EX_TOOLWINDOW,'',WS_POPUP,HInstance,null); if (!Method != null) SetWindowLong(result,GWL_WNDPROC,UInt32(MakeObjectInstance(Method))); } } 使用与UtilWindowClass相关的更多密码. 当你完成后,你会DeallocateHwnd: DeallocateHwnd(listenerWindow); 我知道在.NET框架深处,他们将响应WM_SETTINGCHANGE并更新内部.NET数据结构.我会窃取该代码,但Reflector找不到对WM_SETTINGCHANGE的引用;大概是因为反编译的代码没有显示常量名称,只是常量0x001A. 更新: 注意:此对象应该是自包含的.使用该类的任何人都不应该修改他们的应用程序,以便我的类返回正确的数据.它应该从Windows本身收听广播,而不是要求开发人员修改他们的应用程序来为我监听某些消息(即它不应该破坏困难或复杂操作的封装) 例如: public class FrobbingGrobber: IDisposable { private IntPtr hwnd = IntPtr.Zero; public FrobbingGrobber { _hwnd = AllocateHwnd(listenerWindowProc); } protected virtual void listenerWindowProc(ref Message msg) { switch (msg.msg) { case WM_DwmColorizationColorChanged,WM_DwmCompositionChanged: { UpdateColorizationColor(); } break; } DefWindowProc(msg); } public void UpdateColorizationColor() { NativeMethods.DwmGetColorizationColorParameters_UndocumentedExport137(ref _color); } public void Dispose() { Dispose(true); } protected void Dispose(Boolean safeToDisposeManagedObjects) { if (_hwnd != 0) { DeallocateHwnd(_hwnd); _hwnd = 0; } if (safeToDisposeManagedObjects) GC.SuppressFinalize(this); } public ~FrobbingGrobber { //If the user forgot to call Dispose i could (correctly) leak a handle,//or i could fix their mistake for them Dispose(false); } 解决方法
我假设您给出的示例仅仅是:示例.因为其中许多已经管理了等价物,已经为您包装了所有这些.就像WM_POWERBROADCAST由
Microsoft.Win32.SystemEvents.PowerModeChanged event包装一样.WM_SETTINGCHANGED相当于
Microsoft.Win32.SystemEvents.UserPreferenceChanged .
无论如何,像你描述的广播消息被发送到所有顶级窗口,所以你真正需要做的就是创建一个顶级窗口并覆盖其WndProc方法来处理你感兴趣的通知消息. 使用 .NET Framework在内部完成所有这些工作.例如,用于System.Windows.Forms.Timer的内部TimerNativeWindow类.如果您想在Reflector中查看自己的实现,请从那里开始查看.您应该能够搜索常量,但深入到类的层次结构中,您知道必须在内部处理这样的通知消息,这通常是一种更智能的搜索方式. SystemEvents类(如上所述)也是开始寻找实现策略的好地方. 请注意,你不能在这里使用仅消息窗口(HWND_MESSAGE),因为they won’t receive broadcast events.我上面提到的TimerNativeWindow确实这样做,因为它不关心广播事件,所以不要只复制和粘贴代码从那里! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 无法在Windows上安装python lxml(和libxml2)
- 窗口 – 如何确定我的进程是否受CPU限制,I / O绑定,内存绑定
- windows-server-2008 – 如何在Windows性能监视器中保存计数
- 使用Windows 8 SDK编译Windows 7
- microsoft-metro – Metro UI Multibinding?
- Windows Azure:尝试创建凭据时的身份验证错误
- windows – 如何为下次重启计划表面扫描(chkdsk),而不是现在
- windows – 通过LLVM或GCC定位WinRT
- .net – Windows窗体应用程序的颜色选择器
- Windows 7 64位计算机上的Ruby安装程序
- Windows Azure AppFabric访问控制服务(ACS)中的O
- windows-phone-8 – Rx 2.1:如何在Dispatcher上
- .net – 功能键的标准操作列表
- Windows – 在UAC下,为什么我不能将文件写为模拟
- windows – 如何打开.msu扩展文件?
- windows-server-2003 – IIS6,Windows 2003 Serv
- Windows EventLog:操作速度有多快?
- windows-7 – 我需要做什么以及为Windows Vista
- Windows .bat / .cmd函数库在自己的文件?
- Windows Server 2016-WinSer 2016标准版与数据中