Xha*_*lie 4 c# windows wpf winapi
我正在编写一个WPF应用程序,它将在系统托盘中放置一个图标,作为练习,我想在不依赖System.Windows.Forms和使用它NotifyIcon或NativeWindow类的情况下执行此操作.
这很容易 - Shell_NotifyIcon从C#调用并不难 - 事实上,我已经成功完成了我的任务.
作为这项工作的一部分,我不得不创建一个窗口句柄,其唯一目的是从系统托盘接收消息.我创建本机窗口如下:
// Create a 'Native' window
_hwndSource = new HwndSource(0, 0, 0, 0, 0, 0, 0, null, parentHandle);
_hwndSource.AddHook(WndProc);
Run Code Online (Sandbox Code Playgroud)
消息循环被挂钩AddHook(),消息在一个如下所示的函数中处理:
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
// Handle windows messages in this...
}
Run Code Online (Sandbox Code Playgroud)
而且,最后,当需要销毁这个东西时,我会通过发布WM_CLOSE消息并处理它来关闭窗口HwndSource.
if (null != _hwndSource)
{
UnsafeNativeMethods.PostMessage(_hwndSource.Handle, WindowMessage.WM_CLOSE, 0, 0);
_hwndSource.Dispose();
_hwndSource = null;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:构造函数的前三个参数HwndSource分别是本机Win32窗口的类样式,样式和扩展样式.对于只能用作窗口消息目标的不可见窗口,它们应该是什么?
我的默认值为零,零和......呃..零可以工作,但我使用Spy ++来检查Windows.Forms.NotifyIcon它做了什么,它似乎NativeWindow创建了具有以下内容:
Class Style: <zero>
Styles: WS_CAPTION, WS_CLIPSIBLINGS,
WS_OVERLAPPED
Extended Styles: WS_EX_LEFT, WS_EX_LTRREADING,
WS_EX_RIGHTSCROLLBAR, WS_EX_WINDOWEDGE
Run Code Online (Sandbox Code Playgroud)
对于不可见的窗口,这些是否重要?(我想不是.)
Windows样式标志可以追溯到1986年,当时Windows v1.0发布.在过去的29年中有很多 appcompat hacks和10个主要版本,当应用程序指定了不同的版本时,Windows会默默地覆盖样式标记.然而,没有什么比这更糟糕的,请注意WS_OVERLAPPED样式标志的值为0.这要求一个普通窗口,您自动获得这样一个窗口的相应样式标志.
您的HwndSource窗口具有完全相同的样式标志,也许您在Spy ++中找不到正确的样式标志.所以你没有问题.不,当窗口永远不可见时,它们无关紧要.
请注意代码中的错误,因为您在调用PostMessage()后立即销毁窗口,所以您发布的WM_CLOSE消息实际上从未被处理过.只是删除它,没有必要很好地询问窗口,它不会反对.但是,您必须使用NIM_DELETE调用Shell_NotifyIcon()来删除托盘图标.如果不这样做会留下一个"幽灵"图标,只有当鼠标移到它上面时它才会消失.
并且请注意NotifyIcon并不像您想象的那样微不足道,它有一个非常明显的错误解决方法,您可能会忽略它.当上下文菜单拒绝关闭时,您会注意到.
| 归档时间: |
|
| 查看次数: |
1193 次 |
| 最近记录: |