<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=8557&amp;view=findpost&amp;p=86360</guid>
        <pubDate>Thu, 06 Nov 2003 06:25:31 +0000</pubDate>
        <title>&amp;quot;Свернуть&amp;quot; программу в трей</title>
        <link>https://forum.sources.ru/index.php?showtopic=8557&amp;view=findpost&amp;p=86360</link>
        <description><![CDATA[Song: Нет такого понятия &quot;свернуть в трей&quot;. Есть возможность только <strong class='tag-b'>добавлять, удалять и менять значок в области трея.</strong> Сама же программа просто прячется и/или минимизируется.<br>
Для работы со значками в трее используется функция Shell_NotifyIcon, объявленная в  модуле ShellApi.<br>
<br>
Объявим следующую процедруру:<br>
Параметры к ней такие: n - номер операции ( 1 - добавить, 2 - удалить, 3 - заменить) и Icon - сама иконка с которой будет делаться эта операция<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Procedure TForm1.Ic(n:Integer;Icon:TIcon);</div><div class="code_line">Var Nim:TNotifyIconData;</div><div class="code_line">begin</div><div class="code_line">&nbsp;With Nim do</div><div class="code_line">&nbsp; Begin</div><div class="code_line">&nbsp;  cbSize:=SizeOf(Nim);</div><div class="code_line">&nbsp;  Wnd:=Form1.Handle;</div><div class="code_line">&nbsp;  uID:=1;</div><div class="code_line">&nbsp;  uFlags:=NIF_ICON or NIF_MESSAGE or NIF_TIP;</div><div class="code_line">&nbsp;  hicon:=Icon.Handle;</div><div class="code_line">&nbsp;  uCallbackMessage:=wm_user+1;</div><div class="code_line">&nbsp;  szTip:=&#39;Хинт, который будет появляться у значка&#39;;</div><div class="code_line">&nbsp; End;</div><div class="code_line">&nbsp;Case n OF</div><div class="code_line">&nbsp; 1: Shell_NotifyIcon(Nim_Add,@Nim);</div><div class="code_line">&nbsp; 2: Shell_NotifyIcon(Nim_Delete,@Nim);</div><div class="code_line">&nbsp; 3: Shell_NotifyIcon(Nim_Modify,@Nim);</div><div class="code_line">&nbsp;End;</div><div class="code_line">end;</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<br>
Теперь, нам нужно отловить минимизацию приложения, для того, чтобы заменить стандартное действие Windows на &quot;свёртывание в трей&quot;. Объявляем в секции protected процедуру<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">protected</div><div class="code_line">&nbsp;Procedure ControlWindow(Var Msg:TMessage); message WM_SYSCOMMAND;</div><div class="code_line">&nbsp;</div><div class="code_line">...</div><div class="code_line">&nbsp;</div><div class="code_line">Procedure TForm1.ControlWindow(Var Msg:TMessage);</div><div class="code_line">Begin</div><div class="code_line">&nbsp;IF Msg.WParam=SC_MINIMIZE then</div><div class="code_line">&nbsp; Begin</div><div class="code_line">&nbsp;  Ic(1,Application.Icon);  // Добавляем значок в трей</div><div class="code_line">&nbsp;  ShowWindow(Handle,SW_HIDE);  // Скрываем программу</div><div class="code_line">&nbsp;  ShowWindow(Application.Handle,SW_HIDE);  // Скрываем кнопку с TaskBar&#39;а</div><div class="code_line">&nbsp;End else inherited;</div><div class="code_line">End;</div></ol></div></div></div></div><br>
<br>
Итак, теперь наш обработчик ловит сообщение о минимизации и прячет нашу прогу в трей. Однако ловит не всегда. Попробуем, например, выбрать из системного меню команду Minimize или нажать на кнопку окна в панели задач, и что же? Не срабатывает&#33;<br>
Поэтому, нам нужно ещё переопределить обработчик onMinimize класса TApplication:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Procedure TForm1.OnMinimizeProc(Sender:TObject);</div><div class="code_line">Begin</div><div class="code_line">&nbsp;PostMessage(Handle,WM_SYSCOMMAND,SC_MINIMIZE,0);</div><div class="code_line">End;</div></ol></div></div></div></div><br>
<br>
и не забудем присвоить эту процедуру:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Procedure TForm1.Form1Create(Sender:TObject);</div><div class="code_line">Begin</div><div class="code_line">&nbsp;Application.onMinimize:=OnMinimizeProc;</div><div class="code_line">End;</div></ol></div></div></div></div><br>
<br>
Теперь поясню как работает. Когда приложение минимизируется, но эта минимизация не перехватывается нашим обработчиком WM_SYSCOMMAND, мы перехватываем минимизацию в процедуре OnMinimizeProc и <strong class='tag-b'>принудительно</strong> передаём сообщение о минимизации нашей форме, где оно и будет успешно отловлено нашим обработчиком сообщения WM_SYSCOMMAND, благодаря которому прога и &quot;сворачивается&quot; успешно в трей и в этом случае.<br>
<br>
Теперь нам нужно, чтобы значок в трее мог реагировать на манипуляции с ним. Если Вы внимательно посмотрите процедру Ic(), то Вы увидите там ссылку на сообщение WM_USER+1. Это не что иное, как сообщение, которое приходит нам от этого значка. Обычно для значка в трее делают всплывающее меню и выводят там те или иные действия. Но TPopUpMenu делается обычно для правой кнопки, по левой же просто активируют приложение. На форму кидаем комопонент TPopUpMenu (пусть это будет PopUpMenu1) и заносим в него все пункты меню, которые мы хотим, чтобы онм появилис в меню, которое будет всплывать по нажатию правой кнопки на значке.<br>
После этого описываем обработчик: В вышеназванную секцию protected добавляем ещё одну процедуру IconMouse, которая будет реагировать на сообщение WM_USER+1<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">protected</div><div class="code_line">&nbsp;Procedure ControlWindow(Var Msg:TMessage); message WM_SYSCOMMAND;</div><div class="code_line">&nbsp;Procedure IconMouse(var Msg:TMessage); message WM_USER+1;</div></ol></div></div></div></div><br>
<br>
Теперь описываем собственно процедуру.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">procedure TForm1.IconMouse(var Msg:TMessage);</div><div class="code_line">Var p:tpoint;</div><div class="code_line">begin</div><div class="code_line">&nbsp;GetCursorPos(p); // Запоминаем координаты курсора мыши</div><div class="code_line">&nbsp;Case Msg.LParam OF  // Проверяем какая кнопка была нажата</div><div class="code_line">&nbsp; WM_LBUTTONUP,WM_LBUTTONDBLCLK: {Действия, выполняемый по одинарному или двойному щелчку левой кнопки мыши на значке. В нашем случае это просто активация приложения} </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Begin </div><div class="code_line">&nbsp;                   Ic(2,Application.Icon);  // Удаляем значок из трея</div><div class="code_line">&nbsp;                   ShowWindow(Application.Handle,SW_SHOW); // Восстанавливаем кнопку программы</div><div class="code_line">&nbsp;                   ShowWindow(Handle,SW_SHOW); // Восстанавливаем окно программы</div><div class="code_line">&nbsp;                  End;</div><div class="code_line">&nbsp; WM_RBUTTONUP: {Действия, выполняемый по одинарному щелчку правой кнопки мыши}</div><div class="code_line">&nbsp;  Begin</div><div class="code_line">&nbsp;   SetForegroundWindow(Handle);  // Восстанавливаем программу в качестве переднего окна</div><div class="code_line">&nbsp;   PopupMenu1.Popup(p.X,p.Y);  // Заставляем всплыть тот самый TPopUp о котором я говорил чуть раньше</div><div class="code_line">&nbsp;   PostMessage(Handle,WM_NULL,0,0);</div><div class="code_line">&nbsp;  end;</div><div class="code_line">&nbsp;End;</div><div class="code_line">end;</div></ol></div></div></div></div><br>
Для выполнения пунктов всплывающего меню, пишите стандартные обработчики onClick() для его пунктов.<br>
 <br>
Данный опус писался только в форме, в IDE не тестировался, но работоспособный на 100%. :) Всё работает конечно, но не обессудьте, если будут ошибочки мелкие.]]></description>
        <author>Song</author>
        <category>Hello, World&#33;</category>
      </item>
	
      </channel>
      </rss>
	