【问题标题】:What is the best way to handle OnResize in FMX?在 FMX 中处理 OnResize 的最佳方法是什么?
【发布时间】:2014-03-04 19:59:47
【问题描述】:
当调整窗口大小时,我想在调整大小完成后处理 OnResize 事件,因为更新图形需要几秒钟。这很棘手,因为调整窗口大小会产生大量调整大小事件。由于更新窗口需要一段时间,我不希望每个事件都更新窗口。我尝试检测鼠标向上以将其标记为完成调整大小但从未检测到鼠标向上的事件。
TLama 有一个nice solution,但唉,那是 VCL,我需要它用于 Firemonkey。对 FMX 有什么建议吗?
【问题讨论】:
标签:
delphi
resize
delphi-xe5
firemonkey-fm3
【解决方案2】:
这是在 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.
【解决方案3】:
作为一种解决方法,将TTimer 添加到表单中,将其初始状态设置为禁用,并将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;
最小的延迟应该不会被用户注意到。