How can I create a window the size of the screen without it being treated as a fullscreen window? - The Old New Thinghttps://devblogs.microsoft.com/oldnewthing/20250522-00/?p=111211
問題描述
????????任務欄允許全屏窗口覆蓋它。這樣,當你在放映幻燈片或進行演示時,屏幕底部不會顯示任務欄。自動檢測算法在大多數情況下工作得相當好:如果窗口的客戶區覆蓋了整個屏幕,那么它就被認為是全屏窗口。
????????但你可能會發現,任務欄有時會將你的窗口誤認為是全屏窗口,盡管你并不希望如此;或者當你希望窗口被視為全屏時,任務欄卻未能將其識別為全屏。
????????一種你不想讓屏幕大小的窗口被當作全屏窗口的情況是,如果你的窗口試圖對屏幕應用某種效果,比如顯示一個 50% 透明度的黑色窗口以實現暗化效果,就像“查找我的鼠標”PowerToy 所使用的那樣。而一種你希望強制將屏幕大小的窗口當作全屏窗口的情況是,如果你的窗口有標題欄,因為標題欄是非客戶區,而全屏計算只考慮客戶區。
????????你有兩種方法可以影響這一決策,這兩種方法都在同一頁面上有文檔說明:一種是使用 ITaskbarList2::MarkFullscreenWindow另一種是使用 NonRudeHWND
窗口屬性。
????????這兩種設置在某種程度上是互補的,它們有各自適用的場合。
譯注
MarkFullscreenWindow
和NonRudeHWND
這兩種設置在功能上是相互補充的,但它們的作用方向是相反的:
MarkFullscreenWindow
:
作用:當你調用
MarkFullscreenWindow
并傳遞TRUE
時,明確地告訴任務欄“這個窗口是全屏窗口”。任務欄會根據這個聲明將窗口視為全屏,并相應地隱藏任務欄。這個設置傾向于讓任務欄將窗口識別為全屏窗口。
例子:如果你有一個帶有標題欄的全屏窗口,任務欄可能會因為標題欄的存在而不將其視為全屏窗口。通過調用
MarkFullscreenWindow(TRUE)
,你可以強制任務欄將窗口視為全屏。
NonRudeHWND
:
作用:當你設置
NonRudeHWND
屬性為1
時,你明確地告訴任務欄“這個窗口不是全屏窗口”。任務欄會根據這個聲明將窗口視為非全屏,并相應地顯示任務欄。這個設置傾向于讓任務欄將窗口識別為非全屏窗口。
例子:如果你有一個覆蓋整個屏幕的窗口,但你希望任務欄仍然可見(比如為了顯示某些狀態信息),通過設置
NonRudeHWND
屬性為1
,你可以強制任務欄將窗口視為非全屏。舉個例子
場景1:你有一個全屏窗口,但任務欄沒有將其識別為全屏窗口(可能是因為窗口的某些非客戶區部分導致任務欄誤判)。
解決方案:調用
MarkFullscreenWindow(TRUE)
,明確告訴任務欄這個窗口是全屏的。場景2:你有一個覆蓋整個屏幕的窗口,但你希望任務欄仍然可見(比如為了顯示某些狀態信息)。
解決方案:設置
NonRudeHWND
屬性為1
,明確告訴任務欄這個窗口不是全屏的。
????????如果你向 ITaskbarList2::MarkFullscreenWindow
傳遞 TRUE
,那么你就是在聲明你的窗口是一個全屏窗口。1 如果你傳遞 FALSE
,那么你就是在取消這一聲明。注意,傳遞 FALSE
并不意味著“我聲明這不是一個全屏窗口”。相反,它的意思是“我沒有聲明這是一個全屏窗口”。
????????你可以在顯示窗口之前調用 MarkFullscreenWindow
,也可以在窗口已經顯示的情況下調用它,這種情況下它會立即生效。然而,一旦你隱藏了窗口,你應用的任何設置都會丟失。如果你想讓它在窗口下一次顯示時繼續生效,你需要再次設置它。如果資源管理器崩潰,標記也會丟失,因此要監聽 TaskbarCreated
消息并重新應用你的標記。
????????當窗口顯示時,或者當系統檢測到你的窗口可能是一個全屏窗口時(比如當它改變大小以覆蓋屏幕時),會咨詢 NonRudeHWND
屬性。在決策做出后更改該值,直到系統需要做出新的決策之前都不會有任何效果,比如如果你隱藏你的窗口然后再顯示它。如果 NonRudeHWND
屬性被設置為 1
,那么你就是在聲明你的窗口肯定不是一個全屏窗口。移除該屬性并不會強制你的窗口被當作全屏窗口;相反,它的意思是“繼續你正常的全屏檢測邏輯”。
? ? ? ? 各種情況總結如下:
MarkFullscreenWindow | NonRudeHWND | |
---|---|---|
設置后的效果 | 窗口被視為全屏 | 窗口被視為非全屏 |
最佳調用時機 | 在顯示或調整窗口大小之前 | |
調用頻率 | 每次顯示窗口時 | 一次即可 |
如果在窗口可見時更改 | 生效 | 無事發生 |
如果 TaskbarCreated | 需要再次調用 | 不需要 |
1 窗口仍然必須滿足一些基本標準,比如,你知道的,窗口需要實際上覆蓋了屏幕(窗口的客戶區(client area)必須覆蓋整個屏幕。換句話說,窗口的大小和位置必須使得它看起來像是一個全屏窗口)。你不能創建一個小小的 1×1 窗口并宣稱“我是一個全屏窗口!”
好吧,你非要也可以,反正別人會嘲笑你。🤪