在C#中如何監控其它應用全屏

zhaotianff發表於2024-08-02

在C#中判斷其它應用全屏可以有多種方案。我這裡提供兩種思路

1、使用定時器

在定時器中定時判斷當前視窗的狀態是否是最大化或者寬高是否等於桌面視窗的寬高。

這種方法我沒有去嘗試,憑個人經驗,感覺定時器會消耗一定的系統資源。

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

  1. 建立定時器
  2. 在定時器中呼叫GetDesktopWindow Api函式獲取桌面視窗控制代碼
  3. 在定時器中呼叫GetForegroundWindow Api函式獲取當前前臺視窗控制代碼
  4. 在定時器呼叫GetWindowRect函式獲取以前兩個視窗的大小,然後進行比較

步驟4也可以使用GetWindowPlacement函式,然後判斷視窗的狀態是否是最大化。

2、使用事件鉤子函式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_CLIENTidChild 引數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 回撥函式的 hwndidObjectidChild 引數標識要拖動的物件。
EVENT_OBJECT_DRAGCANCEL
0x8022
使用者已結束拖動操作,然後再將拖動的元素放在放置目標上。 WinEventProc 回撥函式的 hwndidObjectidChild 引數標識要拖動的物件。
EVENT_OBJECT_DRAGCOMPLETE
0x8023
使用者刪除了放置目標上的元素。 WinEventProc 回撥函式的 hwndidObjectidChild 引數標識要拖動的物件。
EVENT_OBJECT_DRAGENTER
0x8024
使用者將元素拖動到放置目標的邊界。 WinEventProc 回撥函式的 hwndidObjectidChild 引數標識放置目標。
EVENT_OBJECT_DRAGLEAVE
0x8025
使用者將元素拖出放置目標的邊界。 WinEventProc 回撥函式的 hwndidObjectidChild 引數標識放置目標。
EVENT_OBJECT_DRAGDROPPED
0x8026
使用者刪除了放置目標上的元素。 WinEventProc 回撥函式的 hwndidObjectidChild 引數標識放置目標。
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 回撥函式的 hwndIDidChild 引數標識所呼叫的項。
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 回撥函式的 hwndidObject 引數描述容器;idChild 引數標識所選的物件。 如果所選子級是同時包含 物件的視窗,則 idChild 引數 OBJID_WINDOW
EVENT_OBJECT_SELECTIONADD
0x8007
容器物件中的子項已新增到現有選定內容中。 系統為以下使用者介面元素髮送此事件:列表框、列表檢視控制元件和樹檢視控制元件。 伺服器應用程式為它們的輔助性物件傳送該事件。
WinEventProc 回撥函式的 hwndidObject 引數描述容器。 idChild 引數是新增到所選內容的子級。
EVENT_OBJECT_SELECTIONREMOVE
0x8008
容器物件中的項已從所選內容中刪除。 系統為以下使用者介面元素髮送此事件:列表框、列表檢視控制元件和樹檢視控制元件。 伺服器應用程式為它們的輔助性物件傳送該事件。
此事件指示子項已從現有選定內容中刪除。
WinEventProc 回撥函式的 hwndidObject 引數描述容器;idChild 引數標識已從所選內容中刪除的子級。
EVENT_OBJECT_SELECTIONWITHIN
0x8009
容器物件中發生了許多選擇更改。 系統為列表框傳送此事件;伺服器應用程式為其可訪問的物件傳送它。
當控制元件中的選定項發生重大更改時,將傳送此事件。 該事件通知客戶端發生了許多選擇更改,並且傳送該事件而不是多個 EVENT_OBJECT_SELECTIONADD 或 EVENT_OBJECT_SELECTIONREMOVE 事件。 客戶端透過呼叫容器物件的 IAccessible::get_accSelection 方法並列舉所選項來查詢所選項。
對於此事件通知,WinEventProc 回撥函式的 hwndidObject 引數描述發生更改的容器。
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 回撥函式的 hwndIDidChild 引數描述更新的文字選擇中包含的項。
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_WINDOWidChild 引數 CHILDID_SELF。
EVENT_SYSTEM_MENUPOPUPEND
0x0007
彈出選單已關閉。 系統為標準選單傳送此事件;伺服器將其傳送到自定義選單。
當彈出選單關閉時,客戶端將收到此訊息,然後 接收EVENT_SYSTEM_MENUEND 事件。
系統不一致地傳送此事件。
EVENT_SYSTEM_MENUPOPUPSTART
0x0006
已顯示彈出選單。 系統為標準選單傳送此事件,這些選單由 HMENU 標識,並使用選單模板資源或 Win32 選單函式建立。 伺服器為自定義選單傳送此事件,這些選單是充當選單但不以標準方式建立的使用者介面元素。 系統不一致地傳送此事件。
EVENT_SYSTEM_MENUEND
0x0005
選單欄中的選單已關閉。 系統為標準選單傳送此事件;伺服器將其傳送到自定義選單。
對於此事件, WinEventProc 回撥函式的 hwndidObjectidChild 引數引用包含選單欄的控制元件或啟用上下文選單的控制元件。 hwnd 引數是與事件相關的視窗的控制代碼。 idObject引數OBJID_MENU或OBJID_SYSMENU選單,或彈出選單的OBJID_WINDOWidChild引數CHILDID_SELF。
EVENT_SYSTEM_MENUSTART
0x0004
已選擇選單欄上的選單項。 系統為標準選單傳送此事件,這些選單由 HMENU 標識,使用選單模板資源或 Win32 選單 API 元素建立。 伺服器為自定義選單傳送此事件,自定義選單是充當選單但不以標準方式建立的使用者介面元素。
對於此事件, WinEventProc 回撥函式的 hwndidObjectidChild 引數引用包含選單欄的控制元件或啟用上下文選單的控制元件。 hwnd 引數是與事件相關的視窗的控制代碼。 idObject 引數是選單的OBJID_MENUOBJID_SYSMENU,或彈出選單的OBJID_WINDOWidChild引數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
防止此掛鉤例項接收註冊此掛鉤的執行緒生成的事件。
 


 
 
 

參考資料:

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

相關文章