15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Как скрыть форму в System Tray.

Компилятор: C++ Builder

На самом деле программа не скрывается в системном трее, а просто делается невидимой и помещает свою иконку рядом с системными часиками. Иконка в System Tray добавляется при помощи API функции Shell_NotifyIcon либо при помощи готовых компонентов, а само приложение можно скрыть при помощи API функции ShowWindow.

Сам код скрытия программы в системный трей можно добавить в событие OnMinimize объекта TApplication либо в событие OnClose, в зависимости от того как Вы хотите скрывать главную форму - при минимизации или при закрытии.

Ниже приведён пример, который скрывает главную форму в системный трей при закрытии формы. Приложение продолжает нормально работать до тех пор, пока пользователь не сделает двойной клик по иконке. Главная форма содержит кнопку и всплывающее меню. Меню имеет всего один пункт с названием. Кнопка и пункт меню unload имеют один и тот же обработчик события OnClick.

//-------------------------------------------------------
// MAINFORM.H
//-------------------------------------------------------
#ifndef mainformH
#define mainformH
//-------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Menus.hpp>
//-------------------------------------------------------

#define WM_TRAYNOTIFY  (WM_USER + 1001)

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

// Первая константа, это ID иконки. Константа char * это текст.
// встплывающей подсказки для иконки.
const int IDC_TRAY1      = 1005;
const char *HINT_MESSAGE = "Tray Hint Message";

#include <shellapi.h>
#include "mainform.h"
//-------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//-------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    // Загружаем иконку из ресурсов
    TrayIcon = new Graphics::TIcon;
    TrayIcon->Handle=LoadImage(HInstance,
                              "LITTLEICON",
                              IMAGE_ICON,
                              0,0,
                              0);

    // Добавляем иконку
    AddIcon();
}
//-------------------------------------------------------
__fastcall TForm1::~TForm1()
{
    // Убираем иконку из трея, и удаляем указатель
    // TIcon, который был создан изначально.
    RemoveIcon();
    delete TrayIcon;
}
//-------------------------------------------------------
void __fastcall TForm1::WMTrayNotify(TMessage &Msg)
{
    // Параметр LPARAM указывает на тип сообщения мышки.
    // При клике правой кнопкой, показываем меню. При двойном клике
    // левой кнопкой, показываем форму.
    switch(Msg.LParam)
    {
        case WM_RBUTTONUP:
            // Получаем координаты курсора мышки и показываем в этом
            // месте всплывающее меню.
            POINT WinPoint;
            GetCursorPos(&WinPoint);
            SetForegroundWindow(Handle);
            PopupMenu1->Popup(WinPoint.x,WinPoint.y);
            PostMessage(Handle, WM_NULL, 0,0);
            break;
        case WM_LBUTTONDBLCLK:
            Visible = true;
            ShowWindow(Application->Handle, SW_SHOW);
            break;
    }
}
//-------------------------------------------------------
void __fastcall TForm1::UnloadBtnClick(TObject *Sender)
{
    // Завершаем приложение при нажатии на специальную кнопку
    Application->Terminate();
}
//-------------------------------------------------------
void __fastcall TForm1::AddIcon()
{
    // Добавляем иконку рядом с ситемными часиками
    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)
{
    // При нажатии на кнопку закрытия приложения, оно станет невидимым
    // однако останется полностью работоспособным.
    if(!Application->Terminated)
    {
        ShowWindow(Application->Handle, SW_HIDE);
        Visible = false;
        Action = caNone;
    }
}
//-------------------------------------------------------



//-------------------------------------------------------
// TRAY.CPP Project Source
//-------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
USERES("tray.res");
USEFORM("mainform.cpp", Form1);

// TrayIcons.res содержит иконку для системного трея.
USERES("TRAYICONS.res");
//-------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    try
    {
        Application->Initialize();
        Application->CreateForm(__classid(TForm1), &Form1);

        // скрываем иконку главной формы в панели задач
        ShowWindow(Application->Handle,SW_HIDE);
        Application->ShowMainForm = false;

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

 

Скачать исходник - 6 Кб