C++ WinAPI - Zachycení zprávy po zobrazení okna

C++ WinAPI - Zachycení zprávy po zobrazení okna

Příspěvekod Wlezley » 10 leden 2013 10:06:14

Je tomu již několik měsíců, co jsem řešil zvláštní problém s CALLBACKem dialogových oken ve WinAPI. Potřeboval jsem podchytit okamžik těsně po vytvoření a zobrazení okna dialogu, abych mohl například bezpečně začít nahrávat dynamická data do jednotlivých prvků, nebo spustit jiný proces. Asi si teď řeknete, že k tomu přeci slouží zpráva WM_SHOWWINDOW. Je to ale omyl. Tato zpráva se posílá právě při procesu zobrazování okna, nikoliv až po jeho zobrazení!

Ukažme si rovnou příklad vyhovujícího řešení:
RAW CODE
#include <Windows.h>

#define WM_APP_START (WM_APP + 10)

INT_PTR CALLBACK DialogEMailReader(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);

switch(message)
{
case WM_SHOWWINDOW:
return (INT_PTR)PostMessage(hDlg, WM_APP_START, 0, 0);

case WM_APP_START:
// V tomto okamžiku je již okno dialogu viditelné
// Zde může být kód, který bude spuštěný až po zobrazení dialogového okna
return (INT_PTR)TRUE;

case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
case IDCLOSE:
case IDCANCEL:
return (INT_PTR)EndDialog(hDlg, LOWORD(wParam));
}
break;
}
return (INT_PTR)FALSE;
}

  1. První věc, které si můžete všimnut, je definice typu naší vlastní zprávy WM_APP_START. Tato zpráva je odvozená od WM_APP. Tato zpráva označuje offset, kde začíná prostor rezervovaných zpráv pro interní užívání naší aplikací. Definice WM_APP má hodnotu 0x8000 (decimálně 32768) a může být k němu přičtena hodnota až do výše 0x3FFF (decimálně 16383); výsledná hodnota tedy nesmí překročit hodnotu 0xBFFF (decimálně 49151). Systém tento rozsah zpráv (svým interním mechanismem) nevyužívá, proto ho označujeme za bezpečný "prostor" pro naše vlastní aplikační zprávy.
  2. "Co se v tomto callbacku vlastně odehrává?" Zde dochází ke zvláštnímu paradoxu, který využívá fázování implicitní pumpy zpráv pro dialogy WinAPI. Zachytíme zprávu WM_SHOWWINDOW a z ní přidáme na konec fronty pumpy naši (námi definovanou) zprávu WM_APP_START.
  3. Zpráva WM_SHOWWINDOW je ukončena, proběhne pár mezi-zpráv na pozadí a zavolá se konečně naše tolik očekávaná zpráva WM_APP_START. Když ji zachytíme, získáme tím bod, kdy je dialogové okno již vytvořené a zobrazené.
Uživatelský avatar
Wlezley
 
Příspěvky: 316
Registrován: 24 září 2011 22:54:46
Bydliště: Plzeň
Projekt: Wlezley EU

Zpět na C/C++

Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 1 návštěvník


cron