Добро пожаловать! Это — архивная версия форумов на «Хакер.Ru». Она работает в режиме read-only.
 

Программа в трее (DELPHI)

Пользователи, просматривающие топик: none

Зашли как: Guest
Все форумы >> [Компилируемые языки] >> Программа в трее (DELPHI)
Имя
Сообщение << Старые топики   Новые топики >>
Программа в трее (DELPHI) - 2007-07-12 21:37:33.493333   
Cannibal666

Сообщений: 59
Оценки: 0
Присоединился: 2007-01-09 19:18:48.060000
Я начинаю програмировать , поэтому мой вопрос может показаться туповатым , и всё-же…
Как в делфи реализовать такие возможности:
1) Окно программы на рабочем столе и эту программу не показывает панель задач и трэй?
2) Окно программы на рабочем столе и её значок в трее?
3) Окно программы на рабочем столе и эту программу не показывает панель задач и эту программу можно свернуть в трэй?
Если можно напишите примеры (листинги) . За помощь буду благодарен!!!!!!!!!!!
Например вот для этой программы "Часы"
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)

    Label1: TLabel;
    Timer1: TTimer;
    procedure ShowTime;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ShowTime;
var
Time: TDateTime;
begin
Time := Now();
Label1.Caption := FormatDateTime('hh:mm:ss',Time);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
ShowTime;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Timer1.Interval := 1000;
Timer1.Enabled := True;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
ShowTime;
end;

end.
Post #: 1
RE: Программа в трее (DELPHI) - 2007-07-13 12:39:16.536666   
blacksun

Сообщений: 2360
Оценки: 0
Присоединился: 2006-09-27 03:05:59.350000
quote:


Что такое System Tray? О чем идет речь?

Если Вы в операционной ситеме Windows'95 или Windows NT 4.0 пользуетесь оболочкой Explorer, то справа на TaskBar'е Вы должны были видеть "углубленную" область в которой, обычно, помещаются часы, переключатель клавиатуры, регулятор громкости и некоторые другие утилиты.

Они изображаются маленькими иконками и для них существуют ToolTip'ы как для кнопок ToolBar'ов. При щелчке или двойном щелчке по такой иконке программа обычно выполняет действие по умолчанию, а при щелчке правой кнопкой показывает Pop-Up меню. Hа уровне оболочки System Tray это приложение, поддерживающее окно, которое вы видите как "углубленную" область и некоторый сервис для работы с этим окном.

Как мне перенести свою программу на Tray?

Это типичный вопрос программиста, пишущего какую-нибудь утилиту, работающую в Background во время всей работы операционной системы (в DOS такие утилиты делались TSR-программами). Hо вопрос поставлен не корректно. Обычно задавает этот вопрос программист имеет в виду примерно следующее : "Моя программа работает [почти] все время в минимизированном состоянии и очень жалко места под ее кнопку на TaskBar'е. Как мне сделать, что бы при минимизации [старте|все время] моя программа представлялась иконкой на System Tray'е и отвечала на сообщения мыши от этой иконки ?" Ответ на этот вопрос состоит из нескольких частей.

Что такое иконка на System Tray?

Ответ на этот вопрос объясняет некорректность вопроса 2. Иконка на Tray'е это просто картинка, а не окно какой-либо программы (исследование системы с помощью Microsoft Spy++ for Windows 95 показывает, что это не окно вообще). System Tray отслеживает события мыши над иконкой и, в случае надобности, показывает ToolTip для этой иконки. Так же он отсылает сообщения о всех действиях мыши над иконкой окну, которое поместило иконку на Tray. Таким образом, нельзя поместить программу на Tray. Любая программа может добавить столько иконок на Tray, сколько ей необходимо. При этом главное окно программы не обязано исчезать или минимизироваться - примером может служить Microsoft Internet Mail, помещающая иконку "конверт" на Tray в случае появления новых писем.

Как добавить иконку на Tray?

Для работы с 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 &gt; 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.

Я добавил иконку на Tray, а как ее там изменить?

После добавления иконки на Tray можно менять саму иконку, ToolTip и сообщение, посылаемое окну. Для этого необходимо заполнить экземпляр структуры NOTIFYICONDATA и вызвать функцию Shell_NotifyIcon() с параметром NIM_MODIFY и указателем на заполненный экземпляр структуры.

При изменении иконки необходимо заполнить поля cbSize, hWnd, uID, uFlags и поля, отвечающие за параметры иконки, которые вы хотите менять. При этом uFlags должен содержать комбинацию флагов, описывающую поля, которые необходимо менять.

А как удалить иконку с Tray?

Для удаления иконки вы должны знать ее ID и дескриптор окна-обработчика сообщений.

Для удаления иконки с Tray надо вызвать функцию Shell_NotifyIcon() с параметром NIM_DELETE и указателем на экземпляр структуры NOTIFYICONDATA, у которого должны быть заполнены следующие поля: cbSize, hWnd, uID.

Как мне узнать о воздействии мыши на иконку, находящуюся на Tray?

При добавлении иконки на Tray вы указывали окно - обработчик сообщения и сообщение (CallbackMessage). Теперь окно, указанное вами будет при любых событиях мыши, происходящих над иконкой получать сообщение, указанное при добавлении иконки. При этом параметры lParam и wParam будут задействованы следующим образом:

(UINT)wParam
содержит ID иконки, над которой произошло событие
(UINT)lParam
содержит стандартное событие мыши, такое как WM_MOUSEMOVE или WM_LBUTTONDOWN.
При этом, информация о клавишах смены регистра, так же как и местоположения события, передаваемые при стандартных "настоящих" сообщениях мыши, теряются.

Hо положение курсора можно узнать функцией GetCursorPos(), а состояние клавиш смены регистра - функцией GetKeyState(), описанных в winuser.h.

Многие программы показывают Pop-Up меню при щелчке на их иконке, помещенной на Tray, как этого добиться?

Вы должны обрабатывать сообщение, указанное вами при добавлении иконки на 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.

Многие программы минимизируясь, оказываются на Tray, как это сделать?

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).

Всегда ли все вышесказанное будет работать?

Hет ! Все вышенаписанное работает только при использовании в операционных системах Windows 95 и Windows NT 4.0 оболочки Explorer, и при разрешенном System Tray. В случае, если не происходит запуска systray.exe (запускаетс автоматически Explorer'ом при старте) или используется другая оболочка (DashBoard, Program Manager, File Manager), функция Shell_NotifyIcon() будет возвращать при вызове FALSE и не выполнять ни каких действий.

Еще раз повторю: System Tray - это возможность оболочки, а не операционной системы !

А есть ли официальная информация по System Tray?

Да, есть. Есть маленький пример в 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
Как сделать пункт "по умолчанию" в Pop-Up меню выделенным?

Вообще-то, это вопрос не относящийся к System Tray, а относящийся к меню. Hо можно ответить и на него.

Устанавливается пункт "по умолчанию" в любом меню функцией API SetMenuDefaultItem(HMENU hMenu, UINT uItem, UINT fByPos), подробности - в Win32 SDK документации. Пункт "По умолчанию" не влияет на работу меню - это чисто интерфейсное выделение пункта меню полужирным (bold) шрифтом.



А вот те пример:

quote:


const WM_NOTIFYTRAYICON = WM_USER + 1; ... private procedure WMTRAYICONNOTIFY(var Msg: TMessage); message WM_NOTIFYTRAYICON; ... uses ShellAPI; procedure TForm1.WMTRAYICONNOTIFY(var Msg: TMessage); var s: string; begin case Msg.LParam of WM_MOUSEMOVE: s := 'Мышь сдвинута'; WM_LBUTTONDOWN: s := 'Левая кнопка нажата'; WM_LBUTTONUP: s := 'Левая кнопка отпущена'; WM_LBUTTONDBLCLK: s := 'Два раза нажата левая кнопка'; WM_RBUTTONDOWN: s := 'Правая кнопка нажата'; WM_RBUTTONUP: s := 'Правая кнопка отпущена'; WM_RBUTTONDBLCLK: s := 'Два раза нажата правая кнопка'; else s := IntToStr(Msg.LParam); end; ListBox1.Items.Add(s); ListBox1.ItemIndex := ListBox1.Items.Count - 1; end; procedure TForm1.FormCreate(Sender: TObject); var tray: TNotifyIconData; Ic: TIcon; begin Ic := TIcon.Create; Ic.LoadFromFile('Icon1.ico'); with tray do begin cbSize := SizeOf(TNotifyIconData); Wnd := Form1.Handle; uID := 1; uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP; uCallBackMessage := WM_NOTIFYTRAYICON; hIcon := Ic.Handle; szTip := ('Это наша иконка'); end; Shell_NotifyIcon(NIM_ADD, Addr(tray)); Ic.Destroy; end; procedure TForm1.Button1Click(Sender: TObject); var tray: TNotifyIconData; Ic: TIcon; begin Ic := TIcon.Create; Ic.LoadFromFile('Icon2.ico'); with tray do begin cbSize := SizeOf(TNotifyIconData); Wnd := Form1.Handle; uID := 1; uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP; uCallBackMessage := WM_NOTIFYTRAYICON; hIcon := Ic.Handle; szTip := ('Это другая иконка'); end; Shell_NotifyIcon(NIM_MODIFY, Addr(tray)); Ic.Destroy; end; procedure TForm1.FormDestroy(Sender: TObject); var tray: TNotifyIconData; begin with tray do begin cbSize := SizeOf(TNotifyIconData); Wnd := Form1.Handle; uID := 1; end; Shell_NotifyIcon(NIM_DELETE, Addr(tray)); end;


И запомни адрес http://google.ru
Post #: 2
RE: Программа в трее (DELPHI) - 2007-07-13 18:52:59.726666   
Cannibal666

Сообщений: 59
Оценки: 0
Присоединился: 2007-01-09 19:18:48.060000
Благодарю за ответ ,но нельзя-ли объяснить про DELPHI программы ; Кстати я работаю на "XP" .
Post #: 3
RE: Программа в трее (DELPHI) - 2007-07-13 19:19:10.473333   
blacksun

Сообщений: 2360
Оценки: 0
Присоединился: 2006-09-27 03:05:59.350000
Баш отдыхает … в палату)
Post #: 4
RE: Программа в трее (DELPHI) - 2007-07-13 21:34:08.900000   
Cannibal666

Сообщений: 59
Оценки: 0
Присоединился: 2007-01-09 19:18:48.060000
Я Чего-то не понял……
Post #: 5
RE: Программа в трее (DELPHI) - 2007-07-13 22:32:36.216666   
A_Tolstoy

Сообщений: 71
Оценки: 0
Присоединился: 2005-11-29 19:22:37
Если бы ты понял вот это :
quote:

Благодарю за ответ ,но нельзя-ли объяснить про DELPHI программы ; Кстати я работаю на "XP"

Было бы странно помойму ;)
Post #: 6
RE: Программа в трее (DELPHI) - 2007-07-16 10:11:30.806666   
Black.Line

Сообщений: 20
Оценки: 0
Присоединился: 2007-07-16 09:45:41.086666
1) Окно программы на рабочем столе и эту программу не показывает панель задач и трэй?
ShowWindow(handle, SW_HIDE);

2) Окно программы на рабочем столе и её значок в трее?
TTrayIcon компонент ищи. torry.net тебе в помощь
Post #: 7
RE: Программа в трее (DELPHI) - 2007-07-16 12:08:25.573333   
Mike3000

Сообщений: 25
Оценки: 0
Присоединился: 2006-03-06 12:19:46
Объявляешь //TrayBar type TIconType=(None,Info,Warn,Err); const WM_MYICONNOTIFY=WM_USER+123; NIF_INFO=$00000010; NIIF_NONE=$00000000; NIIF_INFO=$00000001; NIIF_WARNING=$00000002; NIIF_ERROR=$00000003; uIcon_ID: UINT=1; IconTypes: array[TIconType] of byte=(NIIF_NONE,NIIF_INFO,NIIF_WARNING,NIIF_ERROR); const RestoreMessage: TMessage=(LParam: WM_LBUTTONUP); //Возвращает форму из трея //procedure WMICON(var msg: TMessage); message WM_MYICONNOTIFY; - это надо добавить в начало! //procedure TfMain.WMICON(var msg: TMessage); //begin tray_ShowForm(msg); end;//WMICON //tray_ShowForm(fMirror,RestoreMessage,true,pmMirror); procedure tray_ShowForm(Msg: TMessage; HideIcon: Boolean=true; PopupMenu: TPopupMenu=nil); //Сворачивает Форму на трей //procedure WMSYSCOMMAND(var msg: TMessage); message WM_SYSCOMMAND; //procedure TfMain.WMSYSCOMMAND(var msg: TMessage); //begin inherited; if (Msg.wParam=SC_MINIMIZE) then tray_ShowIcon; end;//WMSYSCOMMAND procedure tray_ShowIcon(HideForm: boolean=true; AppIcon: boolean=true; Icon: TIcon=nil); //Если есть иконка на TrayBar, то выводит сообщение с округленными краями //Title, Text - загаловок и текст; IconType - тип сообщения None,Info,Warn,Err - нет, инфа, опасность или ошибка function tray_ShowMessage(Title, Text: string; IconType: TIconType=None): Boolean;
Имплементация //TrayBar procedure tray_ShowForm(Msg: TMessage; HideIcon: Boolean=true; PopupMenu: TPopupMenu=nil); var nidata: TNotifyIconData; P: TPoint; begin if Msg.LParam=WM_LBUTTONUP then begin Application.ShowMainForm:=true; ShowWindow(Application.Handle,SW_RESTORE); ShowWindow(Application.MainForm.Handle,SW_RESTORE); if HideIcon then begin with nidata do begin cbSize:=SizeOf(TNotifyIconData); // Wnd:=Form.Handle; Wnd:=Application.MainForm.Handle; uID:=uIcon_ID; end; Shell_NotifyIcon(NIM_DELETE,@nidata); end; SetForegroundWindow(Application.Handle); SetForegroundWindow(Application.MainForm.Handle); end; if PopupMenu&lt;&gt;nil then begin if Msg.LParam=WM_RBUTTONUP then begin GetCursorPos(P); SetForegroundWindow(Application.MainForm.Handle); PopupMenu.Popup(P.X,P.Y); end; end; end;//tray_ShowForm procedure tray_ShowIcon(HideForm: boolean=true; AppIcon: boolean=true; Icon: TIcon=nil); var nidata: TNotifyIconData; begin if HideForm then begin Application.ShowMainForm:=false; ShowWindow(Application.Handle,SW_HIDE); ShowWindow(Application.MainForm.Handle,SW_HIDE); end else begin SetForegroundWindow(Application.Handle); SetForegroundWindow(Application.MainForm.Handle); end; with nidata do begin cbSize:=SizeOf(TNotifyIconData); // Wnd:=Form.Handle; Wnd:=Application.MainForm.Handle; uID:=uIcon_ID; uFlags:=NIF_ICON or NIF_MESSAGE or NIF_TIP; uCallBackMessage:=WM_MYICONNOTIFY; if AppIcon or (Icon=nil) then hIcon:=Application.Icon.Handle else hIcon:=Icon.Handle; StrPCopy(szTip,Application.Title); end; Shell_NotifyIcon(NIM_ADD,@nidata); end;//tray_ShowIcon type NotifyIconData_50=record cbSize: DWORD; Wnd: HWND; uID: UINT; uFlags: UINT; uCallbackMessage: UINT; hIcon: HICON; szTip: array[0..MAXCHAR] of AnsiChar; dwState: DWORD; dwStateMask: DWORD; szInfo: array[0..MAXBYTE] of AnsiChar; uTimeout: UINT; szInfoTitle: array[0..63] of AnsiChar; dwInfoFlags: DWORD; end; var NID_50: NotifyIconData_50; function tray_ShowMessage(Title, Text: string; IconType: TIconType=None): Boolean; begin FillChar(NID_50,SizeOf(NotifyIconData_50),0); with NID_50 do begin cbSize:=SizeOf(NotifyIconData_50); Wnd:=Application.MainForm.Handle; uID:=uIcon_ID; uFlags:=NIF_INFO; StrPCopy(szInfo,Text); StrPCopy(szInfoTitle,Title); dwInfoFlags:=IconTypes[IconType]; end; tray_ShowMessage:=Shell_NotifyIcon(NIM_MODIFY,@NID_50); end;//tray_ShowMessage
В начале главного юнита объявляешь
type TfMain = class(TForm) .... procedure WMICON(var msg: TMessage); message WM_MYICONNOTIFY; procedure WMSYSCOMMAND(var msg: TMessage); message WM_SYSCOMMAND; .... private { Private declarations } public { Public declarations } end;
Там же имплементацияprocedure TfMain.WMICON(var msg: TMessage); begin tray_ShowForm(msg); end;//WMICON procedure TfMain.WMSYSCOMMAND(var msg: TMessage); begin inherited; if (Msg.wParam=SC_MINIMIZE) then tray_ShowIcon; end;//WMSYSCOMMAND
Post #: 8
RE: Программа в трее (DELPHI) - 2007-07-19 14:18:24.106666   
Yappi

Сообщений: 26
Оценки: 0
Присоединился: 2007-07-07 11:52:50.896666
Ну скажите человеку просто чтоб скачал Turbo Explorer - и все вопросы отпадут - пускай играется, там компонент TTrayIcon - встроенный, проще он ничего не найдет…8| Все равно наверное на VCL кодит… Хотя 200 мегов всё-таки… да уж - ищи на torry.net если не анлим или денег на жирный канал не жаль… Гугл в помощь;)
Post #: 9
Страниц:  [1]
Все форумы >> [Компилируемые языки] >> Программа в трее (DELPHI)







Связаться:
Вопросы по сайту / xakep@glc.ru

Предупреждение: использование полученных знаний в противозаконных целях преследуется по закону.