Gia*_*mbo 14 delphi firemonkey
我需要拦截Windows关闭,并执行一些数据库查询,然后我的应用程序将关闭.我在FMX项目上使用Windows 10下的Delphi XE10
我尝试的是下面的代码,但它不起作用
private
{ Private declarations }
{$IFDEF MSWINDOWS}
procedure WMQueryEndSession(var Msg: TWMQueryEndSession); message WM_QUERYENDSESSION;
procedure WMEndSession(var Msg : TWMQueryEndSession); message WM_ENDSESSION ;
{$ENDIF}
end;
procedure TfMain.WMQueryEndSession(var Msg: TWMQueryEndSession);
var
lista:TStringList;
begin
{$IFDEF MSWINDOWS}
try
lista:=TStringList.Create;
lista.Add(FOrmatDateTime('DD/MM/YYYY HH:NN:SS',now)+' event WMQueryEndSession');
Lista.SaveToFile(froot+formatdatetime('YYMMDDHHNNSSZZZ',now)+'.log');
SincroClose();
lista.Add(FOrmatDateTime('DD/MM/YYYY HH:NN:SS',now)+' Done');
Lista.SaveToFile(froot+formatdatetime('YYMMDDHHNNSSZZZ',now)+'.log');
finally
lista.Free;
end;
{$ENDIF}
inherited;
end;
procedure TfMain.WMEndSession(var Msg: TWMQueryEndSession);
var
lista:TStringList;
begin
{$IFDEF MSWINDOWS}
try
lista:=TStringList.Create;
lista.Add(FOrmatDateTime('DD/MM/YYYY HH:NN:SS',now)+' WMEndSession');
Lista.SaveToFile(froot+formatdatetime('YYMMDDHHNNSSZZZ',now)+'.log');
SincroClose();
lista.Add(FOrmatDateTime('DD/MM/YYYY HH:NN:SS',now)+' Done');
Lista.SaveToFile(froot+formatdatetime('YYMMDDHHNNSSZZZ',now)+'.log');
finally
lista.Free;
end;
{$ENDIF}
inherited;
end;
procedure TfMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var lista:TStringList;
begin
{$IFDEF MSWINDOWS}
CanClose:=false;
try
lista:=TStringList.Create;
lista.Add(FOrmatDateTime('DD/MM/YYYY HH:NN:SS',now)+' FormCloseQuery');
Lista.SaveToFile(froot+formatdatetime('YYMMDDHHNNSSZZZ',now)+'.log');
SincroClose();
lista.Add(FOrmatDateTime('DD/MM/YYYY HH:NN:SS',now)+' Done');
Lista.SaveToFile(froot+formatdatetime('YYMMDDHHNNSSZZZ',now)+'.log');
CanClose:=true;
finally
lista.Free;
end;
{$ENDIF}
end;
Run Code Online (Sandbox Code Playgroud)
只有正常的关闭应用程序,在FormCloseQuery事件下才能正常工作,但是当Windows关闭时,我的应用程序将关闭而不保存任何数据
Ser*_*yuz 15
FormCloseQuery因为它被框架暴露而起作用.Windows关闭时,您的应用程序不会保存任何数据,因为永远不会调用消息处理程序.消息处理仅适用于VCL应用程序,fmx应用程序具有不同的消息传递机制,如文档所述.
这里的简要说明意味着可以在fmx框架中从OS接收通知.但是我不知道这是否包括关闭通知以及是否可以设置返回,因为文档提到消息对象是只读的.
在您了解fmx消息传递机制如何工作以及它是否满足要求之前,您可以通过常规方法对表单窗口进行子类化.下面的例子使用SetWindowSubclass.
...
protected
{$IFDEF MSWINDOWS}
procedure CreateHandle; override;
procedure DestroyHandle; override;
procedure WMQueryEndSession(var Msg: TWMQueryEndSession); message WM_QUERYENDSESSION;
procedure WMEndSession(var Msg: TWMEndSession); message WM_ENDSESSION;
{$ENDIF}
...
implementation
{$IFDEF MSWINDOWS}
uses
FMX.Platform.Win, Winapi.Commctrl;
function SubclassProc(Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM;
uIdSubclass: UINT_PTR; RefData: DWORD_PTR): LRESULT; stdcall;
var
Self: TfMain;
Message: TMessage;
begin
Result := DefSubclassProc(Wnd, Msg, wParam, lParam);
case Msg of
WM_QUERYENDSESSION, WM_ENDSESSION:
begin
Self := TfMain(RefData);
Message.Msg := Msg;
Message.WParam := wParam;
Message.LParam := lParam;
Message.Result := Result;
Self.Dispatch(Message);
Result := Message.Result;
end;
end;
end;
procedure TfMain.CreateHandle;
var
Wnd: HWND;
begin
inherited;
Wnd := WindowHandleToPlatform(Self.Handle).Wnd;
SetWindowSubclass(Wnd, SubclassProc, 1, DWORD_PTR(Self));
end;
procedure TfMain.DestroyHandle;
var
Wnd: HWND;
begin
Wnd := WindowHandleToPlatform(Self.Handle).Wnd;
RemoveWindowSubclass(Wnd, SubclassProc, 1);
inherited;
end;
procedure TfMain.WMQueryEndSession(var Msg: TWMQueryEndSession);
begin
// do not call inherited here, there's no inherited handling
end;
procedure TfMain.WMEndSession(var Msg: TWMEndSession);
begin
// do not call inherited here, there's no inherited handling
end;
var
ICC: TInitCommonControlsEx;
initialization
ICC.dwSize := SizeOf(ICC);
ICC.dwICC := ICC_STANDARD_CLASSES;
InitCommonControlsEx(ICC);
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
796 次 |
| 最近记录: |