C# - SystemTray ikon üzenete

forráskód letöltése
A ToolBar kontrolgyűjteményében találunk egy NotifyIcon nevű kontrolt, melynek segítségével a program indulásakor elhelyezhetünk egy tetszőleges ikont a Tálcán. Az ikonhoz gyorsmenü rendelhető, valamint elérhető, hogy az egérmutatót a kép fölé mozgatva tájékoztató üzenet jelenjen meg a programmal kapcsolatban. Ezeket a funkciókat egészítjük ki a cikkben elkészített saját komponensünkben úgy, hogy az ikonra történő kattintáskor jelenjen meg egy úgynevezett „balloon”-típusú üzenet, a komponens property-jében megadott szöveggel.
A mellékelt példa két projektet tartalmaz. A NIMComponent projekt tartalmazza a Tálca-ikon megjelenítését végző komponens kódját. A komponenst az NIMClient alkalmazásban tesztelhetjük, annak elindulásakor egy kis mosolygó figura jelenik meg a Tálcán.
Az ikonra kattintva megjelenik egy – a hagyományos NotifyIcon komponens felbukkanó üzenetétől eltérő – üzenet, a komponens Text property-jében szerkesztési időben beállított karakterlánccal.
A megoldás lényege, hogy a komponens osztályában létre kell hoznunk egy, a Form osztályból származó osztályt, mely fogadja majd az ikonra, mint űrlapra történő kattintás üzenetét.
private class NotifyForm : System.Windows.Forms.Form
{
Ennek érdekében az osztályban létrehozunk egy saját eseménykezelő delegáltat, valamint egy eseményt a kattintáshoz.
  public delegate void NIHandler(object sender, uint id);
  public event NIHandler ClickOnIt;
  ...
}
Az esemény kezeléséhez felül kell deklarálnunk az osztály DefWndProc metódusát, hogy az egér bal gombjára történő kattintás üzenete feldolgozható legyen.
protected override void DefWndProc(ref Message msg)
{
  if(msg.Msg == 0x400)
  {
Miután eldöntöttük, hogy az ikon által kapott üzenet a felhasználótól származik – WM_USER (0x004) -, lekérdezzük paramétereit.
    uint msgId = (uint)msg.LParam;
    uint id = (uint)msg.WParam;
    switch(msgId)
    {
Amennyiben az első paraméter az egér bal gombjának lenyomásakor keletkező üzenet volt, nem teszünk semmit.
      case 0x201:
        break;
A gomb felengedésének üzenetére azonban kiváltjuk a fent deklarált eseményt.
      case 0x202:
        if(ClickOnIt != null) ClickOnIt(this, id);
        break;
    }
  }
  ...
}
A komponensünk osztályában deklarálnunk kell még változókat ahhoz, hogy az üzenet megjeleníthető legyen, többek közt létre kell hoznunk egy példányt a fent deklarált osztályból.
private static NotifyForm nForm = new NotifyForm();
Az ikon megjelenítése, program bezárásakor történő eltüntetése és az üzenet megjelenítése mind egy API függvény meghívásával történik, csak különböző paraméterekkel.
[DllImport("shell32.Dll")]
private static extern System.Int32 Shell_NotifyIcon(NotifyCommand cmd, ref NotifyIconData data);
A függvény első paramétere egy felsorolt típus három eleme közül egy, melyek jelzik, hogy létrehozni, eltüntetni, vagy módosítani kell az adott ikont.
private enum NotifyCommand {Add=0x00, Delete=0x02, Modify=0x01}
A függvény második paramétere egy struktúra, melyhez létrehoztuk a menedzselt kódbeli megfelelőjét.
[StructLayout(LayoutKind.Sequential)]
private struct NotifyIconData
{
  ...
}
A program indulásakor a Create metódusba ágyazott kóddal hozzuk létre az ikont. Ekkor feltöltjük adatokkal az említett struktúra példányát, majd meghívjuk a Shell_NotifyIcon függvényt, első paraméterében a megfelelő értékkel.
NotifyIconData data = new NotifyIconData();
...
Shell_NotifyIcon(NotifyCommand.Add, ref data);
A Remove metódusban található kód a program bezárásakor fut le, eltüntetve az ikont a Tálcáról. Ekkor a NotifyCommand felsorolt típus Delete értékét adjuk meg a Shell_NotifyIcon metódus első paraméterében.
Shell_NotifyIcon(NotifyCommand.Delete, ref data);
A ShowBalloon metódusban úgy hívjuk meg a Shell_NotifyIcon metódust, hogy első paramétere NotifyCommand.Modify lesz, vagyis a második paraméterben megadott struktúrában meghatározzuk, hogy mi lesz ez a módosítás. Ekkor jelenítjük meg az üzenetet, a Text property-ben megadott értékkel.
public void ShowBalloon()
{
  NotifyIconData data = new NotifyIconData();
  data.cbSize = (uint)Marshal.SizeOf(data);
  data.hWnd = nForm.Handle;
A struktúra hWnd mezőjében adjuk meg a kezelőjét a komponensünk által tagobjektumként tartalmazott Form objektumnak, hogy a rendszer tudja, melyik ikonra kattintottuk a Tálcán.
  data.uFlags = NotifyFlags.Info;
Az uFlags mezőben megadjuk, hogy egy információs üzenetet kívánunk megjeleníteni, vagyis egy felkiáltójeles ikon legyen az üzenetablak bal sarkában.
Beállíthatjuk az üzenetablak fejlécszövegét is.
  data.szInfoTitle = "NotifyInfoMessage alkalmazás";
Majd megadjuk a szöveget is, ami az üzenet maga lesz.
  data.szInfo = text;
Végül meghívjuk a Shell_NotifyIcon függvényt.
  Shell_NotifyIcon(NotifyCommand.Modify, ref data);
}
Kipróbáláshoz regisztráljuk a NIMComponent komponensünket a ToolBox palettán, majd dobjuk azt a NIMClient alkalmazás Form-jára. Adjunk meg egy szöveget a komponens Text property-jében, valamint a Visible property-t állítsuk igazra. Indítsuk el a mellékelt NIMClient alkalmazást, majd kattintsunk az egér bal gombjával a kis ikonon.