Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[52.14.84.137] |
|
Сообщ.
#1
,
|
|
|
Нет такого понятия "свернуть в трей". Есть возможность только добавлять, удалять и менять значок в области трея. Сама же программа просто прячется и/или минимизируется.
Для работы со значками в трее используется функция Shell_NotifyIcon, объявленная в модуле 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); // Скрываем программу ShowWindow(Application.Handle,SW_HIDE); // Скрываем кнопку с TaskBar'а End else inherited; End; Итак, теперь наш обработчик ловит сообщение о минимизации и прячет нашу прогу в трей. Однако ловит не всегда. Попробуем, например, выбрать из системного меню команду Minimize или нажать на кнопку окна в панели задач, и что же? Не срабатывает! Поэтому, нам нужно ещё переопределить обработчик onMinimize класса TApplication: Procedure TForm1.OnMinimizeProc(Sender:TObject); Begin PostMessage(Handle,WM_SYSCOMMAND,SC_MINIMIZE,0); End; и не забудем присвоить эту процедуру: Procedure TForm1.Form1Create(Sender:TObject); Begin Application.onMinimize:=OnMinimizeProc; End; Теперь поясню как работает. Когда приложение минимизируется, но эта минимизация не перехватывается нашим обработчиком WM_SYSCOMMAND, мы перехватываем минимизацию в процедуре OnMinimizeProc и принудительно передаём сообщение о минимизации нашей форме, где оно и будет успешно отловлено нашим обработчиком сообщения WM_SYSCOMMAND, благодаря которому прога и "сворачивается" успешно в трей и в этом случае. Теперь нам нужно, чтобы значок в трее мог реагировать на манипуляции с ним. Если Вы внимательно посмотрите процедру 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(2,Application.Icon); // Удаляем значок из трея ShowWindow(Application.Handle,SW_SHOW); // Восстанавливаем кнопку программы ShowWindow(Handle,SW_SHOW); // Восстанавливаем окно программы End; WM_RBUTTONUP: {Действия, выполняемый по одинарному щелчку правой кнопки мыши} Begin SetForegroundWindow(Handle); // Восстанавливаем программу в качестве переднего окна PopupMenu1.Popup(p.X,p.Y); // Заставляем всплыть тот самый TPopUp о котором я говорил чуть раньше PostMessage(Handle,WM_NULL,0,0); end; End; end; Для выполнения пунктов всплывающего меню, пишите стандартные обработчики onClick() для его пунктов. Данный опус писался только в форме, в IDE не тестировался, но работоспособный на 100%. Всё работает конечно, но не обессудьте, если будут ошибочки мелкие. |