Delphi 在FMX中处理OnResize的最佳方法是什么?

Delphi 在FMX中处理OnResize的最佳方法是什么?,delphi,resize,delphi-xe5,firemonkey-fm3,Delphi,Resize,Delphi Xe5,Firemonkey Fm3,当窗口调整大小时,我希望在完成调整大小时处理OnResize事件,因为更新图形需要几秒钟。这很棘手,因为调整窗口大小会产生大量调整大小事件。由于更新窗口需要一段时间,我不希望每次事件都更新窗口。我试图检测一个鼠标,将其标记为完成调整大小的事件,但从未检测到鼠标 特拉玛有一个,但唉,这是VCL,我需要它的Firemonkey。对FMX有什么建议吗?类似的建议怎么样?这两个函数都提供了限制过程执行频率的方法 这里有一种在Windows上的FMX中处理它的方法,您需要更改表单以从TResizeForm

当窗口调整大小时,我希望在完成调整大小时处理OnResize事件,因为更新图形需要几秒钟。这很棘手,因为调整窗口大小会产生大量调整大小事件。由于更新窗口需要一段时间,我不希望每次事件都更新窗口。我试图检测一个鼠标,将其标记为完成调整大小的事件,但从未检测到鼠标


特拉玛有一个,但唉,这是VCL,我需要它的Firemonkey。对FMX有什么建议吗?

类似的建议怎么样?这两个函数都提供了限制过程执行频率的方法

这里有一种在Windows上的FMX中处理它的方法,您需要更改表单以从
TResizeForm
继承并分配
OnResizeEnd
属性。不太干净,因为它取决于FMX内部,但应该可以工作

unit UResizeForm;

interface

uses
  Winapi.Windows,
  System.SysUtils, System.Classes,
  FMX.Types, FMX.Forms, FMX.Platform.Win;

type
  TResizeForm = class(TForm)
  strict private
    class var FHook: HHook;
  strict private
    FOnResizeEnd: TNotifyEvent;
  public
    property OnResizeEnd: TNotifyEvent read FOnResizeEnd write FOnResizeEnd;
    class constructor Create;
    class destructor Destroy;
  end;

implementation

uses Winapi.Messages;

var
  WindowAtom: TAtom;

function Hook(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;
var
  cwp: PCWPSTRUCT;
  Form: TForm;
  ResizeForm: TResizeForm;
begin
  try
    cwp := PCWPSTRUCT(lparam);
    if cwp.message = WM_EXITSIZEMOVE then
    begin
      if WindowAtom <> 0 then
      begin
        Form := TForm(GetProp(cwp.hwnd, MakeIntAtom(WindowAtom)));
        if Form is TResizeForm then
        begin
          ResizeForm := Form as TResizeForm;
          if Assigned(ResizeForm.OnResizeEnd) then
          begin
            ResizeForm.OnResizeEnd(ResizeForm);
          end;
        end;
      end;
    end;
  except
    // eat exception
  end;
  Result := CallNextHookEx(0, code, wparam, lparam);
end;

class constructor TResizeForm.Create;
var
  WindowAtomString: string;
begin
  WindowAtomString := Format('FIREMONKEY%.8X', [GetCurrentProcessID]);
  WindowAtom := GlobalFindAtom(PChar(WindowAtomString));
  FHook := SetWindowsHookEx(WH_CALLWNDPROC, Hook, 0, GetCurrentThreadId);
end;

class destructor TResizeForm.Destroy;
begin
  UnhookWindowsHookEx(FHook);
end;

end.
单位UResizeForm;
接口
使用
Winapi.Windows,
System.SysUtils、System.class、,
FMX.type,FMX.Forms,FMX.Platform.Win;
类型
TResizeForm=class(TForm)
严格保密
类别变量FHook:HHook;
严格保密
FOnResizeEnd:TNotifyEvent;
公众的
属性OnResizeEnd:TNotifyEvent读取FOnResizeEnd写入FOnResizeEnd;
类构造函数创建;
类析构函数销毁;
结束;
实施
使用Winapi.Messages;
变量
WindowAtom:TAtom;
函数挂钩(代码:Integer;wparam:wparam;lparam:lparam):LRESULT stdcall;
变量
cwp:PCWPSTRUCT;
形式:TForm;
大小:TResizeForm;
开始
尝试
cwp:=PCWPSTRUCT(lparam);
如果cwp.message=WM_EXITSIZEMOVE,则
开始
如果WindowAtom为0,则
开始
Form:=TForm(GetProp(cwp.hwnd,MakeIntAtom(WindowAtom));
如果表单是TResizeForm,那么
开始
ResizeForm:=作为TResizeForm的表单;
如果已分配(ResizeForm.OnResizeEnd),则
开始
ResizeForm.OnResizeEnd(ResizeForm);
结束;
结束;
结束;
结束;
除了
//吃例外
结束;
结果:=CallNextHookEx(0,代码,wparam,lparam);
结束;
类构造函数TResizeForm.Create;
变量
WindowAtomString:字符串;
开始
WindowAtomString:=格式('FIREMONKEY%.8X',[GetCurrentProcessID]);
WindowAtom:=GlobalFindAtom(PChar(WindowAtomString));
FHook:=SetWindowsHookEx(WH_CALLWNDPROC,Hook,0,GetCurrentThreadId);
结束;
类析构函数TResizeForm.Destroy;
开始
脱钩钩钩(FHook);
结束;
结束。

作为一种解决方法,在表单中添加一个
TTimer
,将其初始状态设置为disabled,将
Interval
属性设置为
100
ms。要最小化应用程序对
OnResize
事件的反应次数,请使用以下代码:

procedure TForm1.FormResize(Sender: TObject);
begin
    with ResizeTimer do
    begin
        Enabled := false;
        Enabled := true;
    end;
end;

procedure TForm1.ResizeTimerTimer(Sender: TObject);
begin
    ResizeTimer.Enabled := false;

    // Do stuff after resize
end;
用户不应注意到最小延迟