關於訊息和消息佇列
不同於 MS-DOS 型應用程式,Windows 應用程式是事件驅動應用程式。 它們不會進行明確的函數調用(例如 C 運行時間連結庫呼叫),以取得輸入。 相反地,他們會等候系統將輸入傳遞至它們。
系統會將應用程式的所有輸入傳遞至應用程式中的各種視窗。 每個視窗都有一個函式,稱為視窗程式,每當系統有視窗的輸入時,系統就會呼叫該函式。 視窗程式會處理輸入,並將控件傳回給系統。 若要了解有關視窗程序的詳細資訊,請參閱 視窗程序。
如果最上層視窗停止回應訊息數秒以上,系統會將窗口視為未回應。 在此情況下,系統會隱藏視窗,並將它取代為具有相同 Z 順序、位置、大小和視覺屬性的幽靈視窗。 這可讓使用者移動、調整大小,或甚至關閉應用程式。 不過,這些都是唯一可用的動作,因為應用程式實際上沒有回應。 在除錯模式時,系統不會產生鬼影視窗。
本節討論下列主題:
Windows 訊息
系統會以 訊息的形式將輸入傳遞至視窗程式。 訊息是由系統和應用程式產生。 系統會在每個輸入事件產生訊息,例如,當使用者輸入、移動滑鼠或按兩下滾動條之類的控制件時。 系統也會產生訊息,以回應應用程式帶來的系統變更,例如當應用程式變更系統字型資源池或調整其其中一個視窗的大小時。 應用程式可以產生訊息,以指示自己的窗口執行工作,或與其他應用程式中的窗口通訊。
系統會使用一組四個參數,將訊息傳送至視窗程式:視窗句柄、訊息識別碼,以及兩個稱為 訊息參數的值。 視窗句柄 會識別訊息的預期視窗。 系統會使用它來判斷應該接收訊息的視窗程式。
訊息標識碼 是識別訊息用途的具名常數。 當視窗程式收到訊息時,它會使用訊息標識碼來判斷如何處理訊息。 例如,訊息標識碼 WM_PAINT 會告訴視窗程序視窗工作區已變更,而且必須重新繪製。
訊息參數會指定處理訊息時,視窗程式所使用的數據或數據位置。 訊息參數的意義和值取決於訊息。 訊息參數可以包含整數、封裝的位旗標、包含其他數據之結構的指標等等。 當訊息不使用訊息參數時,通常會設定為 NULL。 窗口程序必須檢查訊息標識碼,以判斷如何解譯訊息參數。
訊息類型
本節描述這兩種類型的訊息:
System-Defined 訊息
當系統與應用程式通訊時,系統會傳送或張貼 系統定義的訊息。 它會使用這些訊息來控制應用程式的作業,並提供要處理之應用程式的輸入和其他資訊。 應用程式也可以傳送或張貼系統定義的訊息。 應用程式通常會使用這些訊息來控制使用預先註冊的窗口類別所建立的控件窗口作業。
每個系統定義的訊息都有唯一的訊息標識碼和對應的符號常數(定義於軟體開發工具包 (SDK) 頭檔中,指出訊息的目的。 例如,WM_PAINT 常數要求窗口繪製其內容。
符號常數會指定系統定義訊息所屬的類別。 常數的前置詞會識別可以解譯和處理訊息的窗口類型。 以下是前置詞及其相關訊息類別。
前綴 | 訊息類別 | 文件 |
---|---|---|
ABM 和 ABN | 應用程式桌面工具列 | Shell 訊息與通知 |
ACM 和 ACN | 動畫控件 | 動畫控件訊息 和 動畫控件通知 |
BCM、BCN、BM和 BN | 按鈕控件 | 按鈕控制件訊息 和 按鈕控制件通知 |
CB 和 CBN | ComboBox 控制件 | 下拉式方塊控件訊息 和 下拉式方塊控件通知 |
CBEM 和 CBEN | ComboBoxEx 控制件 | ComboBoxEx 訊息 和 ComboBoxEx 通知 |
CCM | 一般控制 | 控制訊息 |
CDM | 通用對話框 | 一般對話框訊息 |
DFM | 預設內容選單 | 界面訊息和通知 |
DL | 拖曳清單框 | 拖曳清單框通知 |
DM | 默認按鈕控制件 | 對話框訊息 |
DTM 和 DTN | 日期和時間選擇器控制件 | 日期和時間選擇器訊息 和 日期和時間選擇器通知 |
EM 和 EN | 編輯控制件 | 編輯控件訊息、編輯控件通知、Rich Edit Messages,以及 Rich Edit Notifications |
HDM 和 HDN | 標頭控件 | 標頭控制訊息 和 標頭控制通知 |
HKM | 熱鍵控制 | 熱鍵控制訊息 |
IPM 和 IPN | IP 位址控制 | IP 位址訊息 和 IP 位址通知 |
LB 和 LBN | 清單框控制件 | 清單框訊息 和 清單框通知 |
LM | SysLink 控制件 | SysLink 控件訊息 |
LVM 和 LVN | 清單檢視控件 | 清單檢視訊息 和 清單檢視通知 |
MCM 和 MCN | 月曆控件 | 月曆訊息 和 月曆通知 |
PBM | 進度列 | 進度列提示 |
PGM 和 PGN | 呼叫器控制件 | 呼叫器控件訊息 和 呼叫器控件通知 |
PSM 和 PSN | 屬性表 | 屬性表訊息 和 屬性表通知 |
RB 和 RBN | 鋼筋控制項 | Rebar 控件訊息 和 Rebar 控件通知 |
SB 和 SBN | 狀態列視窗 | 狀態列訊息 和 狀態列通知 |
SBM | 滾動條控件 | 滾動條訊息 |
SMC | Shell 選單 | Shell 訊息和通知 |
STM 和 STN | 靜態控件 | 靜態控件訊息 和 靜態控件通知 |
TB 和 TBN | 工具列 | 工具列控件訊息 和 工具列控件通知 |
TBM 和 TRBN | 滑動條控件 | 滑桿控制訊息 和 滑桿控制通知 |
中醫 和 TCN | 索引標籤控件 | Tab 控件訊息 和 Tab 控件通知 |
TDM 和 TDN | 工作對話框 | 工作對話框訊息 和 工作對話框通知 |
TTM 和 TTN | 工具提示控件 | 工具提示控制訊息 和 工具提示控制通知 |
TVM 和 TVN | 樹視圖控件 | 樹狀視圖訊息 和 樹狀視圖通知 |
UDM 和 UDN | 上下控制 | Up-Down 訊息 和 Up-Down 通知 |
WM | 一般 |
一般視窗訊息涵蓋廣泛的資訊和要求,包括滑鼠和鍵盤輸入的訊息、功能表和對話框輸入、視窗建立和管理,以及動態數據交換 (DDE)。
Application-Defined 訊息
應用程式可以建立訊息,供自己的視窗使用,或與其他進程中的窗口通訊。 如果應用程式建立自己的訊息,接收訊息的視窗程序必須解譯訊息並提供適當的處理。
訊息識別碼值會使用如下:
- 系統為系統定義的訊息保留訊息識別碼的值,範圍從 0x0000 到 0x03FF(即 WM_USER – 1 的值)。 應用程式無法將這些值用於私人訊息。
- 範圍中的值0x0400 (WM_USER的值) 到 0x7FFF 可用於私用視窗類別的訊息識別碼。
- 如果您的應用程式標示為 4.0 版,您可以在 0x8000 (WM_APP) 到 0xBFFF 範圍內使用訊息識別碼值來發送私人訊息。
- 當應用程式呼叫 RegisterWindowMessage 函式來註冊訊息時,系統會返回範圍中0xC000至0xFFFF的訊息標識符。 此函式傳回的訊息標識碼保證在整個系統中是唯一的。 使用此函式可防止其他應用程式針對不同用途使用相同的訊息標識符時,可能發生的衝突。
訊息路由
系統會使用兩種方法將訊息路由傳送至視窗程式:將訊息張貼至稱為 消息佇列的第一出佇列、系統定義的記憶體物件,可暫時儲存訊息,並將訊息直接傳送至窗口程式。
張貼至消息佇列的訊息稱為 佇列訊息。 這些主要是透過滑鼠或鍵盤輸入的使用者輸入結果,例如 WM_MOUSEMOVE、WM_LBUTTONDOWN、WM_KEYDOWN和 WM_CHAR 訊息。 其他佇列訊息包括定時器、繪製和結束訊息:WM_TIMER、WM_PAINT和 WM_QUIT。 大部分其他訊息會直接傳送至視窗程式,稱為 非佇列訊息。
已排入佇列的訊息
系統一次可以顯示任意數目的視窗。 若要將滑鼠和鍵盤輸入路由傳送至適當的窗口,系統會使用消息佇列。
系統會針對每個 GUI 線程維護單一系統消息佇列和一個線程特定的消息佇列。 為了避免為非 GUI 線程建立消息佇列的額外負荷,所有線程一開始都會建立,而不需要消息佇列。 只有在線程第一次呼叫其中一個特定使用者函式時,系統才會建立線程特定的消息佇列:沒有 GUI 函式呼叫會導致建立消息佇列。
每當使用者移動滑鼠、按下滑鼠按鈕或鍵盤上的類型時,滑鼠或鍵盤的裝置驅動程式會將輸入轉換成訊息,並將其放在系統消息佇列中。 系統會一次從系統消息佇列中移除訊息,檢查訊息以判斷目的地視窗,然後將訊息張貼至建立目的地視窗之線程的訊息佇列。 線程的訊息佇列會接收線程所建立視窗的所有滑鼠和鍵盤訊息。 線程會從其佇列中移除訊息,並指示系統將它們傳送至適當的視窗程序進行處理。
除了 WM_PAINT 訊息、WM_TIMER 訊息和 WM_QUIT 訊息之外,系統一律會在消息佇列結尾張貼訊息。 這可確保視窗會以先進先出(FIFO)的正確順序接收其輸入訊息。 不過,WM_PAINT 訊息、WM_TIMER 訊息和 WM_QUIT 訊息會保留在佇列中,而且只有在佇列不包含其他訊息時,才會轉送至窗口程式。 此外,相同視窗的多個 WM_PAINT 訊息會合併成單一 WM_PAINT 訊息,將工作區的所有無效部分合併成單一區域。 結合 WM_PAINT 訊息可減少窗口必須重新繪製其工作區內容的次數。
系統會將訊息張貼至線程的訊息佇列,方法是填入 MSG 結構,然後將它複製到消息佇列。 MSG 中的資訊 包括:訊息預定的視窗句柄、訊息識別碼、兩個訊息參數、訊息張貼時間,以及滑鼠游標位置。 線程可以使用 postMessage 或 postThreadMessage函式,將訊息張貼至自己的消息佇列或另一個線程的佇列。
應用程式可以使用 getMessage函式,從其佇列中移除訊息。 若要檢查訊息而不將其從佇列中移除,應用程式可以使用 PeekMessage 函式。 此函式會填入 MSG 中有關訊息的資訊。
從佇列中移除訊息之後,應用程式可以使用 DispatchMessage 函式,將訊息傳送至視窗程序進行處理。 DispatchMessage 需要指向由先前呼叫 GetMessage 或 PeekMessage 函式所填入的 MSG 指標。 DispatchMessage 會將視窗句柄、訊息識別碼和兩個訊息參數傳遞給視窗程式,但不會傳遞訊息張貼的時間或滑鼠游標位置。 應用程式可以在處理訊息時呼叫 GetMessageTime 和 GetMessagePos 函式來擷取此資訊。
線程可以使用 WaitMessage 函式,在訊息佇列中沒有訊息時,將控制權傳給其他線程。 函式會暫停執行緒,直到在執行緒的訊息佇列中放置新訊息後才會返回。
您可以呼叫 SetMessageExtraInfo 函式,將值與目前線程的訊息佇列產生關聯。 然後呼叫 getMessageExtraInfo函式,以取得與 getMessage或 PeekMessage 函式所擷取的最後一則訊息相關聯的值。
未佇列的訊息
未佇列的訊息會立即傳送至目的地視窗程式,略過系統消息佇列和線程消息佇列。 系統通常會傳送非佇列訊息,以通知影響它的事件視窗。 例如,當使用者啟動新的應用程式視窗時,系統會傳送一系列訊息,包括 WM_ACTIVATE、WM_SETFOCUS和 WM_SETCURSOR。 這些訊息會通知視窗已啟動、將鍵盤輸入導向視窗,以及滑鼠游標已移至視窗框線內。 當應用程式呼叫特定系統函式時,非佇列訊息也可能會產生。 例如,系統會在應用程式使用 SetWindowPos 函式來移動視窗之後,傳送 WM_WINDOWPOSCHANGED 訊息。
某些傳送非佇列訊息的函式 BroadcastSystemMessage、BroadcastSystemMessageEx、SendMessage、SendMessageTimeout和 SendNotifyMessage。
訊息處理
應用程式必須移除並處理張貼至其線程消息佇列的訊息。 單個線程應用程式通常會在其 WinMain 函式中使用 訊息 迴圈,將訊息移除並傳送至適當的視窗程序進行處理。 具有多個線程的應用程式可以在每個建立視窗的線程中包含訊息迴圈。 下列各節說明訊息循環的運作方式,並說明視窗程式的角色:
訊息迴圈
簡單的訊息迴圈包含這三個函式的一個函式呼叫:GetMessage、TranslateMessage,以及 DispatchMessage。 請注意,如果發生錯誤,GetMessage 傳回 –1,因此需要特殊測試。
MSG msg;
BOOL bRet;
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
GetMessage 函式會從佇列擷取訊息,並將其複製到 MSG類型的結構。 除非它遇到 WM_QUIT 訊息,否則它會傳回非零值,在此情況下,它會傳回 FALSE 並結束迴圈。 在單個線程應用程式中,結束訊息迴圈通常是關閉應用程式的第一個步驟。 應用程式可以使用 PostQuitMessage 函式來結束其自身的迴圈,通常是在應用程式主視窗的視窗程序中回應 WM_DESTROY 訊息時執行。
如果您將視窗句柄指定為 getMessage 的第二個參數,則只會從佇列擷取指定視窗的訊息。 GetMessage 也可以篩選佇列中的訊息,只擷取落在指定範圍內的訊息。 如需篩選訊息的詳細資訊,請參閱 訊息篩選。
如果線程要從鍵盤接收字元輸入,線程的訊息循環必須包含 translateMessage 。 每次使用者按下按鍵時,系統會產生虛擬按鍵訊息(WM_KEYDOWN 和 WM_KEYUP)。 虛擬按鍵訊息包含虛擬按鍵程式代碼,可識別按下的按鍵,但未識別其字元值。 若要擷取此值,訊息循環必須包含 translateMessage ,它會將虛擬密鑰訊息轉譯成字元訊息(WM_CHAR),並將它放入應用程式消息佇列中。 接著可以在訊息循環的後續迭代中移除字元訊息,並分派至視窗程序。
DispatchMessage 函式會將訊息傳送至與 MSG 結構中指定的視窗句柄相關聯的視窗程式。 如果視窗句柄是 HWND_TOPMOST,DispatchMessage 會將訊息傳送至系統中所有最上層視窗的視窗程式。 如果視窗句柄是 NULL時,DispatchMessage 不會對該訊息執行任何動作。
應用程式的主要線程會在初始化應用程式並建立至少一個視窗之後,啟動其訊息迴圈。 啟動之後,訊息循環會繼續從線程的訊息佇列擷取訊息,並將其分派至適當的視窗。 當 getMessage函式從消息佇列中移除 WM_QUIT 訊息時,訊息迴圈就會結束。
訊息佇列只需要一個訊息迴圈,即使應用程式包含許多視窗也一樣。 DispatchMessage 一律將訊息分派至適當的視窗;這是因為佇列中的每個訊息都是一個 MSG 結構,其中包含訊息所屬視窗的句柄。
您可以透過各種方式修改訊息迴圈。 例如,您可以擷取佇列中的訊息,而不將它們分派至視窗。 這適用於張貼未指定視窗之訊息的應用程式。 您也可以指示 GetMessage 來搜尋特定訊息,並將其他訊息留在佇列中。 如果您必須暫時略過消息佇列的一般 FIFO 順序,這會很有用。
使用快速鍵的應用程式必須能夠將鍵盤訊息轉譯成命令訊息。 若要這樣做,應用程式的訊息循環必須包含對 translateAccelerator函式的呼叫。 如需加速鍵的詳細資訊,請參閱 快捷鍵。
如果線程使用無模式對話框,訊息迴圈必須包含 IsDialogMessage 函式,以便對話框可以接收鍵盤輸入。
視窗程序
視窗程式是一個函式,可接收並處理傳送至視窗的所有訊息。 每個窗口類別都有一個視窗程式,而使用該類別建立的每個視窗都會使用相同的視窗程式來回應訊息。
系統將訊息數據作為引數傳遞給窗口程序,以便將訊息發送到該程序。 視窗程序接著會針對訊息執行適當的動作;它會檢查訊息識別碼,並在處理訊息時使用訊息參數所指定的資訊。
視窗程式通常不會忽略訊息。 如果訊息未處理,則必須將訊息傳回系統以進行默認處理。 視窗程式會藉由呼叫 DefWindowProc 函式來執行此動作,以執行預設動作並傳回訊息結果。 然後,視窗程式必須傳回此值作為自己的訊息結果。 大部分的視窗程序只會處理一些訊息,並透過呼叫 DefWindowProc,將其他訊息傳遞給系統。
因為屬於相同類別的所有視窗都會共享視窗程式,所以它可以處理數個不同視窗的訊息。 若要識別受訊息影響的特定視窗,視窗程式可以檢查與訊息一起傳遞的視窗句柄。 如需視窗程序的詳細資訊,請參閱 視窗程序。
訊息篩選
應用程式可以透過使用 GetMessage 或 PeekMessage 函式指定訊息過濾器,篩選要從消息佇列中擷取的特定訊息(而忽略其他訊息)。 篩選條件是訊息標識碼的範圍(由第一個和最後一個標識元指定)、視窗句柄或兩者。 GetMessage 和 PeekMessage 使用訊息篩選來選取要從佇列擷取的訊息。 如果應用程式必須搜尋訊息佇列,尋找稍後抵達佇列中的訊息,訊息篩選會很有用。 如果應用程式在處理張貼的訊息之前必須處理輸入(硬體)訊息,它也會很有用。
WM_KEYFIRST 和 WM_KEYLAST 常數可用來作為篩選值來擷取所有鍵盤訊息;WM_MOUSEFIRST 和 WM_MOUSELAST 常數可用來擷取所有滑鼠訊息。
篩選訊息的任何應用程式都必須確保可以張貼滿足訊息篩選條件的訊息。 例如,如果應用程式在未接收鍵盤輸入的視窗中篩選 WM_CHAR 訊息,則不會傳回 getMessage函式。 這有效地讓應用程式「卡住」。
張貼和傳送訊息
任何應用程式都可以張貼和傳送訊息。 如同系統,應用程式會將訊息複製到消息佇列,並將訊息數據當做自變數傳遞至視窗程式來傳送訊息。 若要張貼訊息,應用程式會使用 PostMessage 函式。 應用程式可以呼叫 SendMessage、BroadcastSystemMessage、SendMessageCallback、SendMessageTimeout、SendNotifyMessage或 SendDlgItemMessage 函數來發送訊息。
張貼訊息
應用程式通常會張貼訊息,以通知特定視窗以執行工作。 PostMessage 會為訊息建立 MSG 結構,並將訊息複製到消息佇列。 應用程式的訊息循環最終會擷取訊息,並將其分派至適當的視窗程式。
應用程式可以在不指定窗口的情況下張貼訊息。 如果應用程式在呼叫 PostMessage時,提供 NULL 視窗句柄,則會將訊息張貼至與目前線程相關聯的佇列。 因為未指定任何視窗句柄,因此應用程式必須在訊息循環中處理訊息。 這是建立套用至整個應用程式的訊息,而不是套用至特定視窗的其中一種方式。
有時候,您可能會想要將訊息張貼到系統中的所有最上層視窗。 應用程式可以呼叫 PostMessage,並在 hwnd 參數中指定 HWND_TOPMOST,以將訊息張貼至所有最上層視窗。
常見的程式設計錯誤是假設 PostMessage 函式一律會張貼訊息。 當消息佇列已滿時,這不是真的。 應用程式應該檢查 PostMessage 函式的傳回值,以判斷訊息是否已張貼,如果尚未張貼,請重新張貼訊息。
傳送訊息
應用程式通常會傳送訊息,以通知視窗程式立即執行工作。 SendMessage 函式會將訊息傳送至對應至指定視窗的視窗程式。 函式會等到視窗程式完成處理,然後傳回訊息結果。 父視窗和子視窗通常會透過彼此傳送訊息來通訊。 例如,具有編輯控件做為其子視窗的父視窗,可以藉由傳送訊息給控件來設定控件的文字。 控件可以藉由將訊息傳送給父視窗,以通知使用者所進行的文字變更。
SendMessageCallback 函式也會將訊息傳送至對應至指定視窗的視窗程式。 不過,此函式會立即傳回。 視窗程序處理訊息之後,系統會呼叫指定的回呼函式。 如需回呼函式的詳細資訊,請參閱 SendAsyncProc 函式。
有時候,您可能會想要將訊息傳送至系統中的所有最上層視窗。 例如,如果應用程式變更系統時間,它必須藉由傳送 WM_TIMECHANGE 訊息來通知所有最上層視窗。 應用程式可以呼叫 sendMessage ,並在 hwnd 參數中指定 HWND_TOPMOST,以將訊息傳送至所有最上層視窗。 您也可以呼叫 BroadcastSystemMessage 函式,並在 lpdwRecipients 參數中指定 BSM_APPLICATIONS,將訊息廣播至所有應用程式。
藉由使用 InSendMessage 或 InSendMessageEx 函式,視窗程式可以判斷它是否正在處理另一個線程所傳送的訊息。 當訊息處理取決於訊息的來源時,這項功能很有用。
訊息死結
呼叫 SendMessage 函式以將訊息傳送給另一個執行緒的執行緒,必須等到接收訊息的視窗程序返回後才能繼續執行。 如果接收線程在處理訊息時讓出控制權,則傳送線程無法繼續執行,因為它正在等候 SendMessage 傳回。 如果接收線程附加至與傳送者相同的佇列,可能會導致應用程式死結發生。 (請注意,日誌鉤子會將線程附加至相同的佇列。)
請注意,接收線程不需要明確產生控制;呼叫下列任一函式可能會導致線程隱含地產生控件。
若要避免應用程式中潛在的死結,請考慮使用 SendNotifyMessage 或 SendMessageTimeout 函式。 否則,視窗程式可以呼叫 InSendMessage 或 InSendMessageEx 函式,判斷它收到的訊息是由另一個線程傳送。 在處理訊息時呼叫上述清單中的任何函式之前,視窗程式應該先呼叫 InSendMessage 或 InSendMessageEx。 如果此函式傳回 TRUE,則視窗過程必須在任何導致線程產生控制權的函式之前呼叫 ReplyMessage 函式。
廣播訊息
每個訊息都包含訊息識別碼和兩個參數,wParam 和 lParam。 訊息標識碼是指定訊息用途的唯一值。 參數會提供與訊息相關的其他特定資訊,而 wParam 參數通常是一個類型值,提供該訊息的更多詳細資訊。
訊息廣播 只是將訊息發送給系統中的多個收件者。 若要從應用程式廣播訊息,請使用 BroadcastSystemMessage 函式,指定郵件的收件者。 您必須指定一或多個收件者類型,而不是指定個別收件者。 這些類型是應用程式、可安裝驅動程式、網路驅動程式,以及系統層級設備驅動器。 系統會將廣播訊息傳送給每個指定類型的所有成員。
系統通常會廣播訊息,以響應系統層級設備驅動器或相關元件內發生的變更。 驅動程式或相關元件會將訊息廣播給應用程式和其他元件,以通知它們變更。 例如,負責磁碟驅動器的元件會在磁碟驅動器的裝置驅動程式偵測到媒體變更時,廣播訊息,例如當使用者在磁碟驅動器中插入磁碟時。
系統會依此順序將訊息廣播給收件者:系統層級設備驅動器、網路驅動程式、可安裝的驅動程式和應用程式。 這表示系統層級設備驅動器,如果選擇為收件者,一律會獲得第一個回應訊息的機會。 在指定的收件者類型內,不保證任何驅動程式在任何其他驅動程式之前都會收到指定的訊息。 這表示一條針對特定驅動程式的訊息必須具有全域唯一的訊息識別碼,以防止其他驅動程式不小心處理到該訊息。
您也可以在 SendMessage、SendMessageCallback、SendMessageTimeout或 SendNotifyMessage 函式中指定 HWND_BROADCAST,將訊息廣播至所有最上層視窗。
應用程式會透過頂層視窗的窗口程序接收訊息。 訊息不會傳送至子視窗。 服務可以透過視窗程式或其服務控制處理程式接收訊息。
注意
系統層級設備驅動器會使用相關的系統層級函式來廣播系統訊息。
查詢訊息
您可以建立自己的自定義訊息,並使用它們來協調應用程式與系統中其他元件之間的活動。 如果您已建立自己的可安裝驅動程式或系統層級設備驅動器,這特別有用。 您的自訂訊息可以在驅動程式與使用該驅動程式的應用程式之間傳遞資訊。
若要輪詢收件者以取得執行指定動作的許可權,請使用 查詢訊息。 呼叫 BroadcastSystemMessage時,您可以在 dwFlags 參數中設定 BSF_QUERY 值,以產生自己的查詢訊息。 查詢訊息的每個收件者都必須傳回 TRUE,此函式才能將訊息傳送給下一個收件者。 如果任何收件者傳回 BROADCAST_QUERY_DENY,廣播會立即結束,函式則會傳回零。