unit WinSizeHook;
interface
procedure StartProportionalSizing;
stdcall;
forward;
procedure StopProportionalSizing;
stdcall;
forward;
implementation
uses Windows, Forms, Dialogs, Messages, SysUtils, Math, Classes, Controls;
var
glbSizeHook: cardinal = 0;
glbRatio: single;
function Hook(code: Integer; W: wParam; L: lParam): LResult;
stdcall;
type
pCWPStruct = ^CWPSTRUCT;
var
currentCWP: CWPSTRUCT;
windowRect: TRect;
PWindowRect: PRect;
newSize: integer;
begin
try
if code >= HC_ACTION
then begin
currentCWP := pCWPStruct(L)^;
case currentCWP.
message of
WM_ENTERSIZEMOVE:
begin
if GetWindowRect(currentCWP.hwnd, windowRect)
then
glbRatio := (windowRect.Right - windowRect.Left) / (windowRect.Bottom - windowRect.Top);
end;
WM_SIZING:
begin
PWindowRect := PRect(currentCWP.LParam);
case currentCWP.WParam
of
WMSZ_BOTTOM, WMSZ_TOP,
WMSZ_TOPLEFT, WMSZ_TOPRIGHT, WMSZ_BOTTOMLEFT, WMSZ_BOTTOMRIGHT:
begin
newSize := trunc(SimpleRoundTo((PWindowRect.Bottom - PWindowRect.Top + 1) * glbRatio, 0));
PWindowRect.Right := PWindowRect.Left + newSize;
end;
WMSZ_LEFT, WMSZ_RIGHT:
begin
newSize := trunc(SimpleRoundTo((PWindowRect.Right - PWindowRect.Left + 1) / glbRatio, 0));
PWindowRect.Bottom := PWindowRect.Top + newSize;
end;
end;
end;
end;
end;
except
end;
result := CallNextHookEx(glbSizeHook, code, w, l);
end;
procedure StartProportionalSizing;
begin
if glbSizeHook = 0
then
glbSizeHook := SetWindowsHookEx(WH_CALLWNDPROC, @Hook, 0, GetCurrentThreadID());
end;
procedure StopProportionalSizing();
begin
if glbSizeHook <> 0
then
UnhookWindowsHookEx(glbSizeHook);
end;
end.