Similar question here: Resize Form while keeping aspect ratio
Basically, what I want is to resize form and maintain its aspect ratio, but I want resizing to follow the cursor as well. The answer in the topic above provided solution that is half-satisfactory - it works, but resizing is working 2x slower than it should. When I start to resize the form by X axis, you can see where the cursor is, and what the form size is:

I thought that since it resizes 2x slower, I should omit 0.5 multiplier in the code and it will work, but no dice. Here is the code that I'm using at the moment:
type
  TfrmTable = class(TForm)
    procedure FormCanResize(Sender: TObject; var NewWidth, NewHeight: Integer; var Resize: Boolean);
    procedure FormCreate(Sender: TObject);
  private
    FAspectRatio: Double;
  public
  end;
var
  frmTable: TfrmTable;
implementation
{$R *.dfm}
procedure TfrmTable.FormCreate(Sender: TObject);
begin
  FAspectRatio := Width / Height;
end;
procedure TfrmTable.FormCanResize(Sender: TObject; var NewWidth, NewHeight: Integer; var Resize: Boolean);
begin
  NewHeight := Round(0.50 * (NewHeight + NewWidth / FAspectRatio));
  NewWidth := Round(NewHeight * FAspectRatio);
end;
I've tried another approach, by using something like this:
procedure TfrmTable.FormCanResize(Sender: TObject; var NewWidth, NewHeight: Integer; var Resize: Boolean);
begin
  if NewWidth <> Width then
    NewHeight := Round(NewWidth / FAspectRatio)
  else
    if NewHeight <> Height then
      NewWidth := Round(NewHeight * FAspectRatio);
end;
What this should do? Well, my thinking is that I first check if NewWidth is different than current Width, and if it is, that means user is resizing form by X axis. Then I should set NewHeight to appropriate value. Otherwise, I check if NewHeight is different than current Height, and set NewWidth value to its appropriate value. This also produces weird results, when I drag form by X axis, it seems to work, and as soon as I stop resizing, form returns to its original size - I concluded that once I stop resizing (let mouse button up), FormCanResize() event gets called with old NewHeight value, which then reverts form back to its old size.
I don't think you can do without auxiliary.
Here I use a simple integer field to store whether you size horizontally, vertically, or not at all. You could also declare an enumeration for that.
  ...
  private
    FAspectRatio: Double;
    FResizing: Integer;
    procedure WMExitSizeMove(var Message: TMessage); message WM_EXITSIZEMOVE;
  end;
...
procedure TForm1.FormCanResize(Sender: TObject; var NewWidth,
  NewHeight: Integer; var Resize: Boolean);
begin
  if FResizing = 0 then
    FResizing := Abs(NewHeight - Height) - Abs(NewWidth - Width);
  if FResizing < 0 then
    NewHeight := Round(NewWidth / FAspectRatio)
  else
    NewWidth := Round(NewHeight * FAspectRatio);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
  FAspectRatio := Width / Height;
end;
procedure TForm1.WMExitSizeMove(var Message: TMessage);
begin
  inherited;
  FResizing := 0;
end;
The correct message to handle this is WM_SIZING:
By processing this message, an application can monitor the size and position of the drag rectangle and, if needed, change its size or position.
procedure TForm1.WMSizing(var Message: TMessage);
begin
  case Message.wParam of
    WMSZ_LEFT, WMSZ_RIGHT, WMSZ_BOTTOMLEFT:
      with PRect(Message.LParam)^ do
        Bottom := Top + Round((Right-Left)/FAspectRatio);
    WMSZ_TOP, WMSZ_BOTTOM, WMSZ_TOPRIGHT, WMSZ_BOTTOMRIGHT:
      with PRect(Message.LParam)^ do
        Right := Left + Round((Bottom-Top)*FAspectRatio);
    WMSZ_TOPLEFT:
      with PRect(Message.LParam)^ do
        Top := Bottom - Round((Right-Left)/FAspectRatio);
  end;
  inherited;
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With