gpt4 book ai didi

c# - 仅用于消息循环的 WPF 窗口句柄

转载 作者:可可西里 更新时间:2023-11-01 14:03:30 42 4
gpt4 key购买 nike

我正在编写一个 WPF 应用程序,它将在系统托盘中放置一个图标,作为练习,我想在不依赖于 System.Windows.Forms 并使用其 的情况下执行此操作NotifyIconNativeWindow 类。

这相当简单 - Shell_NotifyIcon 不难从 C# 调用 - 事实上,我已经成功完成了我的任务。

作为这项工作的一部分,我不得不创建一个窗口句柄,其唯一目的是从系统托盘接收消息。我按如下方式创建 native 窗口:

// Create a 'Native' window
_hwndSource = new HwndSource(0, 0, 0, 0, 0, 0, 0, null, parentHandle);
_hwndSource.AddHook(WndProc);

消息循环在 AddHook() 中 Hook ,消息在如下所示的函数中处理:

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构造函数的前三个参数分别是 native 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

这些对于不可见窗口来说重要吗? (我认为不是。)

最佳答案

Windows 样式标志可以追溯到 1986 年,当时 Windows v1.0 发布。在过去的 29 年和 10 个主要版本中,很多 appcompat hacks,当应用程序指定不可靠的样式标志时,Windows 会默默地覆盖样式标志。然而,这并没有什么特别奇怪的,请注意 WS_OVERLAPPED 样式标志的值为 0。它要求一个普通窗口,您会自动为这样一个窗口获取适当的样式标志。

您的 HwndSource 窗口具有完全相同的样式标志,也许您还没有在 Spy++ 中找到正确的标志。所以你没有问题。不,当窗口永远不可见时,它们并不重要。

请注意代码中的一个错误,您发布的 WM_CLOSE 消息实际上从未被处理过,因为您在调用 PostMessage() 后立即销毁了窗口。删掉就好了,跟窗口好好的问也没用,它不会反对的。但是,您必须使用 NIM_DELETE 调用 Shell_NotifyIcon() 才能删除托盘图标。如果不这样做,会留下一个“幽灵”图标,只有当您将鼠标移到它上面时,该图标才会消失。

请注意 NotifyIcon 并不像您想象的那么简单,它有一个 non-obvious bug workaround你可能会忽视。当上下文菜单拒绝关闭时,您会注意到。

关于c# - 仅用于消息循环的 WPF 窗口句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28364571/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com