ホーム >プログラム >Delphi 6 ローテクTips

フォームの枠あれこれ

メニューバーの高さを取得しようとあれこれやってるときに、フレームのスタイルの組み合わせでフレーム(フォームの枠)が色々変化するのを知りました。
ということでそのおさらい。

当初の目的はフォームの枠の幅と高さを取得したいという趣旨だったのですが、やってるうちに色々なフレームのフォームが作れるというのが分かって面白くなってしまい枠の幅と高さの取得は二の次になってしまいました。

interface

uses
  Windows, SysUtils, Forms, StdCtrls, ExtCtrls, Controls, Classes, Menus;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation


{$R *.dfm}

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  //Params.Style := Params.Style or WS_THICKFRAME;
  //Params.Style := Params.Style or WS_BORDER;
  //Params.Style := Params.Style or WS_DLGFRAME;
  //Params.Style := Params.Style or WS_EX_DLGMODALFRAME;

  //Params.ExStyle := Params.ExStyle or WS_EX_DLGMODALFRAME;
  //Params.ExStyle := Params.ExStyle or WS_EX_WINDOWEDGE;
  //Params.ExStyle := Params.ExStyle or WS_EX_CLIENTEDGE;
  //Params.ExStyle := Params.ExStyle or WS_EX_STATICEDGE;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Close;
end;

これらを色々組み合わせて検証。

フレームのスタイル
WS_EX_DLGMODALFRAME 1
WS_EX_WINDOWEDGE $100
WS_EX_CLIENTEDGE $200
WS_EX_STATICEDGE $20000
WS_THICKFRAME $40000
WS_DLGFRAME $400000
WS_BORDER $800000


bsNone

何もなし。

WS_EX_WINDOWEDGEだけの指定もこれと同じ。
WS_BORDER

1本線。
Windows 3.1の頃のbsSingleがこんな感じだったなぁと。
WS_THICKFRAME

普通のフォームはこれ。

WS_DLGFRAME、WS_EX_DLGMODALFRAMEだけもこれと同じ。
WS_EX_CLIENTEDGE

内側がへこんでる。


WS_EX_STATICEDGE

上のは表示した時の後ろの画像が残ってしまっている状態。
下のが一度他のフォームかぶせてから戻した状態。
このスタイルだけの指定だと最初のフレーム部分のペイントがされないような感じ。
他のスタイルと一緒に指定すればそういうことはない。
WS_BORDER
WS_EX_STATICEDGE
WS_BORDER
WS_EX_CLIENTEDGE
WS_BORDER
WS_EX_CLIENTEDGEWS
WS_EX_STATICEDGE
WS_EX_CLIENTEDGE
WS_EX_STATICEDGE
WS_THICKFRAME
WS_BORDER

WS_THICKFRAMEだけの時より1ドット太い。
WS_THICKFRAME
WS_EX_CLIENTEDGE
WS_THICKFRAME
WS_EX_STATICEDGE
WS_THICKFRAME
WS_EX_CLIENTEDGE
WS_THICKFRAME
WS_EX_WINDOWEDGE

WS_THICKFRAMEだけの時と同じ。
WS_THICKFRAME
WS_BORDER
WS_EX_CLIENTEDGEWS
WS_EX_STATICEDGE

スタイル大盤振る舞い。
一番太い。
WS_THICKFRAME
WS_BORDER
WS_EX_WINDOWEDGE
WS_EX_CLIENTEDGE
WS_EX_STATICEDGE

スタイルてんこ盛り。
一番太くなるかと思いきや、WS_EX_STATICEDGEが効いているせいか右と下が細い。

WS_EX_STATICEDGEだと右と下が1ピクセル小さくなるようです。
WS_BORDERはこれだけだと1ピクセルの1本線。他と組み合わせると1ピクセル太くなるようです。
WS_EX_WINDOWEDGEは組み合わせるスタイルによって変わりなかったり1ピクセル太くなったりするようです。

などという感じなのですが、WS_EX_WINDOWEDGEが組み合わせによって変化しなかったりするのでスタイルを調べて枠の幅、高さを判定するのは容易ではなさそうだなと。
結局はタイトルバーの高さと、フォームのBoundsRectとClientRectの値をスクリーン座標に合わせてからその差でフレームの幅、高さを出すのがいいようです。


2009-01-10