Форум: "KOL";
Текущий архив: 2013.09.08;
Скачать: [xml.tar.bz2];
ВнизTrayIcon и WM_CLOSE Найти похожие ветки
← →
Ruzzz (2009-07-20 01:37) [0]Как я понимаю, при создании TrayIcon вот таким образом NewTrayIcon(frmMain, frmMain.Icon) в качестве первого параматра мы передаем родителя, к функции окна которого мы прикрепим функцию окна нашего TrayIcon, на это указывает строчка из NewTrayIcon - Wnd.AttachProc( WndProcTray ). Далее если посмотреть WndProcTray то видно что мы перехватываем WM_CLOSE и в итоге удаляем иконку из трея. Это дает нам возможность при закрытии формы, автоматически удалять и иконку.
1) Но при этом появляется проблема, так как (указано в описании AttachProc) «Last attached procedure is called first», то если мы захотим «не реагировать на закрытие формы», например установив Accept := False в OnClose, сообщение WM_CLOSE все равно попадет в WndProcTray, и все нам испортит :(
2) Если же не передавать главную форму в NewTrayIcon (в инете есть пример работы с TrayIcon где в NewTrayIcon передается не форма а созданый PControl), то в результате при закрытии главной формы иконка не удаляется из трея.
Что по вашему мнению более разумно сделать в этих ситуациях?
← →
Ruzzz (2009-07-20 01:42) [1]первая проблема актуальна также, если использовать главную форму и TrayIcon, при этом разрабатывая приложение с помощью MCK. Потому что в этом случае MCK генерирует код который в качестве первого параметра NewTrayIcon передает главную форму
← →
Ruzzz (2009-07-20 01:47) [2]Вообще интересует как при минимизации и закрытии формы просто скрыть ее.
← →
Ruzzz (2009-07-20 13:00) [3]Пока что пришел к такому:
procedure DoFormClose(Dummy: Pointer; Sender: PObj; var Accept: Boolean);
begin
if frmMain.Visible then begin
frmMain.Hide;
Accept := False;
end else begin
Tray.Free;
Accept := True;
end;
end;
procedure DoWorkMenu(Dummy: Pointer; Sender: pMenu; Item: Integer);
begin
case Item of
...
2: frmMain.Close;
end;
end;
...
frmMain.OnClose := TOnEventAccept(MakeMethod(nil, @DoFormClose));
...
Menu := NewMenu(frmMain, 0,
["Show/Hide",
"-",
"Exit" ],
TOnMenuItem(MakeMethod(nil, @DoWorkMenu))
);
...
Tray.NoAutoDeactivate := True;
Это позволяет скрывать форму при нажатии кнопки «Закрыть» и при этом корректно удалять иконку при выходе из программы.
← →
Ruzzz (2009-07-20 16:32) [4]Появилась проблема :( Если мы хотим выйти из программы с помощью меню трея, и при этом форма не скрыта, то она просто скрывается :(
← →
Ruzzz (2009-07-20 18:58) [5]
var
AppExit: Boolean = False;
procedure DoWorkMenu(Dummy: Pointer; Sender: pMenu; Item: Integer);
begin
case Item of
0: ShowHideForm;
2: begin
AppExit := True;
frmMain.Close;
end;
end;
end;
procedure DoFormClose(Dummy: Pointer; Sender: PObj; var Accept: Boolean);
begin
if optCloseToHide and frmMain.Visible and not AppExit then begin
frmMain.Hide;
Accept := False;
end else begin
Tray.Free;
Accept := True;
end;
end;
← →
Дмитрий К © (2009-07-20 19:35) [6]
program testFormHide;
uses
Windows, Messages, KOL;
type
PForm1 = ^TForm1;
TForm1 = object(TObj)
private
Form: PControl;
TI: PTrayIcon;
Menu: PMenu;
function FormMessage(var Msg: TMsg; var Rslt: Integer): Boolean;
procedure TIMouse(Sender: PObj; Message: Word);
procedure MenuMenuItem(Sender: PMenu; Item: Integer);
end;
var Form1: PForm1;
const
WM_SHOWHIDE = WM_USER + 1000;
{ TForm1 }
function TForm1.FormMessage(var Msg: TMsg; var Rslt: Integer): Boolean;
begin
Result := False;
case Msg.message of
WM_SYSCOMMAND: begin
case Msg.wParam of
SC_CLOSE, SC_MINIMIZE: begin
Form.Perform(WM_SHOWHIDE, 0, 0);
Result := True;
end;
end;
end;
WM_SHOWHIDE: begin
if Form.Visible then
begin
Form.Hide;
Menu.ItemText[0] := "Show";
end
else begin
Form.Show;
Menu.ItemText[0] := "Hide";
end;
end;
end;
end;
procedure TForm1.MenuMenuItem(Sender: PMenu; Item: Integer);
begin
case Item of
0: Form.Perform(WM_SHOWHIDE, 0, 0);
2: Form.Close;
end;
end;
procedure TForm1.TIMouse(Sender: PObj; Message: Word);
var P: TPoint;
begin
case Message of
WM_RBUTTONUP:begin
SetForegroundWindow(Form.Handle);
GetCursorPos(P);
Menu.Popup(P.X, P.Y);
end;
WM_LBUTTONDOWN:
SetForegroundWindow(Form.Handle);
WM_LBUTTONDBLCLK:
Form.Perform(WM_SHOWHIDE, 0, 0);
end;
end;
begin
New(Form1, Create);
with Form1^ do
begin
Form := NewForm(nil, "Test");
Form.Add2AutoFree(Form1);
Form.OnMessage := FormMessage;
TI := NewTrayIcon(Form, LoadIcon(0, IDI_APPLICATION));
TI.OnMouse := TIMouse;
NewMenu(Form, 0, [], nil);
Menu := NewMenu(Form, 0, ["Hide", "-", "Exit"], MenuMenuItem);
Menu.Items[0].DefaultItem := True;
Run(Form);
end;
end.
← →
Ruzzz (2009-07-20 21:03) [7]Спасибо! :) Сам как раз разобрался и пришел к такому:
function DoFormMessage(Dummy: Pointer; var Msg: TMsg; var Rslt: Integer): Boolean;
begin
Result := False;
if Msg.message = WM_SYSCOMMAND then
case Msg.wParam of
SC_MINIMIZE:
if optMinToHide then begin
frmMain.Hide;
Result := True;
end;
SC_CLOSE:
if optCloseToHide then begin
frmMain.Hide;
Result := True;
end
end;
end;
Действительно лучше ловить не WM_Close, а SC_CLOSE
НО Ваш пример много чего для меня показывает, например организация кода без использования MCK :)
Вопрос, зачем использовать SHOWHIDE, а не вызывать сразу процедуру ShowHide?
← →
Дмитрий К © (2009-07-20 22:29) [8]
> Вопрос, зачем использовать SHOWHIDE, а не вызывать сразу
> процедуру ShowHide?
В данном случае - незачем.
Страницы: 1 вся ветка
Форум: "KOL";
Текущий архив: 2013.09.08;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.002 c