如何控制窗口的边框大小?

时间:2011-03-01 20:47:19

标签: delphi

我有一些使用绝对定位的形式,Win7添加到“手柄”以增强半透明度的额外像素正在搞砸控件。我想带他们回去。我尝试在其中一个答案中使用代码:

Can you make a Borderless Application Main Window in Windows, without WS_POPUP style?

具体来说,GolezTrol通过调用SetWindowRgn在ShowForm中使用覆盖提供的答案。在W7下代码的行为与XP有点不同,无论如何我无法得到我正在寻找的效果。

对于XP中的标准TForm,数量Width-ClientWidth = 8,而在Win7中,它是16.我希望那些8像素回来。

。虽然宽度更重要,但我还是喜欢高度像素

3 个答案:

答案 0 :(得分:7)

我认为依靠表单的边框宽度非常糟糕,尤其是,因为最终用户可以在控制面板中更改它!您可以使用ClientWidth属性代替Width。将前者设置为您喜欢的任何一种,后者将被计算出来。

答案 1 :(得分:2)

您可以使用标记SPI_SETNONCLIENTMETRICS查看WinAPI函数SystemParametersInfo是否有用。您可以使用NONCLIENTMETRICS记录(C中的结构)中提供的值设置所有窗口的非客户区域的各个部分。

请注意,这是一个全局设置,因此不会仅影响您的窗口,而是影响系统上的所有窗口。这很可能是一个非常糟糕的解决方案。

答案 2 :(得分:0)

我在Windows中实现了一个模拟边框大小调整行为的控件。把它放在你的主窗体上,将它与alClient对齐,或使用锚属性(锚点可能更好)并将主窗体的边框样式更改为bsNone,但不要在你链接到的另一个问题中引用黑客。

unit ResizeBorderControlUnit;

// TResizeBorderControl:
//
//  This is a subclass of TShape made to handle the border resize
//  logic for a main form with border style bsNone.  I wanted to 
//  make the form resizeable (think of a post-it note app) but I didn't
//  want any Windows non-client painting or non-client manipulation logic. 
//
// Written by Warren Postma



interface

uses Windows,
      Messages,
      Controls,
      Forms,
      ExtCtrls,
      Classes,
      SysUtils;

const
  // if this value is too small, resizing gets too tricky.
   MinSideMargin = 4;
   MinBottomMargin = 4;

    //Perform(wm_SysCommand, sc_DragMove, 0) etc:
    sc_DragMove = $f012;
    sc_Leftsize = $f001;
    sc_Rightsize = $f002;
    sc_Upsize = $f003;
    sc_UpLeftsize = $f004;
    sc_UpRightsize = $f005;
    sc_Dnsize = $f006;
    sc_DnLeftsize = $f007;
    sc_DnRightsize = $f008;

type
  TResizeBorderControl = class(TShape)
  private
//      FParentFormResize:TForm;
    FSidesResizeHeight: Integer;
    FBottomResizeHeight: Integer;
    FBorderResizeFlag:Integer;
    FAutoSize: Boolean;
    FAutoSizeStartingAtTop: Integer; // currently active state.
    procedure SetBottomResizeHeight(const Value: Integer);
    procedure SetSidesResizeHeight(const Value: Integer);
    procedure SetAutoSize(const Value: Boolean);
    procedure SetAutoSizeStartingAtTop(const Value: Integer);

  protected
      procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
      procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
      procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE; //override;
      procedure CheckPosition(X,  Y: Integer);


      function MainFormMaximized:Boolean;

  public
      constructor Create(AOwner:TComponent); override;
  published
     property AutoSize:Boolean read FAutoSize write SetAutoSize;
     property AutoSizeStartingAtTop:Integer read FAutoSizeStartingAtTop write SetAutoSizeStartingAtTop;
     property BottomResizeHeight:Integer read FBottomResizeHeight write SetBottomResizeHeight;
     property SidesResizeHeight:Integer read FSidesResizeHeight write SetSidesResizeHeight;
  end;
implementation



// TResizeBorderControl 


procedure TResizeBorderControl.CMMouseLeave(var Message: TMessage);
begin
  Parent.Perform(CM_MOUSELEAVE, 0, Longint(Self));
  if (Message.LParam = 0) then
  begin
    if Assigned(OnMouseLeave) then
      OnMouseLeave(Self);

    if ShowHint and not (csDesigning in ComponentState) then
      if CustomHint <> nil then
        CustomHint.HideHint(Self);
  end;

  FBorderResizeFlag := 0; // reset any active state bits.
  Self.Cursor := crDefault;
end;

constructor TResizeBorderControl.Create(AOwner: TComponent);
begin
  inherited;
  Brush.Color := $202020;
end;

function TResizeBorderControl.MainFormMaximized: Boolean;
var
 fm:TCustomForm;
begin
  result := true;
  fm := GetParentForm(Self);
  if Assigned(fm) then
      result := (fm.WindowState=wsMaximized);


end;

procedure TResizeBorderControl.MouseDown(Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);

   procedure DoResize(aType:Integer);
   var
     pw:TCustomForm;
   begin
       ReleaseCapture;
       pw := Forms.GetParentForm(Self);
       if Assigned(pw) then begin
         ReleaseCapture;
         pw.Perform(WM_syscommand, aType, 0);
       end;
   end;
begin
  inherited;

  if csDesigning in ComponentState then exit;
  if MainFormMaximized then exit;

 if (FBorderResizeFlag=0) then begin
    CheckPosition(X, Y);
 end;

 if FBorderResizeFlag  =1 then
      DoResize( sc_Leftsize)
 else if FBorderResizeFlag  =2 then
     DoResize( sc_Rightsize)
 else if FBorderResizeFlag  =4 then
      DoResize( sc_Dnsize )
 else if FBorderResizeFlag  =5 then
      DoResize( sc_DnLeftsize)
 else if FBorderResizeFlag  =6 then
       DoResize( sc_DnRightsize)
 else if FBorderResizeFlag  =8 then
        DoResize( sc_Upsize)
 else
   Self.Cursor := crDefault;

 //FBorderResizeFlag  := 0; // nope. second time mouse down without a move would glitch us.
end;

procedure TResizeBorderControl.MouseMove(Shift: TShiftState; X,
  Y: Integer);
begin
  if MainFormMaximized then exit;

 CheckPosition(X,Y);
end;

procedure TResizeBorderControl.CheckPosition(X,  Y: Integer);
var
 SideMargin,BottomMargin:Integer;
begin


  if csDesigning in ComponentState then begin
    inherited;
    exit;
  end;

  FBorderResizeFlag  := 0;

  if MainFormMaximized then exit;

  BottomMargin := FBottomResizeHeight;
  if BottomMargin<MinBottomMargin then
   BottomMargin := MinBottomMargin;

  SideMargin := FSidesResizeHeight;
  if SideMargin < MinSideMargin then
      SideMargin := MinSideMargin;


 if (X<SideMargin) then
    FBorderResizeFlag   := FBorderResizeFlag   or 1 // left
 else if (X>=Self.Width-SideMargin) then
    FBorderResizeFlag   := FBorderResizeFlag   or 2; // right

 if (Y>=Self.Height-BottomMargin) then
    FBorderResizeFlag   := FBorderResizeFlag   or 4; // bottom
//
// else if (Y<BottomMargin) then // BottomMargin could also be used for top!
//    FBorderResizeFlag   := FBorderResizeFlag   or 8; // top


if FBorderResizeFlag  =1 then
      Self.Cursor := crSizeWE
 else if FBorderResizeFlag  =2 then
      Self.Cursor := crSizeWE
 else if FBorderResizeFlag  =4 then
      Self.Cursor := crSizeNS
 else if FBorderResizeFlag  =5 then
      Self.Cursor := crSizeNESW // bottom left
 else if FBorderResizeFlag  =6 then
      Self.Cursor := crSizeNWSE // bottom right
 else if FBorderResizeFlag  =8 then
      Self.Cursor := crSizeNS  // up
 else begin
      Self.Cursor := crDefault;
      inherited;
 end;

end;

procedure TResizeBorderControl.SetAutoSize(const Value: Boolean);
begin
  FAutoSize := Value;

  if FAutoSize then begin
    Align := alNone;

    if Self.Left<>0 then
        Self.Left := 0;
    if Self.Width<>Parent.Width then
        Self.Width := Parent.Width;
    if Self.Height<>Parent.Height then
        Self.Width := Parent.Width;

    Anchors := [akLeft, akTop, akRight, akBottom];


  end;


  Invalidate;
end;

procedure TResizeBorderControl.SetAutoSizeStartingAtTop(
  const Value: Integer);
begin
  FAutoSizeStartingAtTop := Value;
end;

procedure TResizeBorderControl.SetBottomResizeHeight(
  const Value: Integer);
begin
  FBottomResizeHeight := Value;
end;

procedure TResizeBorderControl.SetSidesResizeHeight(
  const Value: Integer);
begin
  FSidesResizeHeight := Value;
end;

end.

P.S。请注意,这种事情会产生一些副作用,使其成为“一个整洁的黑客”,但不是我将在现实世界的软件中发布的东西。这是一个玩具。