对通知区域(Win 系统托盘)窗口层次的分析

目录

一、前言

二、气球通知(非 Toast 应用通知)

三、通知区域

1)用户通知区域(UserPrompt Notification Area)

2)系统升级的通知区域(System Upgrade Notification Area)

3)任务栏角溢出通知区域(Taskbar Corner Overflow Notification Area)

4)通知中心(Notification Center)

四、MS 对应用通知的设计

4.1 什么是应用通知(Toast 通知)?

4.2 应用通知是如何实现的?


本文出处链接:https://blog.csdn.net/qq_59075481/article/details/128538050

一、前言

Windows 的通知区域也就是我们俗称的 系统托盘,该区域是为了显示应用程序或系统的重要通知以及支持应用程序的最小化操作而诞生的。关于他的历史由来有一些有趣的说法,有兴趣的可以搜索资料了解一下。

在前面的几篇文章中,我详细介绍了在新旧不同版本的 Windows 系统上获取通知区域图标信息的方法。后来,我考虑到:如果缺乏对通知区域界面的基本知识的了解,可能会影响通知区域图标信息的获取方法的理解。所以我就决定将之前整理的一篇介绍通知区域窗口层次的文章展示出来,由于 Windows 对 UI 设计的理念一直在变化,所以这篇文章的分析难免有疏忽之处。这一点还希望大家指点。

P.S. :这篇文章是早在 2022 年就编写的文章,因为当初时间紧,没有写完而一直没有发布。这一点从文章的 AID 其实就可以看出(AID: 128 开头大概是 12 月底的文章序号)。当初是准备先写窗口层次分析,然后再介绍 TB_BUTTON 消息机制的处理方法。当时 Win11 刚出来不久,传统的 TrayBar 的设计还没有被废除。后来,一次偶然间发现之前编写的工具在 Win11 上失效了,于是就有了前面几篇的研究文章。

 系列文章列表:

编号文章标题AID
1

获取系统托盘图标信息的尝试

128594435
2获取 Windows 系统托盘图标信息的最新方案(一)136134195
3获取 Windows 系统托盘图标信息的最新方案(二)136199670
4获取 Windows 系统托盘图标信息的最新方案(三)136240462
5对通知区域(Win 系统托盘)窗口层次的分析128538050

二、气球通知(非 Toast 应用通知)

通知通过简要显示通知区域中图标中的气球(见图示[1]、[2]、[3]、[4]),来通知用户与当前用户活动无关的事件。通知可能是用户操作或重大系统事件导致的,或者可能提供来自 Microsoft Windows 或应用程序的有用信息。

通知中的信息 非常有用且相关,但从不至关重要。 因此,通知不需要即时用户操作,用户可以自由忽略它们。

传统通知主要通过桌面右下角弹出气球窗口的方式提示用户一些有用的信息,下图展示了从 WinXP 到 Win11 系统的部分气球通知消息。

图[1] - WinXP中的气球通知样式
图[2] - Win 7中的气球通知样式

图[3] - Win 10中的气球通知样式

图[4] - Win 11中的气球通知样式

这种气球通知需要应用程序在通知发送期间暂时显示通知区域图标,或者长期显示通知区域图标。主要实现的方式是:1.通过 SHQueryUserNotificationState 函数确定用户何时处于活动状态;2.通过 Shell_NotifyIcon 函数向通知区域发送通知的设置。

三、通知区域

在刚刚的描述中,我们一直谈到名为“通知区域”的部分,那么什么是通知区域呢?

通知区域是任务栏的一部分,提供通知和状态的临时源,默认位于任务栏的右侧(提示:本文中任务栏位置按照默认的屏幕下方模式,且部分的 Win11 操作系统可能无法调整任务栏位置)。

它还可用于显示桌面上没有状态的系统和程序功能的图标,例如电池电量、音量控制和网络状态。 通知区域以前称为系统托盘或状态区域。

通知区域中的项称为通知区域图标,或者如果已明确建立通知区域的上下文,则只是图标。

意思就是说:如果只是为了通知而临时添加的图标和为了更好的功能而本来就添加到任务栏的托盘图标都属于通知区域图标,但后者更趋向于是不显示在桌面的缩小版图标。

微软为了更好的用户体验,所以一直在更改 UI 的设计。在 XP 上,只有一个用户通知区域(旧称系统托盘),在图标过多的时候可以隐藏部分图标,但并不是重新划分区域收纳这些图标。从 Win 7 开始的系统中,改用分开的通知区域来实现更加清洁的任务栏,并且在以后的设计中,除了圆角设计和新增加的 Toast 通知以外,没有太大的变动,但有些细节并不一致。

下面展示显式通知区域(类名均为:ToolbarWindow32)的组成:

1)用户通知区域(UserPrompt Notification Area)

听名字就可以了解到这个窗口是面向用户的,如图 [5] 所示,红色框圈出的区域为用户提示的通知区域,这个区域在 Win7 至 Win10 是默认显示在任务栏上的,用于显示常用应用的通知栏图标(在 XP 中只有这一个显式通知区域)

图[5]  用户通知区域示意图

在 Win11 中,如果没有在 “设置>任务栏设置>其它系统托盘图标” 中标记显示通知区域图标,则该窗口矩形大小将为 0\times 0,但窗口始终为 Visible(可见)。

图[6]  任务栏图标设置页面

在 Win7 中,需要在任务栏属性菜单>通知区域>自定义>取消始终显示...的可选项,并将每一个图标均设置为不显示图标和通知,才能使得该通知区域隐藏(窗口大小为 0,且 Invisible 不可见)。

图[7]  通知区域图标设置页

可以看出,微软在全新的设计理念中,看似完全颠覆了以前的设置。同样的话官方也不是没讲过,在 Windows 7 设计指南中有这样一个粉标备注:

图[8]

这个区域对应的窗口标题为:用户提示的通知区域(Win10、Win11)\用户升级的通知区域( Win7 ),以下简称(用户通知区)。窗口类的类名为:ToolbarWindow32。属于三级子窗口( SysPager 的子窗口,该部分窗口结构从 WinXP 沿用至今),窗口结构为:

      #32769 (桌面)
        - Shell_TrayWnd
          - TrayNotifyWnd
            - SysPager
                - "用户通知区"ToolbarWindow32

2)系统升级的通知区域(System Upgrade Notification Area)

系统升级的通知区域(以下简称系统通知区)光看名字,对很多人来说一定很陌生,甚至很容易忽略。这个窗口一般是看不到的,因为它的 NormalSize 为 0(注意如果需要检测该窗口矩形,请使用高 DPI 设置,否则将得到意外的结果),一般是看不到的,但是窗口却是 Visible(可见),只是因为大小为 0,而 UI 界面不绘制它的边框(毕竟那样不美观),所以一般看不到。

那我们什么时候能看到呢?

我们需要先了解这个通知区域的基本功能,系统通知区域用于部分应用通知图标的临时显示,如果这个应用没有设置为始终显示(或者没有设置始终显示所有图标和通知,Win7 ),那么,当程序刚刚创建通知图标的时候(一般为程序启动时),系统会在其注册图标后约一分钟内持续将其显示在系统通知区内,然后会将其自动移动到溢出通知区域(后面将会讲到)。

系统通知区的位置一处通知区 Button 的右侧,在用户通知区的左侧,当它里面容纳临时图标的时候,他会并排显示在用户通知区左侧(紧挨着)。如图 [9,10] 所示。

图[9] - 任务管理器没有打开前
图[10] - 任务管理器打开后

比如在任务管理器打开前后任务栏的变化:这边的任务管理器图标没有设置为始终显示,图中 OneDrive 和 QQ 被设置为了始终显示,且当前正在运行中。正常设置了始终显示属性的图标,默认是在用户通知区向右排列,而新打开的任务管理器图标显示在用户通知区的左侧边缘外。

使用 Microsoft Spy ++ 分析窗口堆叠树层结构(分析窗口位置),不难发现,任务管理器当前是显示在新的窗口中,而不是用户通知区窗口。这个窗口应该是标题为“系统升级的通知区域”,类名为 ToolbarWindow32 的窗口,属于二级子窗口(与 SysPager 同级)。微软使用该通知区域来强调一个不经常显示的图标的创建操作,以便于提醒用户新的通知程序被创建,同时对于那些真正因为临时通知而不得不显示图标的应用提供便捷的舞台。当预计的超时时间结束时,无论是否是临时显示的通知图标还是长期使用但不需要显示的图标,都会被移动到溢出通知区域(默认处于折叠状态),除非设置了始终可见通知图标;当它显示临时图标的时侯,系统通知区才会显示出来(矩形大小是按照当前排队的临时图标格式来约定的),否则它的大小为 0。 

图[11]  系统升级的通知区域窗口

【备注】:如果是临时图标,在超时前处理完通知,并且结束线程或者注销图标,之后不会再在溢出通知区域创建新图标。如果临时图标没有在超时前完成通知,或者不准备注销或者隐藏通知图标,那么会被移动到溢出通知区域。溢出通知区域在外壳程序重启前或者新的命令发布前,不会尝试刷新或者自动删除这些图标。

3)任务栏角溢出通知区域(Taskbar Corner Overflow Notification Area)

任务栏角溢出通知区域是在 Win7 就引入的一个通知区域。目的是解决通知区域图标个数过多时,使得任务栏臃肿的问题。系统通过设置的配置,选择将大多数不那么重要的通知图标放入到一个自动折叠起来的通知区域。用户通过任务栏上的一个角标按钮来打开这个通知区域:

图[12]  任务栏角溢出

任务栏角溢出通知区域窗口是一个只有窗口类名称(NotifyIconOverflowWindow)的窗口:

图[13]  NotifyIconOverflowWindow 窗口层次

用户可以通过手动操作鼠标左键,按住并拖动图标在“溢出通知区域”和“用户升级通知区域”间移动位置。或者使用设置的 “个性化>任务栏>其它系统托盘图标” (Win11)以及 “控制面板>通知区域图标” (Win10 或更早)等设置来修改图标可见性。

4)通知中心(Notification Center)

通知中心位于任务栏的右端。它包含你可能经常选择的图标:电池、WLAN、音量、时钟和日历以及通知中心。它还提供有关传入电子邮件、更新和网络连接等内容的状态和通知。您可以更改在任务栏通知区域中显示哪些图标和通知,甚至隐藏某些图标和通知。

Windows 10 的通知中心和 Windows 11 略有不同。下图展示了 Windows 11 的通知中心的样式:

图[14]  Windows 11 通知栏

在现阶段的设计理念中,通知中心一般位于桌面的最右侧。如下图 [15]  所示。

图[15]  Win11 通知中心

 Windows 10 的通知栏和通知中心是合并在一起的:

图[16]  Win10 通知中心

 它位于任务栏右下角,有一个单独的按钮(Win11 则是合并到 “日历和时间” 中):

图[17]  Win10 通知中心按钮

24H2 对窗口层次进行了大改动!!!(目前对该系列研究的系统通知解决方案没有影响)

 任务栏窗口层次以前是完全一体化的。现在部分窗口的消息处理窗口放在了 Shell_TrayWnd 窗口外面,作为 PopUp 窗口。

并且,任务栏通知区域的窗口名称发生了变化,完全删除了 ToolBar TrayWnd 窗口(革故鼎新)。

Win 11 24H2:

对比 Win 11 23H2:

Win 11 24H2 的角溢出通知区域也和之前不同。

以前是这样:

这在我的文章 “Win 11 24H2 桌面窗口层次改动_24h2 渠道-CSDN博客” 中已经介绍过。

四、MS 对应用通知的设计

4.1 什么是应用通知(Toast 通知)?

应用通知 (以前称 Toast 通知) 是具有文本、图像和按钮/输入的灵活通知。这是更适应现代化 UI 设计的通知框架,基于 C/C++ WinRT 和 XML 语言的应用通知框架从设计之初就是面向对象的。自适应和交互式应用通知允许开发者创建带有更多内容的灵活弹出通知、可选的嵌入式图像和可选的用户交互。

我们把应用通知的可视部分称作通知内容的视觉对象,其包括包含文本和图像的泛型绑定。下面是应用通知内容的视觉对象的示意图:

图[18]  应用通知的视觉对象

应用通知还支持可选图像设置(图 [19] 蓝色框)。图像可来自于应用包、应用的本地存储或来自 Web。以及标准的输入框和多个自定义按钮以及按钮功能(图 [19] 红色框、绿色框)。

图[19]  应用通知的其他特性

以上只是应用通知框架的最基本的应用,应用通知还有更多的有关视觉、交互的元素。例如:选项卡、音频、上下文菜单、按钮图标和颜色等即时交互元素。

4.2 应用通知是如何实现的?

所有类型的应用(WPF、UWP、WinForms、控制台 C/C++/C#)都可以发送应用通知。本质上,应用通知的内部细节是通过组件对象模型(COM)来实现的。

根据 MS 的文档实现会很复杂,一般情况下可以使用 Github 上的开源项目来轻松完成任务。

比如 WinToast 这个开源项目就非常好用,它包含 Console 终端模式和 Qt 6 窗口模式。

图[20] Console 版的 WinToast

文章出处链接:https://blog.csdn.net/qq_59075481/article/details/128538050

本文发布于:2024.03.03,更新于:2024.03.04 / 2024.04.06。

  • 47
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

涟幽516

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值