MichaSchumann
MichaSchumann

Reputation: 1463

Delphi resizable form completely remove caption bar

I remove the title bar from a VCL form that still needs to be resizable by setting

borderStyle := bsNone;

and override createParams:

procedure TfrmMain.createParams(var Params: TCreateParams);
begin
  inherited;
  Params.Style := Params.Style or WS_THICKFRAME;
end;

This works fine when the window is maximized but adds a small caption bar above the client area (in Windows 10/1903) when the window is in normal state. Using WS_SIZEBOX instead of WS_THICKFRAME doesn't change this.

When I omit the create params override the additional bar is gone but the form is no longer resizable.

I use Delphi 10.3.2 Enterprise.

Upvotes: 2

Views: 1620

Answers (1)

Andreas Rejbrand
Andreas Rejbrand

Reputation: 108929

One possible solution is to remove the border completely but then tell Windows that the edges of the window are to be considered sizing borders.

To do this, set BorderStyle to bsNone and respond to the WM_NCHITTEST message:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
  TForm1 = class(TForm)
  private
  protected
    procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm5 }

procedure TForm1.WMNCHitTest(var Message: TWMNCHitTest);
var
  D: Integer;
  P: TPoint;
begin

  D := GetSystemMetrics(SM_CXSIZEFRAME);

  P := Self.ScreenToClient(Message.Pos);

  if P.Y < D then
  begin
    if P.X < D then
      Message.Result := HTTOPLEFT
    else if P.X > ClientWidth - D then
      Message.Result := HTTOPRIGHT
    else
      Message.Result := HTTOP;
  end
  else if P.Y > ClientHeight - D then
  begin
    if P.X < D then
      Message.Result := HTBOTTOMLEFT
    else if P.X > ClientWidth - D then
      Message.Result := HTBOTTOMRIGHT
    else
      Message.Result := HTBOTTOM;
  end
  else
  begin
    if P.X < D then
      Message.Result := HTLEFT
    else if P.X > ClientWidth - D then
      Message.Result := HTRIGHT
  end;

end;

end.

I'm not sure if this can be considered "best practices", however. Nor do I feel confident that there aren't any unwanted side effects, besides the obvious ones.

As always, you should be very careful when you do "unusual" things.

Upvotes: 4

Related Questions