在C#中如何监控其它应用全屏

news2024/9/23 13:19:07

原文链接:https://www.cnblogs.com/zhaotianff/p/18338275

在C#中判断其它应用全屏可以有多种方案。我这里提供两种思路

使用定时器

在定时器中定时判断当前窗口的状态是否是最大化或者宽高是否等于桌面窗口的宽高。

这种方法我没有去尝试,凭个人经验,感觉定时器会消耗一定的系统资源。

但我还是列一下大概的思路

  1. 创建定时器
  2. 在定时器中调用GetDesktopWindow Api函数获取桌面窗口句柄
  3. 在定时器中调用GetForegroundWindow Api函数获取当前前台窗口句柄
  4. 在定时器调用GetWindowRect函数获取以前两个窗口的大小,然后进行比较

步骤4也可以使用GetWindowPlacement函数,然后判断窗口的状态是否是最大化。

使用事件钩子函数SetWinEventHook

SetWinEventHook函数可以对各种事件进行Hook,详细的事件可以参考下表

常量/值说明

EVENT_AIA_START/EVENT_AIA_END

0xA000-0xAFFF

辅助功能互操作性联盟 (AIA) 指定的 WinEvent 常量值的范围,供整个行业使用。 有关详细信息,请参阅 WinEvent ID 的分配。

EVENT_MIN/EVENT_MAX

0x00000001-0x7FFFFFFF

可能的最低和最高事件值。

EVENT_OBJECT_ACCELERATORCHANGE

0x8012

对象的 KeyboardShortcut 属性 已更改。 服务器应用程序为它们的辅助性对象发送该事件。

EVENT_OBJECT_CLOAKED

0x8017

在隐藏窗口时发送。 隐藏的窗口仍然存在,但对用户不可见。

EVENT_OBJECT_CONTENTSCROLLED

0x8015

窗口对象的滚动已结束。 与 EVENT_SYSTEM_SCROLLEND不同,此事件与滚动窗口相关联。 无论滚动是水平滚动还是垂直滚动,只要滚动操作完成,都应发送此事件。
WinEventProc 回调函数的 hwnd 参数描述滚动窗口;idObject 参数OBJID_CLIENT,idChild 参数CHILDID_SELF。

EVENT_OBJECT_CREATE

0x8000

已创建 对象。 系统为以下用户界面元素发送此事件:插入点、 标题控件、 列表视图控件、 选项卡控件、 工具栏控件、 树视图控件和 窗口 对象。 服务器应用程序为它们的辅助性对象发送该事件。
在为父对象发送事件之前,服务器必须为对象的所有子对象发送事件。 服务器必须确保在父对象发送此事件之前,已完全创建所有子对象并准备好接受来自客户端的 IAccessible 调用。
由于父对象在其子对象之后创建,因此客户端必须确保在调用 IAccessible::get_accParent之前已创建对象的父对象,尤其是在使用上下文中挂钩函数的情况下。

EVENT_OBJECT_DEFACTIONCHANGE

0x8011

对象的 DefaultAction 属性 已更改。 操作系统为对话框发送该事件。 服务器应用程序为它们的辅助性对象发送该事件。

EVENT_OBJECT_DESCRIPTIONCHANGE

0x800D

对象的 Description 属性 已更改。 服务器应用程序为它们的辅助性对象发送该事件。

EVENT_OBJECT_DESTROY

0x8001

对象已被销毁。 系统为以下用户界面元素发送此事件:插入点、标题控件、列表视图控件、选项卡控件、工具栏控件、树视图控件和窗口对象。 服务器应用程序为它们的辅助性对象发送该事件。
客户端假定当父对象发送此事件时,对象的所有子级都会被销毁。
收到此事件后,客户端不会调用对象的 IAccessible 属性或方法。 但是,只要由于 COM 规则) ,接口指针 (存在引用计数,接口指针必须保持有效,但 UI 元素可能不再存在。 对接口指针的进一步调用可能会返回失败错误;为了防止这种情况,服务器 会创建代理对象 并监视其生命周期。

EVENT_OBJECT_DRAGSTART

0x8021

用户开始拖动元素。 WinEventProc 回调函数的 hwndidObject 和 idChild 参数标识要拖动的对象。

EVENT_OBJECT_DRAGCANCEL

0x8022

用户已结束拖动操作,然后再将拖动的元素放在放置目标上。 WinEventProc 回调函数的 hwndidObject 和 idChild 参数标识要拖动的对象。

EVENT_OBJECT_DRAGCOMPLETE

0x8023

用户删除了放置目标上的元素。 WinEventProc 回调函数的 hwndidObject 和 idChild 参数标识要拖动的对象。

EVENT_OBJECT_DRAGENTER

0x8024

用户将元素拖动到放置目标的边界。 WinEventProc 回调函数的 hwndidObject 和 idChild 参数标识放置目标。

EVENT_OBJECT_DRAGLEAVE

0x8025

用户将元素拖出放置目标的边界。 WinEventProc 回调函数的 hwndidObject 和 idChild 参数标识放置目标。

EVENT_OBJECT_DRAGDROPPED

0x8026

用户删除了放置目标上的元素。 WinEventProc 回调函数的 hwndidObject 和 idChild 参数标识放置目标。

EVENT_OBJECT_END

0x80FF

最高的对象事件值。

EVENT_OBJECT_FOCUS

0x8005

对象已接收键盘焦点。 系统为以下用户界面元素发送此事件:列表视图控件、菜单栏、弹出菜单、切换窗口、选项卡控件、树视图控件和窗口对象。 服务器应用程序为它们的辅助性对象发送该事件。
WinEventProc 回调函数的 hwnd 参数标识接收键盘焦点的窗口。

EVENT_OBJECT_HELPCHANGE

0x8010

对象的 帮助属性 已更改。 服务器应用程序为它们的辅助性对象发送该事件。

EVENT_OBJECT_HIDE

0x8003

对象已隐藏。 系统为以下用户界面元素发送此事件:插入点和光标。 服务器应用程序为它们的辅助性对象发送该事件。
为父对象生成此事件时,所有子对象都已隐藏。 服务器应用程序不会为子对象发送此事件。
隐藏的对象包括 STATE_SYSTEM_INVISIBLE 标志;shown 对象不包括此标志。 EVENT_OBJECT_HIDE 事件还指示已设置STATE_SYSTEM_INVISIBLE标志。 因此,在这种情况下,服务器不会发送 EVENT_OBJECT_STATECHANGE 事件。

EVENT_OBJECT_HOSTEDOBJECTSINVALIDATED

0x8020

承载其他可访问对象的窗口已更改托管对象。 客户端可能需要查询主机窗口以发现新的托管对象,尤其是在客户端一直在监视窗口中的事件时。 托管对象是与主机不同的辅助功能框架 (MSAA 或 UI 自动化) 的对象。 托管对象中与主机相同的框架中的更改应随结构更改事件一起处理,例如 MSAA 的EVENT_OBJECT_CREATE 。 有关详细信息,请参阅 winuser.h 中的注释。

EVENT_OBJECT_IME_HIDE

0x8028

IME 窗口已隐藏。

EVENT_OBJECT_IME_SHOW

0x8027

IME 窗口已变为可见。

EVENT_OBJECT_IME_CHANGE

0x8029

输入法窗口的大小或位置已更改。

EVENT_OBJECT_INVOKED

0x8013

已调用 对象;例如,用户单击了一个按钮。 此事件受常见控件支持,由 UI 自动化使用。
对于此事件,WinEventProc 回调函数的 hwndID 和 idChild 参数标识所调用的项。

EVENT_OBJECT_LIVEREGIONCHANGED

0x8019

属于活动区域的对象已更改。 实时区域是应用程序频繁更改和/或异步更改的区域。

EVENT_OBJECT_LOCATIONCHANGE

0x800B

对象已更改位置、形状和大小。 系统为以下用户界面元素发送此事件:插入点和窗口对象。 服务器应用程序为它们的辅助性对象发送该事件。
生成此事件以响应对象层次结构中顶级对象的更改;它不是为对象可能具有的任何子项生成的。 例如,如果用户调整窗口大小,系统会为窗口发送此通知,但不会针对菜单栏、标题栏、滚动条或其他也已更改的对象发送此通知。
当父窗口移动时,系统不会为所有非浮动子窗口发送该事件。 但是,如果应用程序由于调整父窗口的大小而显式调整子窗口的大小,系统将为重设大小的子窗口发送多个事件。
如果对象的 State 属性 设置为 STATE_SYSTEM_FLOATING,则每当对象更改位置时,服务器就会发送 EVENT_OBJECT_LOCATIONCHANGE 。 如果对象不具有此状态,则服务器仅在对象相对于其父级移动时才触发此事件。 对于此事件通知,WinEventProc 回调函数的 idChild 参数标识已更改的子对象。

EVENT_OBJECT_NAMECHANGE

0x800C

对象的 Name 属性 已更改。 系统为以下用户界面元素发送此事件:检查框、光标、列表视图控件、推送按钮、单选按钮、状态栏控件、树视图控件和窗口对象。 服务器应用程序为它们的辅助性对象发送该事件。

EVENT_OBJECT_PARENTCHANGE

0x800F

对象具有新的父对象。 服务器应用程序为它们的辅助性对象发送该事件。

EVENT_OBJECT_REORDER

0x8004

容器对象已添加、移除其子对象或对其子对象重新排序。 系统为以下用户界面元素发送此事件:标头控件、列表视图控件、工具栏控件和窗口对象。 服务器应用程序在适当的时候为它们的辅助性对象发送该事件。
例如,当子元素的数量或元素的顺序发生更改时,列表视图对象会生成此事件。 当子窗口的 Z 顺序更改时,父窗口也会发送此事件。

EVENT_OBJECT_SELECTION

0x8006

容器对象中的选定内容已更改。 系统为以下用户界面元素发送此事件:列表视图控件、选项卡控件、树视图控件和窗口对象。 服务器应用程序为它们的辅助性对象发送该事件。
此事件指示单个选择:在以前不包含任何选定子项的容器中选择了子级,或者所选内容已从一个子级更改为另一个子级。
WinEventProc 回调函数的 hwnd 和 idObject 参数描述容器;idChild 参数标识所选的对象。 如果所选子级是同时包含 对象的窗口,则 idChild 参数 OBJID_WINDOW。

EVENT_OBJECT_SELECTIONADD

0x8007

容器对象中的子项已添加到现有选定内容中。 系统为以下用户界面元素发送此事件:列表框、列表视图控件和树视图控件。 服务器应用程序为它们的辅助性对象发送该事件。
WinEventProc 回调函数的 hwnd 和 idObject 参数描述容器。 idChild 参数是添加到所选内容的子级。

EVENT_OBJECT_SELECTIONREMOVE

0x8008

容器对象中的项已从所选内容中删除。 系统为以下用户界面元素发送此事件:列表框、列表视图控件和树视图控件。 服务器应用程序为它们的辅助性对象发送该事件。
此事件指示子项已从现有选定内容中删除。
WinEventProc 回调函数的 hwnd 和 idObject 参数描述容器;idChild 参数标识已从所选内容中删除的子级。

EVENT_OBJECT_SELECTIONWITHIN

0x8009

容器对象中发生了许多选择更改。 系统为列表框发送此事件;服务器应用程序为其可访问的对象发送它。
当控件中的选定项发生重大更改时,将发送此事件。 该事件通知客户端发生了许多选择更改,并且发送该事件而不是多个 EVENT_OBJECT_SELECTIONADD 或 EVENT_OBJECT_SELECTIONREMOVE 事件。 客户端通过调用容器对象的 IAccessible::get_accSelection 方法并枚举所选项来查询所选项。
对于此事件通知,WinEventProc 回调函数的 hwnd 和 idObject 参数描述发生更改的容器。

EVENT_OBJECT_SHOW

0x8002

显示隐藏的对象。 系统为下列用户界面元素发送此事件:插入符号、光标和窗口对象。 服务器应用程序为它们的辅助性对象发送该事件。
客户端假定当父对象发送此事件时,已显示所有子对象。 因此,服务器应用程序不会为子对象发送此事件。
隐藏的对象包括 STATE_SYSTEM_INVISIBLE 标志;shown 对象不包括此标志。 EVENT_OBJECT_SHOW 事件还指示已清除STATE_SYSTEM_INVISIBLE标志。 因此,在这种情况下,服务器不会发送 EVENT_OBJECT_STATECHANGE 事件。

EVENT_OBJECT_STATECHANGE

0x800A

对象的状态已更改。 系统为以下用户界面元素发送此事件:检查框、组合框、标题控件、推送按钮、单选按钮、滚动条、工具栏控件、树视图控件、向上-向下控件和窗口对象。 服务器应用程序为它们的辅助性对象发送该事件。
例如,单击或释放按钮对象时,或者启用或禁用某个对象时,会发生状态更改。
对于此事件通知,WinEventProc 回调函数的 idChild 参数标识其状态已更改的子对象。

EVENT_OBJECT_TEXTEDIT_CONVERSIONTARGETCHANGED

0x8030

IME 组合中的转换目标已更改。 转换目标是 IME 组合的子集,主动选择作为用户发起的转换的目标。

EVENT_OBJECT_TEXTSELECTIONCHANGED

0x8014

对象的文本选择已更改。 此事件受常见控件支持,由 UI 自动化使用。
WinEventProc 回调函数的 hwndID 和 idChild 参数描述更新的文本选择中包含的项。

EVENT_OBJECT_UNCLOAKED

0x8018

在取消隐藏窗口时发送。 隐藏的窗口仍然存在,但对用户不可见。

EVENT_OBJECT_VALUECHANGE

0x800E

对象的 Value 属性 已更改。 系统为包括滚动条和以下控件的用户界面元素发送此事件:编辑、标头、热键、进度栏、滑块和向上。 服务器应用程序为它们的辅助性对象发送该事件。

EVENT_OEM_DEFINED_START/EVENT_OEM_DEFINED_END

0x0101-0x01FF

为 OEM 保留的事件常量值的范围。 有关详细信息,请参阅 WinEvent ID 的分配。

EVENT_SYSTEM_ALERT

0x0002

已生成警报。 服务器应用程序不应发送此事件。

EVENT_SYSTEM_ARRANGMENTPREVIEW

0x8016

正在显示预览矩形。

EVENT_SYSTEM_CAPTUREEND

0x0009

窗口已丢失鼠标捕获。 此事件由系统发送,从不由服务器发送。

EVENT_SYSTEM_CAPTURESTART

0x0008

窗口已收到鼠标捕获。 此事件由系统发送,从不由服务器发送。

EVENT_SYSTEM_CONTEXTHELPEND

0x000D

窗口已退出上下文相关帮助模式。 系统不一致地发送此事件。

EVENT_SYSTEM_CONTEXTHELPSTART

0x000C

窗口已进入上下文相关帮助模式。 系统不一致地发送此事件。

EVENT_SYSTEM_DESKTOPSWITCH

0x0020

已切换活动桌面。

EVENT_SYSTEM_DIALOGEND

0x0011

对话框已关闭。 系统为标准对话框发送此事件;服务器将其发送到自定义对话框。 系统不一致地发送此事件。

EVENT_SYSTEM_DIALOGSTART

0x0010

已显示一个对话框。 系统为使用资源模板或 Win32 对话框函数创建的标准对话框发送此事件。 服务器为自定义对话框发送此事件,这些对话框是充当对话框但不是以标准方式创建的窗口。
系统不一致地发送此事件。

EVENT_SYSTEM_DRAGDROPEND

0x000F

应用程序将退出拖放模式。 支持拖放操作的应用程序必须发送此事件;系统不发送此事件。

EVENT_SYSTEM_DRAGDROPSTART

0x000E

应用程序将进入拖放模式。 支持拖放操作的应用程序必须发送此事件,因为系统不会发送它。

EVENT_SYSTEM_END

0x00FF

最高的系统事件值。

EVENT_SYSTEM_FOREGROUND

0x0003

前景窗口已更改。 即使前台窗口已更改为同一线程中的另一个窗口,系统也会发送此事件。 服务器应用程序从不发送该事件。
对于此事件, WinEventProc 回调函数的 hwnd 参数是前台窗口的句柄, idObject 参数 OBJID_WINDOW, idChild 参数 CHILDID_SELF。

EVENT_SYSTEM_MENUPOPUPEND

0x0007

弹出菜单已关闭。 系统为标准菜单发送此事件;服务器将其发送到自定义菜单。
当弹出菜单关闭时,客户端将收到此消息,然后 接收EVENT_SYSTEM_MENUEND 事件。
系统不一致地发送此事件。

EVENT_SYSTEM_MENUPOPUPSTART

0x0006

已显示弹出菜单。 系统为标准菜单发送此事件,这些菜单由 HMENU 标识,并使用菜单模板资源或 Win32 菜单函数创建。 服务器为自定义菜单发送此事件,这些菜单是充当菜单但不以标准方式创建的用户界面元素。 系统不一致地发送此事件。

EVENT_SYSTEM_MENUEND

0x0005

菜单栏中的菜单已关闭。 系统为标准菜单发送此事件;服务器将其发送到自定义菜单。
对于此事件, WinEventProc 回调函数的 hwnd、 idObject 和 idChild 参数引用包含菜单栏的控件或激活上下文菜单的控件。 hwnd 参数是与事件相关的窗口的句柄。 idObject参数OBJID_MENU或OBJID_SYSMENU菜单,或弹出菜单的OBJID_WINDOW。 idChild参数CHILDID_SELF。

EVENT_SYSTEM_MENUSTART

0x0004

已选择菜单栏上的菜单项。 系统为标准菜单发送此事件,这些菜单由 HMENU 标识,使用菜单模板资源或 Win32 菜单 API 元素创建。 服务器为自定义菜单发送此事件,自定义菜单是充当菜单但不以标准方式创建的用户界面元素。
对于此事件, WinEventProc 回调函数的 hwnd、 idObject 和 idChild 参数引用包含菜单栏的控件或激活上下文菜单的控件。 hwnd 参数是与事件相关的窗口的句柄。 idObject 参数是菜单的OBJID_MENU或OBJID_SYSMENU,或弹出菜单的OBJID_WINDOW。 idChild参数CHILDID_SELF。
系统触发多个 EVENT_SYSTEM_MENUSTART 事件,这些事件并不总是与 EVENT_SYSTEM_MENUEND 事件相对应。

EVENT_SYSTEM_MINIMIZEEND

0x0017

即将还原窗口对象。 此事件由系统发送,从不由服务器发送。

EVENT_SYSTEM_MINIMIZESTART

0x0016

窗口对象即将最小化。 此事件由系统发送,从不由服务器发送。

EVENT_SYSTEM_MOVESIZEEND

0x000B

窗口的移动或调整大小已完成。 此事件由系统发送,从不由服务器发送。

EVENT_SYSTEM_MOVESIZESTART

0x000A

正在移动窗口或调整窗口的大小。 此事件由系统发送,从不由服务器发送。

EVENT_SYSTEM_SCROLLINGEND

0x0013

滚动条上的滚动已经结束。 此事件由系统为标准滚动条控件和附加到窗口的滚动条发送。 服务器为自定义滚动条发送此事件,这些滚动条是充当滚动条但不是以标准方式创建的用户界面元素。
发送到 WinEventProc 回调函数的 idObject参数OBJID_HSCROLL水平滚动条,垂直滚动条OBJID_VSCROLL。

EVENT_SYSTEM_SCROLLINGSTART

0x0012

滚动条上的滚动已经开始。 系统为标准滚动条控件和附加到窗口的滚动条发送此事件。 服务器为自定义滚动条发送此事件,这些滚动条是充当滚动条但不是以标准方式创建的用户界面元素。
发送到 WinEventProc 回调函数的 idObject 参数对于水平滚动条OBJID_HSCROLL,垂直滚动条OBJID_VSCROLL。

EVENT_SYSTEM_SOUND

0x0001

已播放声音。 当系统声音(例如菜单声音)被播放时,系统发送此事件,即使没有声音 (,例如,由于缺少声音文件或声音卡) 。 每当自定义 UI 元素生成声音时,服务器都会发送此事件。
对于此事件, WinEventProc 回调函数接收 OBJID_SOUND 值作为 idObject 参数。

EVENT_SYSTEM_SWITCHEND

0x0015

用户已释放 Alt+TAB。 此事件由系统发送,从不由服务器发送。 WinEventProc 回调函数的 hwnd 参数标识用户已切换到的窗口。
如果用户按下 Alt+TAB 时只有一个应用程序正在运行,则系统会发送此事件,而不发送相应的 EVENT_SYSTEM_SWITCHSTART 事件。

EVENT_SYSTEM_SWITCHSTART

0x0014

用户已按 Alt+TAB,这会激活切换窗口。 此事件由系统发送,从不由服务器发送。 WinEventProc 回调函数的 hwnd 参数标识用户要切换到的窗口。
如果用户按 Alt+TAB 时只有一个应用程序正在运行,则系统会发送 EVENT_SYSTEM_SWITCHEND 事件,而不发送相应的 EVENT_SYSTEM_SWITCHSTART 事件。

EVENT_UIA_EVENTID_START /EVENT_UIA_EVENTID_END

0x4E00-0x4EFF

为 UI 自动化事件标识符保留的事件常量值的范围。 有关详细信息,请参阅 WinEvent ID 的分配。

EVENT_UIA_PROPID_START/EVENT_UIA_PROPID_END

0x7500-0x75FF

为 UI 自动化属性更改事件标识符保留的事件常量值的范围。 有关详细信息,请参阅 WinEvent ID 的分配。

这里我们Hook EVENT_OBJECT_LOCATIONCHANGE事件就可以,它可以在对象已更改位置、形状和大小时通知。

简单介绍一下SetWinEventHook函数,它的声明如下:

1 HWINEVENTHOOK SetWinEventHook(
2   [in] DWORD        eventMin,
3   [in] DWORD        eventMax,
4   [in] HMODULE      hmodWinEventProc,
5   [in] WINEVENTPROC pfnWinEventProc,
6   [in] DWORD        idProcess,
7   [in] DWORD        idThread,
8   [in] DWORD        dwFlags
9 );

各参数说明如下:

eventMin:事件常量的最小值,取值来源可以看前面的表。可以使用EVENT_MIN 常量来代表可用的最小值,因为我们我们这里只需要Hook一种事件,所以直接传EVENT_OBJECT_LOCATIONCHANGE就可以
eventMax:事件常量的最大值
hmodWinEventProc:包含钩子函数的模块,如果是来自DLL,需要指定,如果是来自当前模块,指定为NULL
pfnWinEventProc:事件钩子函数
idProcess:进程ID,指定0时代表所有进程
idThread:线程ID,指定0时代表所有线程
dwFlags:标记值,取值如下
含义

WINEVENT_INCONTEXT

包含回调函数的 DLL 映射到生成事件的进程的地址空间中。 使用此标志,系统会在事件通知发生时向回调函数发送事件通知。 指定此标志时,挂钩函数必须位于 DLL 中。 当调用进程和生成进程都不是 32 位或 64 位进程,或者生成进程是控制台应用程序时,此标志不起作用。 有关详细信息,请参阅 上下文中挂钩函数。

WINEVENT_OUTOFCONTEXT

回调函数不会映射到生成事件的进程的地址空间中。 由于挂钩函数是跨进程边界调用的,因此系统必须对事件进行排队。 虽然此方法是异步的,但事件保证按顺序排列。 有关详细信息,请参阅 上下文外挂钩函数。

WINEVENT_SKIPOWNPROCESS

防止挂钩的此实例接收此进程中线程生成的事件。 此标志不会阻止线程生成事件。

WINEVENT_SKIPOWNTHREAD

防止此挂钩实例接收注册此挂钩的线程生成的事件。
 

在C#中使用步骤如下

1、导入WinAPI函数

 1  public class User32
 2  {
 3      public static readonly uint SPI_SETDESKWALLPAPER = 0x0014;
 4      public static readonly uint SPIF_UPDATEINIFILE = 0x0001;
 5 
 6      public static readonly uint EVENT_OBJECT_LOCATIONCHANGE = 0x800B;
 7      public static readonly uint WINEVENT_OUTOFCONTEXT = 0x0000; // Events are ASYNC
 8      public static readonly uint WINEVENT_SKIPOWNPROCESS = 0x0002; // Don't call back for events on installer's process
 9 
10      public static readonly uint SW_SHOWMAXIMIZED = 3;
11 
12      public delegate void Wineventproc(IntPtr hWinEventHook, uint eventId, IntPtr hwnd, int idObject, int idChild, uint idEventThread, uint dwmsEventTime);
13 
14 
15      [DllImport("User32.dll", CharSet = CharSet.Auto)]
16      public static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, Wineventproc pfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
17 
18      [DllImport("User32.dll")]
19      public static extern bool UnhookWinEvent(IntPtr hWinEventHook);
20 
21      [DllImport("User32.dll")]
22      public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
23 
24      [DllImport("User32.dll")]
25      public static extern IntPtr GetForegroundWindow();
26 
27      [DllImport("User32.dll")]
28      public static extern IntPtr GetDesktopWindow();
29 
30      [DllImport("User32.dll")]
31      public static extern bool GetWindowRect(IntPtr hWnd, ref System.Drawing.Rectangle lpRect);
32  }
33 
34  public struct WINDOWPLACEMENT
35  {
36      public uint length;
37      public uint flags;
38      public uint showCmd;
39      public System.Drawing.Point ptMinPosition;
40      public System.Drawing.Point ptMaxPosition;
41      public System.Drawing.Rectangle rcNormalPosition;
42      public System.Drawing.Rectangle rcDevice;
43  };

2、定义事件钩子函数

就是在这个函数里判断其它应用是否切换到全屏状态

 1  private void EventProc(IntPtr hWinEventHook, uint eventId, IntPtr hwnd, int idObject, int idChild, uint idEventThread, uint dwmsEventTime)
 2  {
 3      if (hwnd == IntPtr.Zero)
 4          return;
 5 
 6      //判断是否是前台应用
 7      //如果不需要判断是否是前台应用,这个判断可以移除
 8      if (User32.GetForegroundWindow() != hwnd)
 9          return;
10 
11      if (User32.EVENT_OBJECT_LOCATIONCHANGE == eventId)
12      {
13          WINDOWPLACEMENT wp = new WINDOWPLACEMENT();
14          wp.length = (uint)Marshal.SizeOf(wp);
15          if (User32.GetWindowPlacement(hwnd, ref wp))  //Not very accurate
16          {
17              if (User32.SW_SHOWMAXIMIZED == wp.showCmd)
18              {
19                  //应用全屏了
20              }
21              else
22              {
23                  //应用退出全屏了
24              }
25          }
26 
27      }
28  }

3、创建事件钩子

1   private IntPtr g_eventhook;
2   private User32.Wineventproc Wineventproc;

1 Wineventproc = new Wineventproc(EventProc);
2          
3 g_eventhook = User32.SetWinEventHook(User32.EVENT_OBJECT_LOCATIONCHANGE,
4     User32.EVENT_OBJECT_LOCATIONCHANGE,
5     IntPtr.Zero,
6     Wineventproc, 0, 0,
7     User32.WINEVENT_OUTOFCONTEXT | User32.WINEVENT_SKIPOWNPROCESS);

钩子创建成功后,就可以在钩子函数中进行处理相关逻辑了

4、释放事件钩子

在程序退出时,需要调用UnhookWinEvent函数释放钩子。

1 User32.UnhookWinEvent(g_eventhook);

   

5、运行效果

示例代码下载

示例代码

参考资料

https://stackoverflow.com/questions/17436795/setwineventhook-window-maximized-event/34549801#34549801

https://learn.microsoft.com/en-us/windows/win32/winauto/event-constants

https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-unhookwinevent

https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwineventhook

https://stackoverflow.com/questions/7009080/detecting-full-screen-mode-in-windows

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2071458.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

复杂的编辑表格

需求描述 表格可以整体编辑;也可以单行弹框编辑;且整体编辑的时候,依然可以单行编辑 编辑只能给某一列(这里是参数运行值)修改,且根据数据内容的参数范围来判断展示不同的形式:input/数字输入/单…

小波卷积:为计算机视觉任务开辟新的参数效率之路

论文复述 这篇论文介绍了一种创新的卷积神经网络层——WTConv,它通过小波变换技术显著扩展了CNN的感受野,同时保持了参数效率。WTConv层能够实现对输入数据的多频率响应,增强了模型对形状而非纹理的特征识别能力,提高了在图像分类…

黑神话悟空不只是玩游戏 有人用它3天赚了85W

这几天你是不是在想办法升级电脑配置,买PS5玩黑神话悟空游戏,每一个男人看到那么好的游戏画面,都控制不住想玩,今天分享给大家一些资料,让你快速玩游戏的同时,还能挣点外快,黑神话悟空不只是玩游…

MATLAB 计算两点沿某个方向的间距(81)

MATLAB 计算两点沿某个方向的间距(81) 一、算法介绍二、算法实现1.代码2.效果一、算法介绍 上一章介绍了如何计算点到空间直线的距离,这里进一步的,我们也可以计算两个点,沿着某个方向的距离,这在很多处理中都会使用到,实际上就是将两点投影到该方向的直线,再计算间距…

线性表复习之初始化顺序表操作

线性表的顺序表示-初始化顺序表 代码 #include <stdio.h> #define MaxSize 10 // 定义最大长度typedef struct{int data[MaxSize]; // 申请空间&#xff08;静态&#xff09;int length; // 当前长度 }SqList;void InitList(SqList &L){for (int i 0; i < MaxS…

java-队列--黑马

队列 别看这个&#xff0c;没用&#xff0c;还是多刷力扣队列题 定义 队列是以顺序的方式维护一组数据的集合&#xff0c;在一端添加数据&#xff0c;从另一端移除数据。一般来讲&#xff0c;添加的一端称之尾&#xff0c;而移除一端称为头 。 队列接口定义 // 队列的接口定…

河南萌新联赛2024第(六)场:郑州大学

目录 A-装备二选一&#xff08;一&#xff09;_河南萌新联赛2024第&#xff08;六&#xff09;场&#xff1a;郑州大学 (nowcoder.com) 思路&#xff1a; 代码&#xff1a; B-百变吗喽_河南萌新联赛2024第&#xff08;六&#xff09;场&#xff1a;郑州大学 (nowcoder.com) …

3DsMax将两个模型的UV展到一个UV上面

3DsMax将两个模型的UV展到一个UV上面 3Dmax中的准备工作 创建一个方块&#xff0c;一个球体&#xff0c;模拟两个模型 添加修改器 打开UV编辑器&#xff0c;快速剥 使用缩放工具&#xff0c;缩放UV&#xff0c;放到一个位置 选择正方形&#xff1a;添加修改器&#xff0…

8.3 数据库基础技术-关系代数

并、交、差 笛卡尔积、投影、选择 自然连接 真题

宝塔面板配置node/npm/yarn/pm2....相关全局变量 npm/node/XXX: command not found

1.打开终端 , cd 到根目录 cd / 2.跳转至node目录下,我的node版本是v16.14.2 cd /www/server/nodejs/v16.14.2/bin 2.1 如果不知道自己node版本多少就跳转到 cd /www/server/nodejs 然后查找当前目录下的文件 ls 确定自己的node版本 cd /node版本/bin 3.继续查看bin…

天润融通助力呷哺呷哺:AI技术赋能3000万会员精细化运营

呷哺集团于1998年11月在北京成立&#xff0c;以“一人一锅”台式小火锅的用餐模式&#xff0c;以及其推出的多样化套餐与良好的用餐服务赢得了众多消费者的青睐&#xff0c;并迅速在市场上占据了一席之地。经过20多年的发展&#xff0c;呷哺呷哺已成为一个多品牌经营、全产业链…

基于Android的安全知识学习APP的设计与实现(论文+源码)_kaic

基于Android的安全知识学习APP的设计与实现 摘 要 随着科技的进步&#xff0c;智能手机已经成为人们工作、学习和生活的必需品。基于Android系统的强大功能&#xff0c;使用Java语言、Linux操作系统&#xff0c;搭配Android Studio&#xff0c;并配备Android开发插件&#…

Unet改进3:在不同位置添加NAMAttention注意力机制

本文内容:在不同位置添加NAMAttention注意力机制 目录 论文简介 1.步骤一 2.步骤二 3.步骤三 4.步骤四 论文简介 识别不太显著的特征是模型压缩的关键。然而,它在革命性的注意机制中尚未得到研究。在这项工作中,我们提出了一种新的基于归一化的注意力模块(NAM),它抑制…

广州自闭症学校哪家好?

在广州&#xff0c;选择一家适合自闭症儿童的康复学校是一个需要慎重考虑的决定。在众多机构中&#xff0c;星启帆自闭症儿童康复机构以其专业的师资团队、全面的康复服务以及温馨的学习环境脱颖而出&#xff0c;成为众多家长信赖的选择。 星启帆自闭症康复中心&#xff0c;作…

敦煌智旅:Serverless 初探,运维提效 60%

作者&#xff1a; 百潼 行业新趋势 在后疫情时代&#xff0c;文旅行业开始复苏&#xff0c;在行业的发展趋势中&#xff0c;我们看到了一个充满机遇和挑战的未来。通过不断创新和适应市场需求&#xff0c;文旅行业继续不断发展壮大&#xff0c;为消费者提供更加丰富多样的旅游…

UnQLite:多语言支持的嵌入式NoSQL数据库深入解析

文章目录 1. 引言2. Key/Value 存储接口2.1 关键函数2.2 使用示例2.3 高级操作&#xff1a;批量文件存储 3. 游标的使用4. UnQLite-Python使用示例4. UnQLite数据库引擎架构5.1 Key/Value存储层5.2 文档存储层5.3 可插拔的存储引擎5.4 事务管理器与分页模块5.5 虚拟文件系统 6.…

右值引用与左值引用

目录 1. 左值与右值2. 左值引用与右值引用 1. 左值与右值 2. 左值引用与右值引用

千益畅行,旅游卡,案例分享

旅游卡作为新旅游这个赛道&#xff0c;到处都是金矿&#xff0c;看你怎么去挖&#xff0c;商机无限。千益畅行旅游卡作为旅游卡源头&#xff0c;提供优质完善的服务&#xff0c;你只需要去铺卡搞钱&#xff0c;其他的售后交给我们&#xff01; #旅游卡服务#

使用静态IP为什么比动态IP的人多?

在网络世界中&#xff0c;IP地址就好比我们的身份证&#xff0c;用来标识我们在互联网上的唯一身份。而静态IP与动态IP&#xff0c;则是这“身份证”的两种不同分配方式。 一、静态IP与动态IP的区别 动态IP&#xff1a;动态IP地址如同租住的公寓&#xff0c;用户每次上网时&a…

【Qt】常见控件 —— QWidget(下)

文章目录 QWidget 的 windowlcon 属性使用 qrc文件管理资源qrc的使用方式在项目中创建 qrc文件把图片 导入到qrc 文件中 QWidget 的 windowOpacity属性 QWidget 的 windowlcon 属性 windowlcon 表示 一个窗口的图标 ( 只能针对 顶层窗口使用 ) windowlcon() 表示 获取到控件的…