關於訊息和訊息佇列
不同于 MS-DOS 型應用程式,Windows 型應用程式是事件驅動。 它們不會 (明確呼叫函式,例如 C 執行時間程式庫呼叫) 以取得輸入。 相反地,他們會等候系統將輸入傳遞至它們。
系統會將應用程式的所有輸入傳遞至應用程式中的各種視窗。 每個視窗都有一個函式,稱為視窗程式,每當系統有視窗的輸入時,系統就會呼叫此函式。 視窗程式會處理輸入,並將控制項傳回給系統。 如需視窗程式的詳細資訊,請參閱 視窗程式。
如果最上層視窗停止回應訊息超過數秒,系統會將視窗視為不回應。 在此情況下,系統會隱藏視窗,並將它取代為具有相同 Z 順序、位置、大小和視覺屬性的准刪除視窗。 這可讓使用者移動、調整大小,或甚至關閉應用程式。 不過,這些是唯一可用的動作,因為應用程式實際上沒有回應。 在偵錯工具模式中時,系統不會產生准刪除視窗。
本節討論下列主題:
Windows 訊息
系統會以 訊息形式將輸入傳遞至視窗程式。 訊息是由系統和應用程式產生。 系統會在每個輸入事件產生訊息,例如,當使用者輸入、移動滑鼠或按一下捲軸之類的控制項時。 系統也會產生訊息,以回應應用程式所產生的系統變更,例如當應用程式變更系統字型資源的集區或調整其其中一個視窗的大小時。 應用程式可以產生訊息,以指示自己的視窗執行工作,或與其他應用程式中的視窗通訊。
系統會使用一組四個參數將訊息傳送至視窗程式:視窗控制碼、訊息識別碼,以及兩個稱為 訊息參數的值。 視窗控制碼會識別訊息預定的視窗。 系統會使用它來判斷應該接收訊息的視窗程式。
訊息識別碼是可識別訊息用途的具名常數。 當視窗程式收到訊息時,它會使用訊息識別碼來判斷如何處理訊息。 例如,訊息識別碼 WM_PAINT 會告訴視窗程式視窗的工作區已變更,而且必須重新繪製。
訊息參數會指定處理訊息時,視窗程式所使用的資料或資料位置。 訊息參數的意義和值取決於訊息。 訊息參數可以包含整數、已封裝的位旗標、包含其他資料的結構指標等等。 當訊息不使用訊息參數時,它們通常會設定為 Null。 視窗程式必須檢查訊息識別碼,以判斷如何解譯訊息參數。
訊息類型
本節描述兩種類型的訊息:
System-Defined訊息
當系統與應用程式通訊時,系統會傳送或張貼 系統定義的訊息 。 它會使用這些訊息來控制應用程式的作業,並提供要處理之應用程式的輸入和其他資訊。 應用程式也可以傳送或張貼系統定義的訊息。 應用程式通常會使用這些訊息來控制使用預先註冊的視窗類別所建立的控制視窗作業。
每個系統定義的訊息都有唯一的訊息識別碼,以及軟體發展工具組中定義的對應符號常數 (, (SDK) 標頭檔,) 指出訊息的目的。 例如, WM_PAINT 常數要求視窗繪製其內容。
符號常數會指定系統定義訊息所屬的類別。 常數的前置詞會識別可以解譯和處理訊息的視窗類型。 以下是前置詞及其相關訊息類別。
前置詞 | 訊息類別 | 文件 |
---|---|---|
ABM 和 ABN | 應用程式桌面工具列 | 殼層訊息和通知 |
ACM 和 ACN | 動畫控制項 | 動畫控制項訊息 和 動畫控制項通知 |
BCM、 BCN、 BM和 BN | Button 控制項 | 按鈕控制項訊息 和 按鈕控制項通知 |
CB 和 CBN | ComboBox 控制項 | ComboBox 控制項訊息 和 ComboBox 控制項通知 |
CBEM 和 CBEN | ComboBoxEx 控制項 | ComboBoxEx 訊息 和 ComboBoxEx 通知 |
Ccm | 一般控制項 | 控制訊息 |
CDM | 通用對話方塊 | 一般對話方塊訊息 |
Dfm | 預設操作功能表 | 殼層訊息和通知 |
DL | 拖曳清單方塊 | 拖曳清單方塊通知 |
DM | 預設的按鈕控制項 | 對話方塊訊息 |
DTM 和 DTN | 日期和時間選擇器控制項 | 日期和時間選擇器訊息和日期和時間選擇器通知 |
EM 和 EN | 編輯控制項 | 編輯控制項訊息、 編輯控制項通知、 豐富編輯訊息和 豐富編輯通知 |
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 控制項訊息 和 Rebar 控制項通知 |
SB 和 SBN | 狀態列視窗 | 狀態列訊息 和 狀態列通知 |
SBM | 捲軸控制項 | 捲軸訊息 |
Smc | 殼層功能表 | 殼層訊息和通知 |
STM 和 STN | 靜態控制項 | 靜態控制項訊息 和 靜態控制項通知 |
TB 和 TBN | 工具列 | 工具列控制項訊息 和 工具列控制項通知 |
TBM 和 TRBN | 追蹤列控制項 | 追蹤列控制項訊息 和 追蹤欄控制項通知 |
TCM 和 TCN | 索引標籤控制項 | Tab 控制項訊息 和 索引標籤控制項通知 |
TDM 和 TDN | 工作對話方塊 | 工作對話方塊訊息 和 工作對話方塊通知 |
TTM 和 TTN | 工具提示控制項 | 工具提示控制項訊息 和 工具提示控制項通知 |
TVM 和 TVN | 樹狀檢視控制項 | 樹狀檢視訊息 和 樹狀檢視通知 |
UDM 和 UDN | 向上鍵控制項 | 向上關閉訊息 和 向上關閉通知 |
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_ACTI加值稅E、 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 傳回。 如果接收執行緒附加至與傳送者相同的佇列,可能會導致應用程式死結髮生。 (請注意,日誌勾點會將執行緒附加至相同的 queue.)
請注意,接收執行緒不需要明確產生控制權;呼叫下列任一函式可能會導致執行緒隱含地產生控制權。
- DialogBox
- DialogBoxIndirect
- DialogBoxIndirectParam
- DialogBoxParam
- GetMessage
- MessageBox
- PeekMessage
- 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,則廣播會立即結束,且函式會傳回零。