DELPHI FAQ: Как свернуть прогу в tray?


Как свернуть прогу в tray?
Previous  Home  Next




Проще всего использовать RxTrayIcon компонент из библиотеки RxLib

procedure
 TForm1.ApplicationMinimize(Sender : TObject);
begin

RxTrayIcon1.Show; 
ShowWindow(Application.Handle,SW_HIDE); 
end
;

procedure
 TForm1.RxTrayIcon1Click(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin

Application.Restore; 
SetForeGroundWindow(Application.MainForm.Handle); 
RxTrayIcon1.Hide; 
end
;

Автор ответа:
Vit
Взято с Vingrad.ru http://forum.vingrad.ru



Взято с сообщения Song на другом форуме:
http://pascal.sources.ru/cgi-bin/forum/YaBB.cgi?board=delphi;action=display;num=1020241631

Нет такого понятия "свернуть в трей". Есть возможность только добавлять, удалять и менять значок в области трея. Сама же программа просто прячется.
Для изменения значка в трее используется класс TShellNotifyIcon модуля ShellApi
Объявим следующую процедруру:
Параметры к ней такие: n - номер операции ( 1 - добавить, 2 - удалить, 3 - заменить) и Icon - сама иконка с которой будет делаться эта операция

Procedure TForm1.Ic(n:Integer;Icon:TIcon);
  
Var Nim:TNotifyIconData;
begin

With Nim do 
Begin 
cbSize:=SizeOf(Nim); 
Wnd:=Form1.Handle; 
uID:=1
uFlags:=NIF_ICON or NIF_MESSAGE or NIF_TIP; 
hicon:=Icon.Handle; 
uCallbackMessage:=wm_user+1
szTip:='Хинт, который будет появляться у значка'
End
Case n OF 
1: Shell_NotifyIcon(Nim_Add,@Nim); 
2: Shell_NotifyIcon(Nim_Delete,@Nim); 
3: Shell_NotifyIcon(Nim_Modify,@Nim); 
End
end
;

Теперь, нам нужно отловить минимизацию приложения, для того, чтобы заменить стандартное действие Windows на "свёртывание в трей". Объявляем в секции protected процедуру

protected

Procedure
 ControlWindow(Var
 Msg:TMessage); message
 WM_SYSCOMMAND;
...
Procedure
 TForm1.ControlWindow(Var
 Msg:TMessage);
Begin

IF
 Msg.WParam=SC_MINIMIZE then
Begin

Ic(1
,Application.Icon); // Добавляем значок в трей
ShowWindow(Handle,SW_HIDE); // Скрываем программу

End
 
else
 
inherited
;
End
;

Теперь нам нужно, чтобы значок в трее мог реагировать на манипуляции с ним. Если Вы внимательно посмотрите процедру Ic(), то Вы увидите там ссылку на сообщение WM_USER+1. Это не что иное, как сообщение, которое приходит нам от этого значка. Обычно для значка в трее делают всплывающее меню и выводят там те или иные действия. Но TPopUpMenu делается обычно для правой кнопки, по левой же просто активируют приложение. На форму кидаем комопонент TPopUpMenu (пусть это будет PopUpMenu1) и заносим в него все пункты меню, которые мы хотим, чтобы онм появилис в меню, которое будет всплывать по нажатию правой кнопки на значке.
После этого описываем обработчик: В вышеназванную секцию protected добавляем ещё одну процедуру IconMouse, которая будет реагировать на сообщение WM_USER+1

protected 
Procedure ControlWindow(Var Msg:TMessage); message WM_SYSCOMMAND; 
Procedure IconMouse(var Msg : TMessage); message WM_USER+1
 
Теперь описываем собственно процедуру.

procedure
 TForm1.IconMouse(var Msg:TMessage);
Var p:tpoint; 
begin

GetCursorPos(p); // Запоминаем координаты курсора мыши 
Case Msg.LParam OF // Проверяем какая кнопка была нажата 
WM_LBUTTONUP,WM_LBUTTONDBLCLK: {Действия, выполняемый по одинарному или двойному щел?ку левой кнопки мыши на зна?ке. В нашем слу?ае это просто активация приложения}  
Begin  
Ic(3,Applicattion.Icon); // Удаляем зна?ок из трея 
ShowWindow(Application.Handle,SW_SHOWNORMAL); // Восстанавливаем окно программы 
End
WM_RBUTTONUP: {Действия, выполняемый по одинарному щел?ку правой кнопки мыши} 
Begin 
SetForegroundWindow(Handle); // Восстанавливаем программу в ка?естве переднего окна 
PopupMenu1.Popup(p.X,p.Y); // Заставляем всплыть тот самый TPopUp о котором я говорил ?уть раньше 
PostMessage(Handle,WM_NULL,0,0// Обнуляем сообщение 
end
End
end
;

Для выполнения пунктов всплывающего меню, пишите стандартные обработчики onClick() для его пунктов.

Данный опус писался только в форме, в IDE не тестировался . Всё работает конечно, но не обессудьте, если будут ошибочки мелкие.

Взято с Vingrad.ru http://forum.vingrad.ru




Взято из FAQ: http://blackman.km.ru/myfaq/cont4.phtml]http://blackman.km.ru/myfaq/cont4.phtml


Hаиболее часто задаваемые вопросы по SystemTary.

Hаиболее часто задаваемые вопросы по SystemTary.
Автор - Лев Серебряков (Lev Serebryakov),
2:5030/219.33@fidonet или lev@spb.runnet.ru
]
Версия 1.1 Часть 0. О чем.
Данный спиок вопросов и ответов на них содержит наиболее часто
задаваемые вопросы по использованию в своих программах для Microsoft
Windows 95 и Microsoft Windows NT 4.0 возможности оболочки, называемой
System Tray. Часть 1. Комментарий. Я хочу поблагадорить:
Andy Nicks (2:5031/16.2@Fidonet), Kirill Pushkin (2:5030/219.19),
а так же программистов петербургской фирмы " ПРОМТ" , без этих людей
вряд ли я бы написал этот FAQ. Любые пожелания, поправки, уточнения принимаются !
Распространение - свободное ! Часть 2. Версии. 19 января 1997 года - Версия 1.1, появились вопросы 11 и 12, исправлен
код в ответе на вопрос 8.
15 января 1997 года - Версия 1.0, впервые написан. Часть 3. Содержание.
Q1 Что такое System Tray ?
Q2 Как мне перенести свою программу на Tray ?
Q3 Что такое иконка на Tray ?
Q4 Как добавить иконку на Tray ?
Q5 А как ее там изменить ?
Q6 А как удалить иконку с Tray ?
Q7 Как мне узнать о воздействии мыши на иконку, находящуюся на
Tray ?
Q8 Многие программы показывают Pop-Up меню при щелчке на их иконке,
как этого добиться ?
Q9 Многие программы минимизируясь, оказываются на Tray, как это
сделать ?
Q10 Всегда ли все вышесказанное будет работать ?
Q11 А есть ли официальная информация по System Tray ?
Q12 Как сделать пункт " по умолчанию" в Pop-Up меню выделенным ? Часть 4. Собственно FAQ.
======================================================================
Q1: Что такое System Tray ? О чем идет речь ?
A1: Если Вы в операционной ситеме Windows'95 или Windows NT 4.0
пользуетесь оболочкой Explorer, то справа на TaskBar'е Вы
должны были видеть " углубленную" область в которой, обычно,
помещаются часы, переключатель клавиатуры, регулятор громкости и
некоторые другие утилиты. Они изображаются маленькими иконками и
для них существуют ToolTip'ы как для кнопок ToolBar'ов. При
щелчке или двойном щелчке по такой иконке программа обычно
выполняет действие по умолчанию, а при щелчке правой кнопкой
показывает Pop-Up меню.
Hа уровне оболочки System Tray это приложение, поддерживающее
окно, которое вы видите как " углубленную" область и некоторый
сервис для работы с этим окном.
====================================================================== Q2: Как мне перенести свою программу на Tray ?
A2: Это типичный вопрос программиста, пишущего какую-нибудь утилиту,
работающую в Background во время всей работы операционной системы
(в DOS такие утилиты делались TSR-программами). Hо вопрос
поставлен не корректно.
Обычно задавае этот вопрос программист имеет в виду примерно
следующее : " Моя программа работает [почти] все время в
минимизированном состоянии и очень жалко места под ее кнопку на
TaskBar'е. Как мне сделать, что бы при минимизации [старте|все
время] моя программа представлялась иконкой на System Tray'е и
отвечала на сообщения мыши от этой иконки ?"
Ответ на этот вопрос состоит из нескольких частей. Смотри
следующие вопросы и ответы на них.
====================================================================== Q3: Что такое иконка на System Tray ?
A3: Ответ на этот вопрос объясняет некорректность вопроса 2. Иконка
на Tray'е это просто картинка, а не окно какой-либо
программы (исследование системы с помощью Microsoft Spy++ for
Windows 95 показывает, что это не окно вообще). System Tray
отслеживает события мыши над иконкой и, в случае надобности,
показывает ToolTip для этой иконки. Так же он отсылает сообщения
о всех действиях мыши над иконкой окну, которое поместило иконку
на Tray.
Таким образом, нельзя поместить программу на Tray. Любая
программа может добавить стоько иконок на Tray, сколько ей
необходимо. При этом главное окно программы не обязано исчезать
или минимизироватся - примером может служить Microsoft Internet
Mail, помещающая иконку " конверт" на Tray в случае появления
новых писем.
====================================================================== Q4: Как добавить иконку на Tray ?
A4: Для работы с SystemTray существует всего одна функция. Вот ее
Си-прототип:
WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(
DWORD dwMessage, // message identifier
PNOTIFYICONDATA pnid // pointer to structure
);
Эта функция описана в заголовочном файле Win32-SDK " shellapi.h" ,
включаемом в программу при включении " windows.h" . Параметр
dwMessage может принимать одно из трех значений: NIM_ADD,
NIM_DELETE, NIM_MODIFY. Для добавления иконки он должен быть
установлен в NIM_ADD.
Параметр pnid имеет тип PNOTIFYDATA, который описан как:
typedef struct _NOTIFYICONDATA { // nid
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
char szTip[64];
} NOTIFYICONDATA, *PNOTIFYICONDATA;
Поля структуры NOTIFYICONDATA имеют следующий смысл:
cbSize - размер структуры, должен быть
sizeof(NOTIFYICONDATA).
hWnd - дескриптор окна, которое будет получать события
мыши над иконкой.
uID - уникальный идентификатор иконки. Идентификатор
должен быть уникален в пределах окна - обрабо-
тчика, передаваемого в hWnd.
uFlags - битовое поле, определяющее какое из следующих
полей несет действительную информацию.
Может быть одним из следующих значений: NIF_ICON,
NIF_MESSAGE, NIF_TIP или их OR-комбинацией.
uCallbackMessage - сообщение, передаваемое окну - обработчику при
событиях мыши. Желательно получать номер
сообщения вызовом RegisterWindowMessage(),
но допускаются и значения WM_USER+N, где N > 0.
hIcon - дескриптор иконки, помещаемой на Tray.
szTip - текст для ToolTip'а, если szTip[0] = 0x00, то
ToolTip'а не будет.
Таким образом, для добавления иконки на Tray необходимо
заполнить экземпляр структуры NOTIFYICONDATA и вызвать функцию
Shell_NotifyIcon() с параметром NIM_ADD и указателем на
заполненный экземпляр структуры.
При добавлении иконки необходимо заполнить поля cbSize, hWnd,
uID, uFlags, uCallbackMessage, hIcon. Поле szTip можно оставить
пустым, если вам не нужен ToolTip. Поле uFlags должно содержать
как минимум NIF_MESSAGE | NIF_ICON.
====================================================================== Q5: Я добавил иконку на Tray, а как ее там изменить ?
A5: После добавления иконки на Tray можно менять саму иконку, ToolTip
и сообщение, посылаемое окну. Для этого необходимо заполнить
экземпляр структуры NOTIFYICONDATA и вызвать функцию
Shell_NotifyIcon() с параметром NIM_MODIFY и указателем
на заполненный экземпляр структуры.
При изменении иконки необходимо заполнить поля cbSize, hWnd,
uID, uFlags и поля, отвечающие за параметры иконки, которые вы
хотите менять. При этом uFlags должен содержать комбинацию
флагов, описывающую поля, которые необходимо м
====================================================================== Q6: А как удалить иконку с Tray ?
A6: Для удаления иконки вы должны знать ее ID и дескриптор
окна-обработчика сообщений.
Для удаления иконки с Tray надо вызвать функцию
Shell_NotifyIcon() с параметром NIM_DELETE и указателем на
экземпляр структуры NOTIFYICONDATA, у которого должны быть
заполнены следующие поля: cbSize, hWnd, uID.
====================================================================== Q7: Как мне узнать о воздействии мыши на иконку, находящуюся на Tray ?
A7: При добавлении иконки на Tray вы указывали окно - обработчик
сообщения и сообщение (CallbackMessage). Теперь окно, указанное
вами будет при любых событиях мыши, происходящих над иконкой
получать сообщение, указанное при добавлении иконки. При этом
параметры lParam и wParam будут задействованы следующим образом:
(UINT)wParam - содержит ID иконки, над которой произошло
событие
(UINT)lParam - содержит стандартное событие мыши, такое
как WM_MOUSEMOVE или WM_LBUTTONDOWN.
При этом, информация о клавишах смены регистра, так же как и
местоположения события, передаваемые при стандартных " настоящих"
сообщениях мыши, теряются.
Hо положение курсора можно узнать функцией GetCursorPos(), а
состояние клавиш смены регистра - функцией GetKeyState(),
описанных в winuser.h.
====================================================================== Q8: Многие программы показывают Pop-Up меню при щелчке на их иконке,
помещенной на Tray, как этого добиться ?
A8: Вы должны обрабатывать сообщение, указанное вами при добавлении
иконки на Tray. При значении (UINT)lParam, равном WM_RBUTTONDOWN
(это обычно дял Pop-Up меню по правой кнопке), или любому другому
необходимому вам, вы должны вызовом функции GetCursorPos()
получить позицию курсора в момент события (вряд ли пользователь
успеет убрать мышь за время обработки сообщения, особенно если
он ожидает меню), получить вескриптор Pop-Up меню одним из многих
способов (LoadMenu(), GetSubMenu(), CreateMenu(), и т.д.) и
выполнить следующий код: SetForegroundWindow(hWnd);
TrackPopupMenuEx(hMenu,TPM_HORIZONTAL|TPM_LEFTALIGN,x, y,hWnd,
NULL);
DestroyMenu(hMenu);
PostMessage(hWnd,WM_USER,0,0); где hWnd - дескриптор окна, которое будет обрабатывать команду
меню, hMenu - дескриптор меню, x и y - позиция курсора. Для
подробностей смотрите Win32 SDK Help по функции TrackPopupMenuEx.
====================================================================== Q9: Многие программы минимизируясь, оказываются на Tray, как это
сделать ?
A9: Hа самом деле, не " программа оказывается на Tray" , а только
иконка помещается на Tray, а главное окно программы скрывается.
Для достижения такого результата вам надо обрабатывать сообщение
WM_SIZE, и при значении wParam, равном SIZE_MINIMIZED вы должны
выполнить примерно следующую последовательность действий:
добавить иконку на Tray и скрыть окно - вызвать ShowIndow(hWnd,
SW_HIDE).
Когда произойдет действие, которое должго активировать вашу
программу - WM_LBUTTONDBLCLK или WM_LBUTTONDOWN (или то, что
нравится вам), вы должны удалить иконку и вызвать
ShowWindow(hWnd,SW_SHOW) или ShowWindow(hWnd,SW_SHOWMAXIMIZED).
====================================================================== Q10: Всегда ли все вышесказанное будет работать ?
A10: Hет ! Все вышенаписанное работает только при использовании в
операционных системах Windows 95 и Windows NT 4.0 оболочки
Explorer, и при разрешенном System Tray. В случае, если не
происходит запуска systray.exe (запускаетс автоматически
Explorer'ом при старте) или используется другая оболочка
(DashBoard, Program Manager, File Manager), функция
Shell_NotifyIcon() будет возвращать при вызове FALSE и не
выполнять ни каких действий.
Еще раз повторю: System Tray - это возможность оболочки, а не
операционной системы !
====================================================================== Q11: А есть ли официальная информация по System Tray ?
A11: Да, есть. Есть маленький пример в Win32 SDK:
SDKRoot\Samples\Win32\Win95\TrayNot\*.*
Hу и конечно описание в документации функции Shell_NotifyIcon()
и структуры NOTIFYICONDATA.
Так же можно посмотреть Microsoft Knowledge Base:
PSS ID Number: Q128129
PSS ID Number: Q134237
PSS ID Number: Q139408
====================================================================== Q12: Как сделать пункт " по умолчанию" в Pop-Up меню выделенным ?
A12: Вообще-то, это вопрос не относящийся к System Tray, а
относящийся к меню. Hо можно ответить и на него.
Устанавливается пункт " по умолчанию" в любом меню функцией API
SetMenuDefaultItem(HMENU hMenu, UINT uItem, UINT fByPos),
подробности - в Win32 SDK документации. Пункт " По умолчанию" не
влияет на работу меню - это чисто интерфейсное выделение пункта
меню полужирным (bold) шрифтом.

Взято с Vingrad.ru http://forum.vingrad.ru








DELPHI FAQ




EOMY TOP 100      Рейтинг@Mail.ru      Rambler's Top100