There is a program on Delphi XE. At startup, the program is minimized to tray (using the built-in component TrayIcon). How to make the program intercept these events on and off when shutting down Windows or logging out? If possible, code samples are needed.

PS: I bring the folding code to tray when the program starts:

DM.TrayIcon1.Visible := True; DM.TrayIcon1.Hint := 'Журнал заявок'; // Убираем с панели задач ShowWindow(Handle, SW_HIDE); // Скрываем программу ShowWindow(Application.Handle, SW_HIDE); // Скрываем кнопку с TaskBar'а SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) or (not WS_EX_APPWINDOW)); 
  • If your program finishes normally, being not minimized to the tray (by pressing the close button, it’s also a cross), it will normally shut down when Windows is finished. No additional manipulation is required. - kami
  • Everything would be fine, but on Windows XP such manipulations do not work. - e.khamidullin
  • Try to write in more detail. What are "such" manipulations? What does it mean - "do not work"? Is an exception in the program? Does it hang? Is it interrupted, as if she was done TerminateProcess? Says "I do not want to end"? - kami
  • one
    Do you happen to have any messages or questions before leaving the program? Maybe they block the normal completion? - androschuk
  • one
    What happens if in the program window to click on the "cross" (system button to close the window)? - Alekcvp

1 answer 1

Add a method and a variable to the main form:

 ... private FSessionEnding: Boolean; procedure WMQueryEndSession(var Message: TMessage); message WM_QUERYENDSESSION; 

In the implementation write:

 procedure TForm1.WMQueryEndSession(var Message: TMessage); { чтобы программа не препятствовала выключению компа } begin FSessionEnding := True; Message.Result := 1; end; procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin CanClose := FSessionEnding; { закрываемся, если выбрали выход из меню или выключаем комп } if not CanClose then cltrycn1.HideMainForm; { иначе сворачиваемся в трей } // cltrycn1 - аналог TrayIcon end; 

If there are other ways to exit the program, for example, the exit button in the menu, then in order for the program to close, you must set FSessionEnding to True before exiting. For example:

 procedure TForm1.Exit1Click(Sender: TObject); begin FSessionEnding := True; Close; end; 

UPD: If the form does not use the OnCloseQuery handler, then the FSessionEnding variable FSessionEnding not needed, and the WM_QUERYENDSESSION message WM_QUERYENDSESSION should be used, for example, like this:

 procedure TForm1.WMQueryEndSession(var Message: TMessage); begin Message.Result := 1; Close; end; 
  • This method, unfortunately, did not help. It is still necessary to forcibly close the program in order to log out or restart the computer. - e.khamidullin
  • What method is your code for minimizing to tray? - kot-da-vinci
  • On the main form in the following method: - e.khamidullin
  • procedure TForm6.FormActivate (Sender: TObject); - e.khamidullin
  • What is DM in your code in question? - kot-da-vinci