1

I'm trying to resize a non borderless form (bsNone border style). It can be done with the following code, but it worked only when the application has no a VCL style enabled.

protected
   procedure WMNCHitTest(var message: TWMNCHitTest); message WM_NCHITTEST;
....

procedure TForm1.WMNCHitTest(var message: TWMNCHitTest);
const
  EDGEDETECT = 7;
var
  deltaRect: TRect;
begin
  inherited;
  if BorderStyle = bsNone then
    with Message, deltaRect do
    begin
      Left   := XPos - BoundsRect.Left;
      Right  := BoundsRect.Right - XPos;
      Top    := YPos - BoundsRect.Top;
      Bottom := BoundsRect.Bottom - YPos;
      if (Top < EDGEDETECT) and (Left < EDGEDETECT) then
        Result := HTTOPLEFT
      else if (Top < EDGEDETECT) and (Right < EDGEDETECT) then
        Result := HTTOPRIGHT
      else if (Bottom < EDGEDETECT) and (Left < EDGEDETECT) then
        Result := HTBOTTOMLEFT
      else if (Bottom < EDGEDETECT) and (Right < EDGEDETECT) then
        Result := HTBOTTOMRIGHT
      else if (Top < EDGEDETECT) then
        Result := HTTOP
      else if (Left < EDGEDETECT) then
        Result := HTLEFT
      else if (Bottom < EDGEDETECT) then
        Result := HTBOTTOM
      else if (Right < EDGEDETECT) then
        Result := HTRIGHT
    end;

I have also tried to do something like this and it's has the same result. Then how can i make it resizable when VCL style enabled?

Thank you very much.

procedure CreateParams(var params: TCreateParams); override;
    ...
    procedure TForm1.CreateParams(var params: TCreateParams);
          begin
            BorderStyle := bsNone;
            inherited;
            params.ExStyle := params.ExStyle or WS_EX_STATICEDGE;
            params.Style   := params.Style or WS_SIZEBOX;
          end;
Ling Loeng
  • 128
  • 2
  • 9
  • 1
    Don't set BorderStyle or indeed any property in CreateParams. – David Heffernan Jun 29 '17 at 05:43
  • @DavidHeffernan I've tried it, removing `BorderStyle := bsNone`. And still i can not resize the form. – Ling Loeng Jun 29 '17 at 05:52
  • 1
    The fact that removing that code doesn't fix your problem doesn't mean the code was right. Don't set properties in CreateParams. It's job is to populate the params argument. It must not change state. – David Heffernan Jun 29 '17 at 05:54

1 Answers1

3

The reason that VCL styles breaks your WM_NCHITTEST message handler is that the form's style hook handles WM_NCHITTEST directly. You can override that and regain control like this:

protected
  function DoHandleStyleMessage(var Message: TMessage): Boolean; override;

....

function TForm1.DoHandleStyleMessage(var Message: TMessage): Boolean;
begin
  if Message.Msg=WM_NCHITTEST then begin
    Result := False;
  end else begin
    Result := inherited;
  end;
end;

Now your event handler for WM_NCHITTEST will be invoked again. Of course, you will lose any functionality that the VCL styles handler for WM_NCHITTEST provided, but I suspect that is exactly what you want.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Thank you very much @DavidHeffernan for your help. Looks like i have one step closer to solve my problem. Unfortunately, i can't fully understand how to apply this - eventough i've spent many hours for trying to implement `DoHandleStyleMessage`, i'm still failed. I'll accept this answer after i am able to implement it correctly. – Ling Loeng Jun 30 '17 at 09:31
  • I knew, SO is not tutorial page, i should do a hard work first as much as possible - to solve a problem by myself before creating question or asking in comment. Indeed quite a shame for me, as a self-taught beginner, here is what i've tried so far : `procedure TForm1.FormCreate(Sender: TObject);` `var ` `aMessage : TMessage;` `begin` `aMessage.Msg := WM_NCHITTEST;` `DoHandleStyleMessage(aMessage);` – Ling Loeng Jun 30 '17 at 09:32
  • My answer had a silly copy/paste mistake. It is accurate now. – David Heffernan Jun 30 '17 at 09:39
  • Then i have to call `DoHandleStyleMessage`, am i right? if so, where should i call this function, is it on `FormCreate` event handler or something else? – Ling Loeng Jun 30 '17 at 09:47
  • No. It's a virtual method that is called by the framework. Don't call it. – David Heffernan Jun 30 '17 at 09:49
  • 1
    Awesome. Finally it works like a charm. @DavidHeffernan really i am one of your fans - and also fan of @RemyLebeau. lol. btw, you should edit again for a litle typo `procedure` to `function`. Thank you very much. You save my days..!! – Ling Loeng Jun 30 '17 at 10:02