Sdílet prostřednictvím


O zprávách a frontách zpráv

Na rozdíl od aplikací založených na MS-DOS jsou aplikace založené na systému Windows řízené událostmi. Nevyvolají explicitní volání funkce (například volání knihovny runtime jazyka C) pro získání vstupu. Místo toho čekají, až systém předá vstup.

Systém předává všechny vstupy pro aplikaci do různých oken v aplikaci. Každé okno má funkci označovanou jako procedura okna, kterou systém volá pokaždé, když má vstup pro okno. Procedura okna zpracuje vstup a vrátí řízení do systému. Další informace o okenních procedurách naleznete v tématu Postupy oken.

Pokud okno nejvyšší úrovně přestane reagovat na zprávy déle než několik sekund, systém považuje okno za nereagující. V tomto případě systém skryje okno a nahradí ho stínovým oknem, které má stejné pořadí vykreslování, umístění, velikost a vizuální atributy. To uživateli umožní přesunout, změnit jeho velikost nebo dokonce zavřít aplikaci. Jedná se však o jediné dostupné akce, protože aplikace ve skutečnosti nereaguje. V režimu ladicího programu systém nevygeneruje stínové okno.

Tato část popisuje následující témata:

Zprávy systému Windows

Systém předává vstup do okenní procedury ve formě zprávy. Zprávy jsou generovány systémem i aplikacemi. Systém vygeneruje zprávu při každé vstupní události – například když uživatel zadá, přesune myš nebo klikne na ovládací prvek, například posuvník. Systém také generuje zprávy v reakci na změny systému, které aplikace přinesla, například když aplikace změní fond prostředků systémového písma nebo změní velikost jednoho ze svých oken. Aplikace může generovat zprávy, které budou směrovat vlastní okna, aby prováděla úkoly nebo komunikovala s okny v jiných aplikacích.

Systém odešle zprávu do procedury okna se sadou čtyř parametrů: popisovač okna, identifikátor zprávy a dvě hodnoty nazývané parametry zprávy. Popisovač okna identifikuje okno, pro které je zpráva určena. Systém ho používá k určení, který okenní postup má obdržet zprávu.

Identifikátor zprávy je pojmenovaná konstanta, která identifikuje účel zprávy. Když procedura okna obdrží zprávu, používá identifikátor zprávy k určení způsobu zpracování zprávy. Například identifikátor zprávy WM_PAINT informuje proceduru okna, že se změnila klientská oblast okna a musí být znovu nakreslena.

Parametry zprávy určují data nebo umístění dat používaných procedurou okna při zpracování zprávy. Význam a hodnota parametrů zprávy závisí na zprávě. Parametr zprávy může obsahovat celé číslo, zabalené bitové příznaky, ukazatel na strukturu obsahující další data atd. Pokud zpráva nepoužívá parametry zprávy, jsou obvykle nastaveny na NULL. Procedura okna musí zkontrolovat identifikátor zprávy, aby bylo možné určit, jak interpretovat parametry zprávy.

Typy zpráv

Tato část popisuje dva typy zpráv:

System-Defined Zprávy

Systém odešle nebo publikuje zprávu definovanou systémem , když komunikuje s aplikací. Tyto zprávy používá k řízení operací aplikací a k poskytování vstupních a dalších informací pro zpracování aplikací. Aplikace může také odesílat nebo zveřejňovat systémově definované zprávy. Aplikace obvykle používají tyto zprávy k řízení provozu ovládacích oken vytvořených pomocí předemregistrovaných tříd oken.

Každá zpráva definovaná systémem má jedinečný identifikátor zprávy a odpovídající symbolickou konstantu (definovanou v hlavičkových souborech sady SDK )), která uvádí účel zprávy. Například konstantní WM_PAINT žádá, aby okno vykreslilo svůj obsah.

Symbolické konstanty určují kategorii, do které patří zprávy definované systémem. Předpona konstanty identifikuje typ okna, který může interpretovat a zpracovávat zprávu. Následují předpony a jejich související kategorie zpráv.

Předpona Kategorie zprávy Dokumentace
ABM a ABN Panel nástrojů pracovní plochy aplikace Zprávy a oznámení Shellu
ACM a ACN Ovládání animace Zprávy pro řízení animace a Upozornění pro řízení animace
BCM, BCN, BMa BN Ovládací prvek Tlačítko Ovládací zprávy tlačítka a oznámení ovládacího tlačítka
CB a CBN Ovládací prvek ComboBox ovládacích prvků ComboBox a oznámení ovládacích prvků ComboBox
CBEM a CBEN Ovládací prvek ComboBoxEx zprávy ComboBoxEx a oznámení ComboBoxEx
CCM Obecný ovládací prvek Ovládací Zprávy
CDM Společné dialogové okno běžné zprávy dialogového okna
DFM Výchozí místní nabídka shellových zpráv a oznámení
DL Přetáhnout seznamový rámeček Oznámení seznamového okna pro přetahování
DM Výchozí ovládací prvek stisknutou tlačítkem Zprávy dialogového okna
DTM a DTN Ovládací prvek pro výběr data a času Zprávy pro výběr data a času a Oznámení pro výběr data a času
EM a EN Upravit ovládací prvek zprávy ovládacích prvků, oznámení ovládacích prvků, zprávy bohatého formátování, a oznámení bohatého formátování
HDM a HDN Ovládací prvek Záhlaví zprávy řízení záhlaví a oznámení řízení záhlaví
HKM Ovládání klávesových zkratek Řídicí zprávy klávesových zkratek
IPM a IPN Řízení IP adres zprávy pro IP adresy a oznámení o IP adresách
LB a LBN Ovládací prvek seznamového pole Zprávy seznamu a Oznámení seznamu
LM Ovládací prvek SysLink Zprávy řízení SysLinku
LVM a LVN Ovládací prvek zobrazení seznamu Seznam zobrazení zpráv a Seznam zobrazení oznámení
MCM a MCN Ovládací prvek Měsíční kalendář Zprávy kalendáře měsíce a oznámení kalendáře měsíce
PBM Indikátor průběhu zprávy indikátoru průběhu
PGM a PGN Ovládací prvek Pager zprávy ovládacích prvků pageru a oznámení ovládacích prvků pageru
PSM a PSN Seznam vlastností zprávy vlastnostního listu a oznámení vlastnostního listu
RB a RBN Ovládací prvek Rebar řídicí zprávy ovládacích prvků Rebar a oznámení ovládacích prvků Rebar
SB a SBN okno se stavovým řádkem Zprávy na stavovém řádku a Oznámení na stavovém řádku
SBM Ovládací prvek posuvníku zprávy posuvníku
Řadiče pro správu základní desky Nabídka Shell Shell zpráv a oznámení
STM a STN Statický ovládací prvek Statické řídicí zprávy a Statická řídicí oznámení
TB a TBN Panel nástrojů Zprávy ovládacích prvků panelu nástrojů a oznámení ovládacích prvků panelu nástrojů
TBM a TRBN Ovládací prvek Trackbar Řídicí zprávy trackbaru a oznámení ovládacích prvků trackbaru
TCM a TCN Ovládací prvek Tab Zprávy ovládacích prvků karty a Oznámení ovládacích prvků karty
TDM a TDN Úkolový dialog Zprávy dialogového okna úkolů a oznámení dialogového okna úkolů
TTM a TTN Ovládací prvek tooltipu zprávy ovládacích prvků nástrojových tipů a oznámení ovládacích prvků nástrojových tipů
TVM a TVN Ovládací prvek stromového zobrazení Stromové zobrazení zpráv a Stromové zobrazení oznámení
UDM a UDN Ovládací prvek nahoru dolů Up-Down zprávy a Up-Down oznámení
WM Obecné
Zprávy schránky
Oznámení o schránce
Oznámení o obecných dialogových oknech
Oznámení o kurzoru
Zpráva kopírování dat
Zprávy Desktop Window Manageru
zprávy správy zařízení
Oznámení dialogového okna
dynamické zprávy výměny dat
Oznámení o dynamické výměně dat
Upozornění na hooky
Zprávy akcelerátoru klávesnice
oznámení akcelerátoru klávesnice
vstupní zprávy klávesnice
Upozornění na zadávání z klávesnice
Notifikace nabídky
Oznámení o vstupu z myši
Zprávy rozhraní pro více dokumentů
nezpracovaná vstupní oznámení
Oznámení o posuvníku
Oznámení časovače
zprávy okna
Oznámení okna

Obecné zprávy oken pokrývají širokou škálu informací a požadavků, včetně zpráv pro vstup myši a klávesnice, nabídky a dialogového okna zadávání, vytváření a správy oken a dynamické výměny dat (DDE).

Application-Defined zprávy

Aplikace může vytvářet zprávy, které budou používat vlastní okna nebo které budou sloužit ke komunikaci s okny v jiných procesech. Pokud aplikace vytvoří vlastní zprávy, musí procedura okna, která je přijme, interpretovat zprávy a poskytovat odpovídající zpracování.

Hodnoty identifikátoru zpráv se používají takto:

  • Systém si vyhrazuje hodnoty identifikátoru zpráv v rozsahu 0x0000 prostřednictvím 0x03FF (hodnota WM_USER – 1) pro zprávy definované systémem. Aplikace nemohou tyto hodnoty použít pro soukromé zprávy.
  • Hodnoty v rozsahu 0x0400 (hodnota WM_USER) až 0x7FFF jsou k dispozici pro identifikátory zpráv pro třídy privátních oken.
  • Pokud je vaše aplikace označená verzí 4.0, můžete pro soukromé zprávy použít hodnoty identifikátorů zpráv v rozsahu 0x8000 (WM_APP0xBFFF).
  • Systém vrátí identifikátor zprávy v oblasti 0xC000 prostřednictvím 0xFFFF, když aplikace volá funkci RegisterWindowMessage pro registraci zprávy. Identifikátor zprávy vrácený touto funkcí je zaručen jedinečný v celém systému. Použití této funkce zabraňuje konfliktům, ke kterým může dojít, pokud jiné aplikace používají stejný identifikátor zprávy pro různé účely.

Směrování zpráv

Systém používá dvě metody pro směrování zpráv do procedury okna: odesílání zpráv do fronty typu FIFO s názvem fronta zpráv , systémově definovaného paměťového objektu, který dočasně ukládá zprávy, a odesílání zpráv přímo do procedury okna.

Zpráva odeslaná do fronty zpráv se nazývá zpráva zařazená do fronty. Jedná se především o výsledek uživatelského vstupu zadaného myší nebo klávesnicí, jako jsou WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_KEYDOWNa WM_CHAR zprávy. Mezi další zprávy zařazené do fronty patří časovač, malování a ukončení zpráv: WM_TIMER, WM_PAINTa WM_QUIT. Většina dalších zpráv, které jsou odesílány přímo do okna procedura, se nazývají neřaděné zprávy.

Zprávy zařazené do fronty

Systém může zobrazit libovolný počet oken najednou. Ke směrování vstupu myši a klávesnice do příslušného okna systém používá fronty zpráv.

Systém udržuje jednu systémovou frontu zpráv a jednu frontu zpráv specifickou pro vlákno pro každé vlákno grafického uživatelského rozhraní. Aby se zabránilo režijním nákladům na vytvoření fronty zpráv pro vlákna bez grafického uživatelského rozhraní, jsou všechna vlákna vytvořena zpočátku bez fronty zpráv. Systém vytvoří frontu zpráv specifickou pro vlákno pouze tehdy, když vlákno provede první volání jedné z konkrétních uživatelských funkcí; Žádné volání funkce grafického uživatelského rozhraní způsobí vytvoření fronty zpráv.

Kdykoli uživatel přesune myš, klikne na tlačítka myši nebo zadá na klávesnici, ovladač zařízení myši nebo klávesnice převede vstup na zprávy a umístí je do systémové fronty zpráv. Systém odebere zprávy po jednom z fronty systémových zpráv, prozkoumá je, aby určil cílové okno, a pak je publikuje do fronty zpráv ve vlákně, které vytvořilo cílové okno. Fronta zpráv vlákna přijímá všechny zprávy myši a klávesnice pro okna vytvořená vláknem. Vlákno odebere zprávy z fronty a nasměruje systém tak, aby je odeslal do příslušného okna pro zpracování.

S výjimkou zprávy WM_PAINT, zprávy WM_TIMER a zprávy WM_QUIT systém vždy publikuje zprávy na konci fronty zpráv. Tím se zajistí, že okno obdrží vstupní zprávy ve správném pořadí první dovnitř, první ven (FIFO). Zprávy WM_PAINT, WM_TIMER a WM_QUIT se však uchovávají ve frontě a přepošlou se do procedury okna pouze v případě, že fronta neobsahuje žádné jiné zprávy. Kromě toho se více WM_PAINT zpráv pro stejné okno sloučí do jediného WM_PAINT zprávy, konsolidujíc všechny neplatné části klientské oblasti do jedné oblasti. Kombinování WM_PAINT zpráv snižuje počet případů, kdy musí okno překreslit obsah své klientské oblasti.

Systém odesílá zprávu do fronty zpráv vlákna vyplněním struktury MSG a poté jejím zkopírováním do fronty zpráv. Informace v MSG zahrnují: popisovač okna, pro které je zpráva určena, identifikátor zprávy, dva parametry zprávy, čas odeslání zprávy a umístění kurzoru myši. Vlákno může odeslat zprávu do vlastní fronty zpráv nebo do fronty jiného vlákna pomocí funkce PostMessage nebo PostThreadMessage.

Aplikace může odebrat zprávu z fronty pomocí funkce GetMessage. Pro prozkoumání zprávy bez odebrání z fronty může aplikace použít funkci PeekMessage. Tato funkce vyplní msG informacemi o zprávě.

Po odebrání zprávy z fronty může aplikace použít funkci DispatchMessage k nasměrování systému na odeslání zprávy do okna pro zpracování. DispatchMessage přijímá ukazatel na MSG, který byl vyplněn předchozím voláním funkce GetMessage nebo PeekMessage. DispatchMessage předá popisovač okna, identifikátor zprávy a dva parametry zprávy k proceduře okna, ale nepředá čas odeslání zprávy ani umístění kurzoru myši. Aplikace může načíst tyto informace voláním GetMessageTime a GetMessagePos funkce při zpracování zprávy.

Vlákno může použít funkci WaitMessage k tomu, aby předalo řízení jiným vláknům, pokud nemá žádné zprávy ve své frontě zpráv. Funkce pozastaví vlákno a nevrátí se, dokud se do fronty zpráv vlákna nevrátí nová zpráva.

Můžete volat funkci SetMessageExtraInfo, která přidruží hodnotu k frontě zpráv aktuálního vlákna. Potom zavolejte funkci GetMessageExtraInfo, která získá hodnotu přidruženou k poslední zprávě načtené funkcí GetMessage nebo PeekMessage funkce.

Neřadené zprávy

Neřaděné zprávy se odesílají okamžitě do cílového okna procedury a vynechávají frontu zpráv systému a frontu zpráv ve vlákně. Systém obvykle odesílá zprávy, které nejsou ve frontě, aby upozorňovaly na události, které na ni mají vliv. Například když uživatel aktivuje nové okno aplikace, systém odešle okno řadu zpráv, včetně WM_ACTIVATE, WM_SETFOCUSa WM_SETCURSOR. Tyto zprávy upozorňují na aktivované okno, že se do okna směruje vstup klávesnice a že kurzor myši byl přesunut v rámci ohraničení okna. Neřazení zpráv může také vést k tomu, že aplikace volá určité systémové funkce. Systém například odešle WM_WINDOWPOSCHANGED zprávu poté, co aplikace použije funkci SetWindowPos k přesunutí okna.

Některé funkce odesílající nefrontované zprávy jsou BroadcastSystemMessage, BroadcastSystemMessageEx, SendMessage, SendMessageTimeouta SendNotifyMessage.

Zpracování zpráv

Aplikace musí odebírat a zpracovávat zprávy odeslané do front zpráv ve svých vláknech. Jednovláknová aplikace obvykle používá smyčku zpráv ve své funkci WinMain k odebrání a odesílání zpráv do příslušných procedur okna pro zpracování. Aplikace s více vlákny můžou do každého vlákna, které vytvoří okno, obsahovat smyčku zpráv. Následující části popisují fungování smyčky zpráv a vysvětlují roli procedury okna:

Smyčka zpráv

Jednoduchá smyčka zpráv se skládá z jednoho volání každé z těchto tří funkcí: GetMessage, TranslateMessagea DispatchMessage. Všimněte si, že pokud dojde k chybě, GetMessage vrátí hodnotu –1, takže je potřeba provést speciální testování.

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); 
    }
}

Funkce GetMessage načte zprávu z fronty a zkopíruje ji do struktury typu MSG. Vrátí nenulovou hodnotu, pokud nenarazí na zprávu WM_QUIT, v takovém případě vrátí FALSE a ukončí smyčku. V jednovláknové aplikaci je ukončení smyčky zpráv často prvním krokem při zavření aplikace. Aplikace může ukončit vlastní smyčku pomocí funkce PostQuitMessage, obvykle v reakci na WM_DESTROY zprávu ve výchozím okně aplikace.

Pokud jako druhý parametr zadáte popisovač okna do GetMessage, z fronty budou načteny pouze zprávy určené pro toto okno. GetMessage může také filtrovat zprávy ve frontě a načítat pouze ty zprávy, které spadají do zadaného rozsahu. Další informace o filtrování zpráv naleznete v tématu Filtrování zpráv.

Smyčka zpráv vlákna musí obsahovat TranslateMessage, pokud vlákno přijímá znakový vstup z klávesnice. Systém generuje zprávy virtuálních kláves (WM_KEYDOWN a WM_KEYUP) pokaždé, když uživatel stiskne klávesu. Zpráva virtuálního klíče obsahuje kód virtuálního klíče, který identifikuje, která klávesa byla stisknuta, ale ne znaková hodnota. Pro načtení této hodnoty musí smyčka zpráv obsahovat TranslateMessage, která přeloží zprávu virtuálního klíče do znakové zprávy (WM_CHAR) a umístí ji zpět do fronty zpráv aplikace. Znakovou zprávu lze odebrat při následné iteraci smyčky zpráv a odeslat ji do procedury okna.

Funkce DispatchMessage odešle zprávu do procedury okna přidružené k popisovači okna zadanému ve struktuře MSG. Pokud je popisovač okna HWND_TOPMOST, DispatchMessage odešle zprávu procedurám oken všech oken nejvyšší úrovně v systému. Pokud je popisovač okna null, DispatchMessage nic nedělá se zprávou.

Hlavní vlákno aplikace spustí smyčku zpráv po inicializaci aplikace a vytvoření alespoň jednoho okna. Po spuštění smyčka zpráv bude dál načítat zprávy z fronty zpráv vlákna a odesílat je do příslušných oken. Smyčka zpráv skončí, když funkce GetMessage odebere WM_QUIT zprávu z fronty zpráv.

Pro frontu zpráv je potřeba jenom jedna smyčka zpráv, i když aplikace obsahuje mnoho oken. DispatchMessage vždy odešle zprávu do správného okna; je to proto, že každá zpráva ve frontě je struktura MSG, která obsahuje identifikátor okna, do kterého zpráva patří.

Smyčku zpráv můžete upravovat různými způsoby. Můžete například načíst zprávy z fronty, aniž byste je odeslali do okna. To je užitečné pro aplikace, které zasílají zprávy bez zadání okna. Také můžete směrovat GetMessage k vyhledání konkrétních zpráv, zatímco ostatní zprávy zůstanou ve frontě. To je užitečné, pokud je nutné dočasně obejít obvyklé pořadí FIFO fronty zpráv.

Aplikace, která používá klávesy akcelerátoru, musí být schopná přeložit zprávy klávesnice na zprávy příkazů. Aby se to provedlo, musí smyčka zpráv aplikace obsahovat volání funkce TranslateAccelerator. Další informace o akceleračních klávesách naleznete v tématu akcelerační klávesy.

Pokud vlákno používá bezmodální dialogové okno, musí smyčka zpráv obsahovat funkci IsDialogMessage, aby dialogové okno mohlo přijímat vstupy z klávesnice.

Postup okna

Procedura okna je funkce, která přijímá a zpracovává všechny zprávy odeslané do okna. Každá třída okna má proceduru okna a každé okno vytvořené s danou třídou používá stejný postup okna k odpovídání na zprávy.

Systém odešle zprávu do procedury okna předáním dat zprávy jako argumentů procedury. Postup okna pak provede příslušnou akci pro zprávu; kontroluje identifikátor zprávy a při zpracování zprávy používá informace zadané parametry zprávy.

Procedura okna obvykle zprávu neignoruje. Pokud zprávu nezpracová, musí zprávu odeslat zpět do systému pro výchozí zpracování. Tento postup okna provede voláním funkce DefWindowProc, která provede výchozí akci a vrátí výsledek zprávy. Procedura okna pak musí tuto hodnotu vrátit jako vlastní výsledek zprávy. Většina okenních procedur zpracovává pouze několik zpráv a předává ostatní do systému voláním DefWindowProc.

Protože procedura okna je sdílena všemi okny patřícími do stejné třídy, může zpracovávat zprávy pro několik různých oken. Pokud chcete identifikovat konkrétní okno ovlivněné zprávou, může procedura okna prozkoumat popisovač okna předaný zprávou. Další informace o procedurách oken naleznete v tématu Oken procedury.

Filtrování zpráv

Aplikace může zvolit konkrétní zprávy, které se mají načíst z fronty zpráv (a současně ignorovat jiné zprávy), pomocí funkce GetMessage nebo PeekMessage určit filtr zpráv. Filtr je tvořen rozsahem identifikátorů zpráv (určeným prvním a posledním identifikátorem), popisovačem okna, nebo obojím. GetMessage a PeekMessage používají filtr zpráv k výběru, které zprávy se mají načíst z fronty. Filtrování zpráv je užitečné, pokud musí aplikace prohledat frontu zpráv kvůli zprávám, které dorazily později do fronty. Je také užitečné, pokud aplikace musí zpracovat vstupní (hardwarové) zprávy před zpracováním publikovaných zpráv.

Konstanty WM_KEYFIRST a WM_KEYLAST lze použít jako hodnoty filtru k načtení všech zpráv klávesnice; konstanty WM_MOUSEFIRST a WM_MOUSELAST lze použít k načtení všech zpráv myši.

Každá aplikace, která filtruje zprávy, musí zajistit, aby byla publikována zpráva vyhovující filtru zpráv. Pokud například aplikace filtruje zprávu WM_CHAR v okně, které nepřijímá vstup klávesnice, funkce GetMessage se nevrátí. Tím se aplikace efektivně zablokuje.

Publikování a odesílání zpráv

Každá aplikace může publikovat a odesílat zprávy. Podobně jako systém aplikace publikuje zprávu tak, že ji zkopíruje do fronty zpráv a odešle zprávu předáním dat zprávy jako argumenty do procedury okna. K publikování zpráv používá aplikace funkci PostMessage. Aplikace může odeslat zprávu voláním SendMessage, BroadcastSystemMessage, SendMessageCallback, SendMessageTimeout, SendNotifyMessagenebo SendDlgItemMessage funkce.

Publikování zpráv

Aplikace obvykle publikuje zprávu, která upozorní konkrétní okno na provedení úkolu. PostMessage vytvoří pro zprávu strukturumsGa zkopíruje zprávu do fronty zpráv. Smyčka zpráv aplikace nakonec načte zprávu a odešle ji do příslušné funkce okna.

Aplikace může publikovat zprávu bez zadání okna. Pokud aplikace poskytuje popisovač okna NULL při volání PostMessage, zpráva se odešle do fronty přidružené k aktuálnímu vláknu. Vzhledem k tomu, že není zadán žádný popisovač okna, musí aplikace zpracovat zprávu ve smyčce zprávy. Toto je jeden ze způsobů, jak vytvořit zprávu, která se vztahuje na celou aplikaci, a ne na konkrétní okno.

Někdy můžete chtít zprávu publikovat do všech oken nejvyšší úrovně v systému. Aplikace může publikovat zprávu do všech oken nejvyšší úrovně voláním PostMessage a určením HWND_TOPMOST v parametru hwnd.

Běžnou programovací chybou je předpokládat, že funkce PostMessage vždy publikuje zprávu. To neplatí, pokud je fronta zpráv zaplněná. Aplikace by měla zkontrolovat návratovou hodnotu funkce PostMessage, aby určila, zda byla zpráva odeslána, a pokud nebyla, znovu ji odeslat.

Odesílání zpráv

Aplikace obvykle odešle zprávu, která upozorní proceduru okna, aby okamžitě provedla úlohu. Funkce SendMessage odešle zprávu do procedury okna odpovídající danému okně. Funkce počká, až se proces okna dokončí, a vrátí výsledek zprávy. Nadřazená a podřízená okna často komunikují tak, že vzájemně odesílají zprávy. Nadřazené okno, které má jako podřízené okno ovládací prvek pro úpravy, může například nastavit text ovládacího prvku odesláním zprávy. Ovládací prvek může upozornit nadřazené okno o změnách textu, které uživatel provádí odesláním zpráv zpět do nadřazeného objektu.

Funkce SendMessageCallback také odešle zprávu do procedury okna odpovídající danému okně. Tato funkce se však vrací okamžitě. Jakmile procedura okna zpracuje zprávu, systém zavolá zadanou funkci zpětného volání. Další informace o funkci zpětného volání naleznete ve funkci SendAsyncProc.

Někdy můžete chtít poslat zprávu do všech oken nejvyšší úrovně v systému. Pokud například aplikace změní systémový čas, musí o této změně upozornit všechna okna nejvyšší úrovně odesláním WM_TIMECHANGE zprávy. Aplikace může odeslat zprávu do všech oken nejvyšší úrovně voláním SendMessage a určením HWND_TOPMOST v parametru hwnd. Zprávu můžete také vysílat všem aplikacím voláním funkce BroadcastSystemMessage a zadáním BSM_APPLICATIONS v parametru lpdwRecipients.

Pomocí funkce InSendMessage nebo InSendMessageEx může procedura okna určit, zda zpracovává zprávu poslanou jiným vláknem. Tato funkce je užitečná, když zpracování zpráv závisí na původu zprávy.

Zablokování zpráv

Vlákno, které volá funkci SendMessage k odeslání zprávy do jiného vlákna nemůže pokračovat v provádění, dokud procedura okna, která obdrží zprávu vrátí. Pokud přijímající vlákno předá řízení při zpracování zprávy, odesílající vlákno nemůže pokračovat v provádění, protože čeká, až se SendMessage vrátí. Pokud je přijímající vlákno připojené ke stejné frontě jako odesílatel, může dojít k zablokování aplikace. (Všimněte si, že háky deníku připojují vlákna ke stejné frontě.)

Všimněte si, že přijímající nit nemusí explicitně uvolnit řízení; volání kterékoli z následujících funkcí může způsobit implicitní předání řízení.

Pokud se chcete vyhnout potenciálním zablokováním ve vaší aplikaci, zvažte použití funkcí SendNotifyMessage nebo SendMessageTimeout. V opačném případě může procedura okna určit, zda zpráva byla přijata jiným vláknem voláním InSendMessage nebo InSendMessageEx funkce. Před voláním některé z funkcí v předchozím seznamu při zpracování zprávy by procedura okna měla nejprve volat InSendMessage nebo InSendMessageEx. Pokud tato funkce vrátí TRUE, okenní procedura musí volat funkci ReplyMessage před jakoukoli funkcí, která způsobí, že vlákno předá řízení.

Vysílání zpráv

Každá zpráva se skládá z identifikátoru zprávy a dvou parametrů, wParam a lParam. Identifikátor zprávy je jedinečná hodnota, která určuje účel zprávy. Parametry poskytují další informace specifické pro zprávu, ale wParam parametr je obecně hodnota typu, která poskytuje další informace o zprávě.

Rozesílání zpráv znamená jednoduše odeslání zprávy více příjemcům v systému. Pokud chcete vysílat zprávu z aplikace, použijte funkci BroadcastSystemMessage a určete příjemce zprávy. Místo zadávání jednotlivých příjemců je nutné zadat jeden nebo více typů příjemců. Tyto typy jsou aplikace, instalovatelné ovladače, síťové ovladače a ovladače zařízení na úrovni systému. Systém odesílá hromadné zprávy všem členům každého zadaného typu.

Systém obvykle vysílá zprávy v reakci na změny, které probíhají v rámci ovladačů zařízení na úrovni systému nebo souvisejících komponent. Ovladač nebo související komponenta vysílá zprávu aplikacím a dalším komponentám, které je upozorní na změnu. Například komponenta odpovědná za diskové jednotky vysílá zprávu pokaždé, když ovladač zařízení pro disketovou jednotku zjistí změnu média, například když uživatel vloží disk do jednotky.

Systém vysílá zprávy příjemcům v tomto pořadí: ovladače zařízení na úrovni systému, síťové ovladače, instalovatelné ovladače a aplikace. To znamená, že ovladače zařízení na úrovni systému, pokud jsou vybrány jako příjemci, vždy dostanou první příležitost odpovědět na zprávu. V daném typu příjemce není zaručeno, že žádný ovladač obdrží danou zprávu před jakýmkoli jiným ovladačem. To znamená, že zpráva určená pro konkrétní ovladač musí mít globálně jedinečný identifikátor, aby ji žádný jiný ovladač neúmyslně nezpracoval.

Zprávy můžete také vysílat do všech oken nejvyšší úrovně zadáním HWND_BROADCAST v SendMessage, SendMessageCallback, SendMessageTimeoutnebo SendNotifyMessage funkce.

Aplikace přijímají zprávy prostřednictvím procedury pro hlavní okna. Zprávy se neodesílají do podřízených oken. Služby mohou přijímat zprávy prostřednictvím procedury okna nebo obslužných rutin řízení služeb.

Poznámka

Ovladače zařízení na úrovni systému používají související funkci na úrovni systému k vysílání systémových zpráv.

Dotazování zpráv

Můžete vytvářet vlastní zprávy a používat je ke koordinaci aktivit mezi aplikacemi a dalšími komponentami v systému. To je zvlášť užitečné, pokud jste vytvořili vlastní instalovatelné ovladače nebo ovladače zařízení na úrovni systému. Vaše vlastní zprávy můžou přenášet informace do a z ovladače a aplikací, které ovladač používají.

Chcete-li se dotazovat příjemce na svolení k provedení dané akce, použijte dotazovací zprávu. Vlastní dotazovací zprávy můžete vygenerovat nastavením hodnoty BSF_QUERY v parametru dwFlags při volání funkce BroadcastSystemMessage. Každý příjemce zprávy dotazu musí vrátit TRUE, aby funkce odeslala zprávu dalšímu příjemci. Pokud některý příjemce vrátí BROADCAST_QUERY_DENY, vysílání skončí okamžitě a funkce vrátí nulu.