Smooth resizing in a borderless form/window in Delphi

前端 未结 4 1909
难免孤独
难免孤独 2021-01-18 17:00

I am trying to resize a borderless form but when I increase the size using the right/bottom side, I get a gap between the border and the old client area that depends of the

4条回答
  •  栀梦
    栀梦 (楼主)
    2021-01-18 17:36

    Well, Warren P already pretty convincingly pointed you in another direction, but I'll try to answer your question. Or not really.

    Your edit makes the question very clear now:

    The effect is more noticeable when you resize from the left border or even from the bottomleft corner, it's horrible everywhere (I tried with other commercial apps and it happens as well). This effect happens as well when I change to sizeable border, but it's not as awful as when I remove the border.

    Not only other commercial applications, but also every OS window manifests this effect. Stretching the top of an Explorer window also "hides" and "expands" the status bar or bottom panel. I am pretty sure it cannot be defeated.

    It may seem worse for a borderless form, but I think that is just optical deception.

    If I had to take a guess at explaining this effect, then I would say that during the resize operation, the update of top and left takes precedence over that of width and height, which results in both not being updated an equal amount of times. Maybe it is graphics card related. Or maybe, ...hell what am I talking about? This is way out of my reach.

    Though, I still can not reproduce it for resizing the right and/or bottom of the form. If the amount of controls or (the combination of) their align and anchor properties is a problem, then you could consider temporarily disabling align all together, but I am almost sure you do not want that either. Below is my test code, copied from the question, slightly changed and of course with Sertac's constants added:

    function TForm1.ResizableAt(X, Y: Integer): Boolean;
    const
      BorderBuffer = 5;
    var
      R: TRect;
      C: TCursor;
    begin
      SetRect(R, 0, 0, Width, Height);
      InflateRect(R, -BorderBuffer, -BorderBuffer);
      Result := not PtInRect(R, Point(X, Y));
      if Result then
      begin
        FSides := [];
        if X < R.Left then
          Include(FSides, sLeft)
        else if X > R.Right then
          Include(FSides, sRight);
        if Y < R.Top then
          Include(FSides, sTop)
        else if Y > R.Bottom then
          Include(FSides, sBottom);
      end;
    end;
    
    function TForm1.SidesToCursor: TCursor;
    begin
      if (FSides = [sleft, sTop]) or (FSides = [sRight, sBottom]) then
        Result := crSizeNWSE
      else if (FSides = [sRight, sTop]) or (FSides = [sLeft, sBottom]) then
        Result := crSizeNESW
      else if (sLeft in FSides) or (sRight in FSides) then
        Result := crSizeWE
      else if (sTop in FSides) or (sBottom in FSides) then
        Result := crSizeNS
      else
        Result := crNone;
    end;
    
    procedure TForm1.ApplicationEventsMessage(var Msg: tagMSG;
      var Handled: Boolean);
    var
      CommandType: WPARAM;
    begin
      case Msg.message of
        WM_LBUTTONDOWN:
          if FResizable then
          begin
            CommandType := SC_SIZE;
            if sLeft in FSides then
              Inc(CommandType, WMSZ_LEFT)
            else if sRight in FSides then
              Inc(CommandType, WMSZ_RIGHT);
            if sTop in FSides then
              Inc(CommandType, WMSZ_TOP)
            else if sBottom in FSides then
              Inc(CommandType, WMSZ_BOTTOM);
            ReleaseCapture;
            DisableAlign;
            PostMessage(Handle, WM_SYSCOMMAND, CommandType, 0);
            Handled := True;
          end;
        WM_MOUSEMOVE:
          with ScreenToClient(Msg.pt) do
          begin
            FResizable := ResizableAt(X, Y);
            if FResizable then
              Screen.Cursor := SidesToCursor
            else
              Screen.Cursor := Cursor;
            if AlignDisabled then
              EnableAlign;
          end;
      end;
    end;
    

    Concerning your top aligned panel: try setting Align = alCustom and Anchors = [akLeft, akTop, akRight], though the enhancement may depend on the panel having a different color from that of the form, or maybe on me being optical deceived. ;)

提交回复
热议问题