我正在编写一个 WPF 应用程序,它将在系统托盘中放置一个图标。为了练习,我想做到不依赖于 System.Windows.Forms 并使用其 NotifyIcon 或 NativeWindow 类来完成此操作。
这相当容易 - 从 C# 调用 Shell_NotifyIcon 不难 - 我已经成功完成了我的任务。
作为此努力的一部分,我不得不创建一个窗口句柄,只是为了接收来自系统托盘的消息。我按照以下方式创建本地窗口:
消息循环在
我的问题是:
这些对于一个不可见的窗口来说有用吗?我认为不需要。
这相当容易 - 从 C# 调用 Shell_NotifyIcon 不难 - 我已经成功完成了我的任务。
作为此努力的一部分,我不得不创建一个窗口句柄,只是为了接收来自系统托盘的消息。我按照以下方式创建本地窗口:
// Create a 'Native' window
_hwndSource = new HwndSource(0, 0, 0, 0, 0, 0, 0, null, parentHandle);
_hwndSource.AddHook(WndProc);
消息循环在
AddHook()
中被挂钩,消息会在一个类似于下面这样的函数中被处理:private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
// Handle windows messages in this...
}
最后,当需要销毁该对象时,我通过发送WM_CLOSE
消息并处理HwndSource
来关闭窗口。
if (null != _hwndSource)
{
UnsafeNativeMethods.PostMessage(_hwndSource.Handle, WindowMessage.WM_CLOSE, 0, 0);
_hwndSource.Dispose();
_hwndSource = null;
}
我的问题是:
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
这些对于一个不可见的窗口来说有用吗?我认为不需要。
new IntPtr(-3)
代替parentHandle。 - Hans Passant