Более гибкий вариант, работающий как под х86, так и под х64:
unit Forms.Persistent;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
{$IF Defined(WIN32) OR Defined(WIN64)}
System.Generics.Collections, Winapi.Windows, FMX.Platform.Win, Winapi.Messages,
{$ENDIF}
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs;
type
TfrmPersistent = class(TForm)
{$IF Defined(WIN32) OR Defined(WIN64)}
private
class var Callbacks: TDictionary<HWND, Pointer>;
class constructor ClassCreate;
class destructor ClassDestroy;
protected
procedure CreateHandle; override;
procedure DestroyHandle; override;
{$ENDIF}
end;
implementation
{$R *.fmx}
{$IF Defined(WIN32) OR Defined(WIN64)}
{ TfrmPersistent }
function WindowProc(hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
frm: TCommonCustomForm;
oldProc: Pointer;
begin
frm := FindWindow(hwnd);
if Assigned(frm) and (uMsg = WM_GETMINMAXINFO) then
begin
with PMinMaxInfo(LParam)^.ptMinTrackSize, frm do
begin
X := 950 + Width - ClientWidth;
Y := 500 + Height - ClientHeight;
end;
Result := 0;
end else
if TfrmPersistent.Callbacks.TryGetValue(hwnd, oldProc) and Assigned(oldProc) then
Result := CallWindowProc(oldProc, hwnd, uMsg, wParam, lParam)
else
Result := DefWindowProc(hwnd, uMsg, wParam, lParam);
end;
procedure TfrmPersistent.CreateHandle;
var
wnd: HWND;
begin
inherited CreateHandle;
wnd := FormToHWND(Self);
if wnd <> 0 then
begin
Callbacks.Add(wnd, Ptr(GetWindowLongPtr(wnd, GWLP_WNDPROC)));
SetWindowLongPtr(wnd, GWLP_WNDPROC, NativeInt(@WindowProc));
end;
end;
procedure TfrmPersistent.DestroyHandle;
var
wnd: HWND;
oldProc: Pointer;
begin
wnd := FormToHWND(Self);
if (wnd <> 0) and Callbacks.TryGetValue(wnd, oldProc) then
SetWindowLongPtr(wnd, GWLP_WNDPROC, NativeInt(oldProc));
inherited DestroyHandle;
end;
class constructor TfrmPersistent.ClassCreate;
begin
Callbacks := TDictionary<HWND, Pointer>.Create;
end;
class destructor TfrmPersistent.ClassDestroy;
begin
Callbacks.Free;
end;
{$ENDIF}
end.
Похоже, что при компиляции в х64, вложенные процедуры как-то хитро компилируются, в итоге либо кривой стек возникает, либо еще что, поэтому пришлось колбек вынести в глобальный метод.