the_modder
asked on
Program won't accept TMessage without Show, then Hide
Hi. I'm making a system tray application that is not supposed to be visible, ever. It needs to detect when the user is about to log off, and pop up a message. However, I'm having issues getting a clean solution to intercepting the windows messages, as I have to show the form and then hide it. If I don't do this, then the messages never get received.
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm2 = class(TForm)
Button1: TButton;
procedure EndSMsg(var T : TMessage);message WM_QUERYENDSESSION;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
hide;
end;
procedure TForm2.EndSMsg(var T : TMessage);
begin
T.result := 1;
if T.lparam = 0 then
begin
ShowMessage('System is shutting down');
end
else if (DWORD(T.lparam) and ENDSESSION_LOGOFF) =
ENDSESSION_LOGOFF then
begin
ShowMessage('User is logging off');
end;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
show;
hide;
end;
end.
use Application.OnMessage event handler, the way you do this message wil lbe intercepted only if TFOrm2 exists
ziolko.
ziolko.
ASKER
ThievingSix:
The attached code doesn't seem to work. Nothing gets triggered.
ziolko: I think that the message never gets sent to my window because the application never registers itself since its invisible (application.showmainform = false)
The attached code doesn't seem to work. Nothing gets triggered.
ziolko: I think that the message never gets sent to my window because the application never registers itself since its invisible (application.showmainform = false)
program Project1;
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ShellAPI, INIFiles,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
var
Msg : TMsg;
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
application.showmainform := false;
Application.Run;
While GetMessage(Msg,0,0,0) Do
begin
If Msg.message = WM_QUERYENDSESSION Then
begin
If Msg.lParam = 0 Then
begin
ShowMessage('System is shutting down');
Break;
end
Else If (Msg.lParam And ENDSESSION_LOGOFF) = ENDSESSION_LOGOFF Then
begin
ShowMessage('User is logging off');
Break;
end;
end;
end;
end.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Even this code doesn't work. It does not detect a user logoff :(
program Project1;
uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
StdCtrls,
ShellAPI,
INIFiles;
{$R *.res}
var
Msg : TMsg;
begin
While GetMessage(Msg,0,0,0) Do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
If Msg.message = WM_QUERYENDSESSION Then
begin
If Msg.lParam = 0 Then
begin
ShowMessage('System is shutting down');
Break;
end
Else If (Msg.lParam And ENDSESSION_LOGOFF) = ENDSESSION_LOGOFF Then
begin
ShowMessage('User is logging off');
Break;
end;
end;
end;
end.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
ziolko: I have followed your advice and added a TApplicationEvents component. However, it still does not detect a user log off. If I don't comment out the Msg.lparam and the following sections, when I right click on the desktop, it seems that the application just keeps on opening up message boxes.
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
begin
//if Msg.lparam = 0 then
// begin
// ShowMessage('System is shutting down');
// end
//else
if (DWORD(Msg.lparam) and ENDSESSION_LOGOFF) =
ENDSESSION_LOGOFF then
begin
ShowMessage('User is logging off');
end;
end;
ASKER
Thanks guys. After hours of bashing my head into the wall, I figured out that another one of my procedures was grabbing the messages. However, ziolko's solution was better, as I learned something new from it, which I will use later in my projects.
Like so:
Open in new window