Reputation: 4840
When a window is resized I want to handle the OnResize event when resizing is finished as updating the graphic takes seconds. That is tricky because resizing a window generates lots of resize events. As updating the window takes a while I don't want the window being updated on each event. I tried to detect a mouse up to flag that as the event that finishes a resize but the mouseup is never detected.
TLama had a nice solution but alas, that's VCL, I need it for Firemonkey. Any suggestions for FMX?
Upvotes: 3
Views: 1164
Reputation: 1483
As a workaround add a TTimer
to the form, set its initial state to disabled and the Interval
property to 100
ms. To minimize the amount of times your application reacts to the OnResize
event use the following code:
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;
The minimal delay should not be noticeable by the user.
Upvotes: 0
Reputation: 2224
Here is a way to handle it in FMX on Windows, you need to change your form to inherit from TResizeForm
and assign OnResizeEnd
property. Not very clean since it depends on on FMX internals, but should work.
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.
Upvotes: 1
Reputation: 10368
What about something similar to the Debounce() or Throttle() function in Underscore.js? Both functions provide ways to limit how regularly a procedure is executed.
Upvotes: 2