Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
15-1364737450
ProgRAMmer Dimonych
2013-03-31 17:44
2013.09.08
Книги об общих принципах программирования


3-1292570406
johnden
2010-12-17 10:20
2013.09.08
Проблема с ClientDataSet в связке Master-Detail


15-1364877349
Piligrim
2013-04-02 08:35
2013.09.08
Delphi-приложения на многоядерных системах


2-1356533751
Vlad
2012-12-26 18:55
2013.09.08
Быстрый алгоритм поиска


15-1364654871
TUser
2013-03-30 18:47
2013.09.08
Умер Леонид Мацих





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский