加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 如何在VCL项目中将Fmx项目中的Windows关闭事件作为WM_

发布时间:2020-12-15 10:10:35 所属栏目:大数据 来源:网络整理
导读:我需要拦截 Windows关闭,并执行一些DB查询,之后我的应用程序将关闭. 我在Windows 10上使用Delphi XE10在FMX项目 我试过的是下面的代码,但它不起作用 private { Private declarations } {$IFDEF MSWINDOWS} procedure WMQueryEndSession(var Msg: TWMQueryEnd
我需要拦截 Windows关闭,并执行一些DB查询,之后我的应用程序将关闭.
我在Windows 10上使用Delphi XE10在FMX项目

我试过的是下面的代码,但它不起作用

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');
  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');
    CanClose:=true;
  finally
    lista.Free;
  end;
{$ENDIF}

end;

只有正常的关闭应用程序,才能正常工作,在FormCloseQuery事件下,但是当Windows关闭时,我的应用程序将关闭而不保存任何数据

解决方法

FormCloseQuery的工作原理是由框架公开的.由于您的邮件处理程序永远不会被调用,所以您的应用程序不会在Windows关闭时保存任何数据.消息处理仅适用于VCL应用程序,fmx应用程序具有与 documented不同的消息传递机制.

简要说明here意味着可以在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,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}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读