Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
C/C++
Úprava systémové nabídky formuláře
12. února 2001, 00.00 | Chcete přidat vlastní položky do systémového menu formuláře, nebo upravit stávající výchozí položky? Více se dozvíte v tomto článku!
Chcete z nějakého důvodu (i když to není příliš obvyklé) přidat vlastní položky do systémového menu formuláře, nebo upravit stávající výchozí položky třeba tak, jak je vidět na obrázku?
Pozor - jak vidíte, nejde o běžné tzv. hlavní menu okna, ale o nabídku, která se rozbalí například při kliknutí na ikonku v levém horním rohu titulkového pruhu formuláře. Co k tomu potřebujeme? Za prvé musíme získat handle na systémové menu formuláře. K tomu použijeme API funkci
HMENU GetSystemMenu(HWND hwnd, BOOL bRevert);
Pro vlastní přidání položek pak použijeme API funkci
BOOL InsertMenuItem(HMENU hMenu, UINY uItem, BOOL fbyPositon, LPCMENUITEMINFO lpmi);
Před tím musíme správně naplnit strukturu MENUITEMINFO (parametr lpmi). Nejlépe bude ukázat si vše na příkladu. Následující funkce AddSysMenuItems přidá do systémového menu nejprve oddělovač (separátor) před položku "Zavřít ...", a před tento separátor pak dvě vlastní položky. S položkami jsou přidány také bitmapy (je použita stejná bitmapa u obou položek). Handle této bitmapy, které potřebujeme při naplnění struktury MENUITEMINFO, načítáme v konstruktoru ze zdrojů (resources) programu.
|
Kromě přidání položek můžeme i upravovat stávající položky, včetně těch výchozích. V ukázkovém programu je příklad na modifikaci položky "Minimalizovat". U této položky je změněn text i bitmapa. Jak, to vidíte v následující funkci:
|
Vidíte, že nejdříve získáme informace o dané položce pomocí API funkce GetSystemMenu, která nám naplní strukturu MENUITEMINFO. V této struktuře pak provedeme příslušné úpravy a použijeme ji jako parametr volání API funkce SetMenuItemInfo. Tím tedy máme v systémovém menu vlastní položky, ale potřebujeme také umět v programu zachytit jejich vybrání uživatelem. Jak to provedeme? Systémové menu posílá svému oknu zprávu WM_SYSCOMMAND (na rozdíl od "normálního" menu, které posílá zprávu WM_COMMAND). V dokumentaci je u popisu zprávy WM_SYSCOMMAND poněkud zavádějící označení parametru wParam jako "system command type". To může svádět k myšlence, že tento parametr může nabývat pouze jedné ze zde uvedených hodnot SC_xxxx. Ve skutečnosti se jedná, podobně jako u zprávy WM_COMMAND o identifikátor položky menu. Také konstanty SC_xxxx jsou takovými identifikátory příkazu. Závěr z toho je jasný. Stačí mít vlastní handler zprávy WM_SYSCOMMAND a hodnotu wParam testovat na vlastní definované identifikátory. V doprovodném příkladu jsem vytvořil takovýto handler:
|
|
USERES("user.res");
v hlavním modulu projektu (SysMenu.cpp).
Vytvoření handleru zprávy WM_SYSCOMMAND je realizováno pomocí mapy zpráv, jejíž princip je dostatečně popsán v nápovědě C++ Builderu a myslím, že většina programátorů dokáže přidat vlastní handler zprávy. Pro úplnost zde uvedu postup, jak lze přidat kostru handleru pomocí ClassExploreru. Vyvoláte kontextovou nabídku (např. pravým tlačítkem myši) objektu formuláře, vyberete "New Method...", a následný dialog vyplníte třeba takto:
Položku "Method Name" můžete vyplnit libovolným názvem metody, důležitý je typ argumentu: Můžete použít obecný typ zprávy TMessage, nebo typ TWMSysCommand, který je přizpůsobený konkrétní zprávě, v našem případě WM_SYSCOMMAND. Po potvrzení tohoto dialogu nám "wizard" vytvoří v deklaraci třídy formuláře tzv. mapu zpráv pomocí maker BEGIN_MESSAGE_MAP a END_MESSAGE_MAP:
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_SYSCOMMAND, TMessage, OnWM_SYSCOMMAND)
END_MESSAGE_MAP(TForm)
Vlastní kód handleru pak vidíte ve výše uvedeném výpisu.
V souboru UkazkovyProjekt.zip je vše, co bylo zmíněno v tomto článku,
demonstrováno v konkrétním projektu, jehož "screenshot" je na začátku
článku.
UkazkovyProjekt.zip (z důvodu velikosti je linkován s použitím run-time balíčku a RTL knihovny)
Diskuse k článku
-
25. listopadu 2012
-
30. srpna 2002
-
10. října 2002
-
4. listopadu 2002
-
12. září 2002
-
25. listopadu 2012
-
28. července 1998
-
31. července 1998
-
28. srpna 1998
-
6. prosince 2000
-
27. prosince 2007
-
4. května 2007