C# - Rendszermenü elérése alkalmazásból

forráskód letöltése
Ha a Windows-os alkalmazások fejlécére kattintunk az egér jobb gombjával, akkor legördül az úgynevezett rendszermenü, hogy bizonyos funkciókat könnyebben elérhessünk. Néhány Windows API függvénnyel képesek vagyunk ezt a menüt manipulálni, új menüpontokat felvenni illetve törölni, akár a meglévőket is. Cikkünkben bemutatjuk ezeket a metódusokat használat közben.
Az API metódusok közvetlenül alkalmasak a rendszermenü elérésére, csupán paramétereiket kell megfelelően megadni. A függvények a USER32.DLL állományban találhatók. Lássuk sorban, melyek lesznek ezek.
GetSystemMenu
A metódus deklarációja a C# mellékelt példában a következő:
[DllImport("user32.dll")] 
private static extern int GetSystemMenu(int hwnd, int bRevert);
A metódus segítségével lekérdezhetjük az adott alkalmazás rendszermenüjének azonosítóját, mely egy egész szám. Az első paraméterben kell megadni az adott alkalmazás ablakának kezelőjét.
AppendMenu
A deklarációja a következő:
[DllImport("user32.dll")] 
private static extern int AppendMenu(int hMenu,int Flagsw,int IDNewItem,string lpNewItem);
A metódus segítségével adhatunk új menüpontot, vagy szeparátort a menühöz. A metódus paraméterei:
  • hMenu: a fenti metódussal lekérdezett menüazonosító.
  • Flagsw: a művelet jellegére utaló egész konstans. Több lehetséges értéke közül mi a 0 értéket használjuk, ekkor a menüpont az azonosítója alapján kerül hozzáadásra (a harmadik paraméter az azonosító).
  • IDNewItem: a menüpont általunk megadott azonosítója. A szám tetszőleges pozitív egész lehet.
  • lpNewItem: a menüpont felirata, szeparátor esetében NULL.
DeleteMenu
A deklaráció a következő:
[DllImport("user32.dll")] 
private static extern int DeleteMenu(int hMenu,int uPosition,int uFlags);
A metódussal törölhetünk egy tetszőleges azonosítóval vagy sorszámmal rendelkező menüpontot, vagy szeparátort. A metódus paraméterei:
  • hMenu: a rendszermenü azonosítója.
  • uPosition: a menüpont azonosítója, vagy pozíciója. Értéke az uFlags értékétől függ: amennyiben az uFlags nulla, akkor a törlendő menüpont ID-jét kell megadnunk, ami az általunk megadott menüpont esetében ismert. Amennyiben viszont az uFlags értéke 0x400, akkor a menüpont sorszámát kell megadnunk.
GetMenuItemCount
A deklaráció a következő:
[DllImport("user32.dll")] 
private static extern int GetMenuItemCount(int hMenu);
A metódus visszaadja a megadott azonosítóval rendelkező rendszermenü elemeinek számát.
GetMenuItemID
A deklaráció a következő:
[DllImport("user32.dll")] 
private static extern int GetMenuItemID(int hMenu,int nPos);
A metódus visszaadja a megadott pozícióban található menüpont azonosítóját.
Gyakorlati felhasználásuk
A mellékelt példában tetszőleges feliratú menüpontokat, vagy szeparátorokat adhatunk a rendszermenühöz a megfelelő feliratú nyomógomb megnyomásával.
A szövegmezőben megadott feliratú menüpontot a következőképpen adhatjuk a rendszermenühöz. Elsőként lekérdezzük a rendszermenü azonosítóját.
menu_ref = GetSystemMenu(Handle.ToInt32(), 0);
Majd a menüpontot a menühöz adjuk. Azonosítóként a 999-et választjuk.
AppendMenu(menu_ref,0,999,textBox1.Text);
A menüpont törlésekor egyszerűen meghívjuk a DeleteMenu metódust, mely az összes 999-es azonosítóval bíró menüpontot törli.
DeleteMenu(menu_ref,999,0);
A szeparátort hozzáadásakor a következőképpen járunk el:
AppendMenu(menu_ref,0xA00,0,null);
Annak törlésekor lekérdezzük a rendszermenü elemszámát.
int count = GetMenuItemCount(menu_ref);
Majd lekérdezzük az utolsó elem (ha ez a szeparátor) azonosítóját.
int id = GetMenuItemID(menu_ref,count-1);
Amennyiben ez nulla, vagyis az elem egy szeparátor, akkor töröljük azt.
if (id == 0)
{
  DeleteMenu(menu_ref,count-1,0x400);
}
Ezzel elkerülhető a rendszermenü beépített elemeinek törlése.