API
16.08.1999
  • Zarządzanie ikonką obok zegara.

       W następujący sposób możesz umieścić ikonkę w SysTray'u (obok zegara na pasku zadań): użyj gotowego komponentu (np. z RX Library) albo wywołaj funkcję API Shell_NotifyIcon. Ikonę z paska zadań ukryjesz funkcją API ShowWindow.

       Jeżeli chcesz, żeby ikona pojawiała się po minimalizacji programu, musisz stworzyć zdarzenie OnMinimize dla obiektu TApplication, które ukryje główną formę i ikonę programu z paska zadań. Jeżeli natomiast program ma pokazywać ikonkę po "zamknięciu", musisz przenieść kod do handlera OnClose.

       Poniższy kod demonstruje "zamykanie" programu do ikonki w SysTray'u. Program pozostaje normalnie ukryty, dopóki użytkownik nie kliknie dwa razy na ikonkę. Wtedy pojawia się główna forma. Gotowy projekt (a także projekt w którym program minimalizuje się do SysTray'u) możesz ściągnąć tutaj (BCB4).

Uwaga: W przykładzie tym forma zawiera przycisk i rozwijane menu. Rozwijane menu ma jedną pozycję - zakończ. Przycisk i pozycja menu dzielą ten sam handler OnClick.

//-------------------------------------------------------
// MAINFORM.H
//-------------------------------------------------------

//----------------------------------------------
#ifndef mainformH
#define mainformH
//----------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Menus.hpp>
//----------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE-managed Components
    TPopupMenu *PopupMenu1;
    TMenuItem *Unload1;
    TButton *UnloadBtn;
    void __fastcall UnloadBtnClick(TObject *Sender);
    void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
private:	// User declarations
    Graphics::TIcon *TrayIcon;
    void __fastcall WMTrayNotify(TMessage &Msg);
    void __fastcall RemoveIcon();
    void __fastcall AddIcon();

public:		// User declarations
    __fastcall TForm1(TComponent* Owner);
    __fastcall ~TForm1();

BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(WM_TRAYNOTIFY,TMessage,WMTrayNotify)
END_MESSAGE_MAP(TForm)
};
//----------------------------------------------
extern PACKAGE TForm1 *Form1;
//----------------------------------------------
#endif

//-------------------------------------------------------
// MAINFORM.CPP
//-------------------------------------------------------

//----------------------------------------------
#include <vcl.h>
#pragma hdrstop
//Pierwsza stała to numer ID ikonki. Wartość jest przypadkowa
//Jeżeli Twój program wyświetla więcej niż jedną na raz
//to musisz każdej ikonce przypisać inny numer.
//Stała char* zawiera tekst jaki pojawi się po najechaniu
//myszką na ikonkę.
//Ostatnia stała to zdefiniowany przez użytkownika komunikat
//który zostanie wysłany do naszego okna przy zdarzeniu dotyczącym
//naszej ikonki

const int IDC_TRAY1      = 1005;
const char *HINT_MESSAGE = "Tekst nad ikonką";
const int WM_TRAYNOTIFY  = WM_USER + 1001;

#include 
#include "mainform.h"
//----------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//----------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    // Ładuje ikonkę z pliku RES
    TrayIcon = new Graphics::TIcon;
    TrayIcon->Handle=LoadImage(HInstance,
                              "LITTLEICON",
                              IMAGE_ICON,
                              0,0,
                              0);

    // Wyświetla ikonkę obok zegara
    AddIcon();
}
//----------------------------------------------
__fastcall TForm1::~TForm1()
{
    // Usuwa ikonkę i kasuje wskaźnik TIcon, który stworzyliśmy
    RemoveIcon();
    delete TrayIcon;
}

void __fastcall TForm1::WMTrayNotify(TMessage &Msg)
{
        //LParam określa typ komunikatu.
        //Przy naciśnięciu prawego przycisku pokazuje się menu.
        //Podwójne kliknięcie lewym powoduje pokazanie formy i
        //ukrycie ikonki.

    switch(Msg.LParam)
    {
        case WM_RBUTTONUP:
  // kiedy prawy klawisz zostanie zwolniony pobiera pozycję kursora
  // i wyświetla menu. SetForegroundWindow i PostMessage naprawiają
  // błąd systemu operacyjnego.
            POINT WinPoint;
            GetCursorPos(&WinPoint);
            SetForegroundWindow(Handle);
            PopupMenu1->Popup(WinPoint.x,WinPoint.y);
            PostMessage(Handle, WM_NULL, 0,0);
            break;
        case WM_LBUTTONDBLCLK:
            RemoveIcon();
            ShowWindow(Application->Handle, SW_SHOW);
            Visible = true;
            break;
    }
}

//----------------------------------------------
void __fastcall TForm1::UnloadBtnClick(TObject *Sender)
{
    // kończy program po naciśnięciu "Zakończ"
    Application->Terminate();
}

void __fastcall TForm1::AddIcon()
{
    // używa funkcji Shell_NotifyIcon
    // żeby dodać ikonkę do SysTray.
    NOTIFYICONDATA IconData;
    IconData.cbSize = sizeof(NOTIFYICONDATA);
    IconData.uID    = IDC_TRAY1;
    IconData.hWnd   = Handle;
    IconData.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
    IconData.uCallbackMessage = WM_TRAYNOTIFY;
    lstrcpy(IconData.szTip, HINT_MESSAGE);
    IconData.hIcon  = TrayIcon->Handle;

    Shell_NotifyIcon(NIM_ADD,&IconData);
}

void __fastcall TForm1::RemoveIcon()
{
    NOTIFYICONDATA IconData;
    IconData.cbSize = sizeof(NOTIFYICONDATA);
    IconData.uID    = IDC_TRAY1;
    IconData.hWnd   = Handle;
    IconData.hIcon  = TrayIcon->Handle;

    Shell_NotifyIcon(NIM_DELETE,&IconData);
}

//----------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender,
                                  TCloseAction &Action)
{
 // Przy próbie zamknięcia aplikacji, ukryta zostaje główna forma,
 // w SysTray zostaje umieszczona ikonka, a program dalej działa.
    if(!Application->Terminated)
    {
        AddIcon();
        ShowWindow(Application->Handle, SW_HIDE);
        Visible = false;
        Action = caNone;
    }
}
//----------------------------------------------

//-------------------------------------------------------
// TRAY.CPP
//-------------------------------------------------------

//----------------------------------------------
#include <vcl.h>
#pragma hdrstop
USERES("tray.res");
USEFORM("mainform.cpp", Form1);
USERES("TRAYICON.res");
//----------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    try
    {
        Application->Initialize();
        Application->CreateForm(__classid(TForm1), &Form1);
        ShowWindow(Application->Handle,SW_HIDE);
        Application->MainForm->Visible = false;
        Application->ShowMainForm = false;

        Application->Run();
    }
    catch (Exception &exception)
    {
         Application->ShowException(&exception);
    }
    return 0;
}
//----------------------------------------------