請(qǐng)將所有未處理的消息傳遞給 DefWindowProc
在之前的一篇文章中,我曾提到:如果你希望拒絕一次設(shè)備移除查詢請(qǐng)求,則需要返回一個(gè)特殊的 BROADCAST_QUERY_DENY 值,因?yàn)樘嗟某绦蜷_發(fā)者認(rèn)為,他們已經(jīng)覆蓋了所有 Windows 消息的處理了,對(duì)于其他的消息,直接返回 0 就可以了。
從那時(shí)候開始,操作系統(tǒng)引入了很多新的消息,這些消息中的很大一部分都是在 DefWindowProc 中進(jìn)行了默認(rèn)的處理。
時(shí)不時(shí)的,我會(huì)碰到一些應(yīng)用程序會(huì)這樣假設(shè):微軟應(yīng)該從來不會(huì)優(yōu)化窗口管理器組件吧?對(duì)于那些我不需要處理的消息,我直接返回 0 就可以了,問題不大。
其實(shí),這些應(yīng)用程序甚至都沒有處理所有現(xiàn)有的舊消息!
我們看一個(gè)例子,在一個(gè)應(yīng)用程序中,它有一個(gè)幫助窗口,這個(gè)窗口會(huì)處理一些它感興趣的消息,然后對(duì)于所有其他消息,它直接返回了 0。結(jié)果就是:用戶連關(guān)機(jī)都關(guān)不了,因?yàn)閼?yīng)用程序?qū)ο到y(tǒng)發(fā)出的廣播消息 WM_QUERYENDSESSION 返回了一個(gè) 0,這意味著,應(yīng)用程序?qū)Σ僮飨到y(tǒng)說:”等等,請(qǐng)不要關(guān)機(jī)”。
我猜這個(gè)應(yīng)用程序的開發(fā)者會(huì)意味用戶會(huì)在關(guān)機(jī)前先手動(dòng)關(guān)閉他的應(yīng)用程序吧。
另外,自定義鍵盤按鈕(如音量控制按鈕)也不起作用(如果焦點(diǎn)在此幫助程序窗口上),因?yàn)樗雎粤藢?WM_APPCOMMAND 消息傳遞給 DefWindowProc 函數(shù)。
因此,我再次懇求你:如果你不處理窗口過程中的消息,請(qǐng)將其傳遞給 DefWindowProc 函數(shù)。你的用戶真的會(huì)謝。
另外有個(gè)小細(xì)節(jié)需要注意:如果你使用的是框架窗口,請(qǐng)遵循該框架的協(xié)議來指示你希望進(jìn)行默認(rèn)消息處理。例如,對(duì)話框過程不會(huì)將未經(jīng)處理的消息傳遞給 DefWindowProc 函數(shù)。它們僅返回 FALSE 以指示應(yīng)進(jìn)行默認(rèn)處理。
總結(jié)
我想這里作者的原則很簡(jiǎn)單:對(duì)于你不想處理的消息,不要處理并簡(jiǎn)單返回 0,而是交給系統(tǒng)默認(rèn)處理函數(shù) DefWindowProc。
否則,各種意外會(huì)發(fā)生。