WindowハンドルからタイトルバーのRectを知りたい

解決


Fusa  URL  2008-02-12 07:06:29  No: 29777

こんばんは。

質問します。

現在、WindowのタイトルバーのRectを知りたくて
次の関数を作ってます。

function GetBarRect(WinHandle: HWND): TRect;
begin
  //ウインドウサイズ取得
  GetWindowRect(WinHandle, Result) ;
  With Result do
  begin
//    if  Form.BorderStyle in [bsDialog,bsSingle,bsToolWindow] Then
//    //一重線のウインドウ場合
//    begin
//      Right  := Right - GetSystemMetrics(SM_CXSIZEFRAME)+1  ;
//      Left   := Left + GetSystemMetrics(SM_CXSIZEFRAME)-1;
//      Top    := Top + GetSystemMetrics(SM_CYSIZEFRAME)-1;
//    end else
    //二重線のウインドウの場合
    begin
      Right  := Right - GetSystemMetrics(SM_CXSIZEFRAME);
      Left   := Left + GetSystemMetrics(SM_CXSIZEFRAME);
      Top    := Top + GetSystemMetrics(SM_CYSIZEFRAME);
    end;

//    if Form.BorderStyle in [bsToolWindow,bsSizeToolWin] Then
//    //ツールウインドウの場合
//    begin
//      Bottom := Top+GetSystemMetrics(SM_CYSMCAPTION) -1
//    end else
    begin
    //標準のウインドウの場合
      Bottom := Top+GetSystemMetrics(SM_CYCAPTION)-1;
    end;
  end;
end;

上記ではコメントアウトしている部分でFormのBorderStyleの条件から
Rectを求めようとしていますが
私が知りたいのは、ハンドルから求めたいと思っています。

このときに、一重線ウィンドウや、ツールウィンドウかどうかを
ウィンドウハンドルのなんのスタイルから求めればよいでしょうか?

ご存じでしたら教えてください。

よろしくお願いします。


KHE00221  2008-02-12 08:39:43  No: 29778

あえて答えは言わずに・・・・

フォームのスタイルは BorderStyle で設定されているわけで

 property BorderStyle: TFormBorderStyle read FBorderStyle write SetBorderStyle
      stored IsForm default bsSizeable;

つまり SetBorderStyle を見れば分かるわけで・・・・


Fusa  2008-02-12 10:34:25  No: 29779

返事も適宜アドリブで演出ですかっ!(w
ちょっぴり楽したかったのにな〜。


ofZ  2008-02-12 19:59:30  No: 29780

s := GetWindowLong(Handle, GWL_STYLE);

s AND WS_CAPTION > 0 :タイトルあり
s AND WS_THICKFRAME > 0:二重線のウインドウ
s AND WS_THICKFRAME = 0:一重線のウインドウ

s2 := GetWindowLong(Handle, GWL_EXSTYLE);

s2 and WS_EX_TOOLWINDOW > 0:ツールウインドウ
s2 and WS_EX_TOOLWINDOW = 0:標準ウインドウ

このへんじゃないかと。

余談ですが、アクセラレータキーの反応
https://www.petitmonte.com/bbs/answers?question_id=5434
またあとでレスします(^^ゞ


n  2008-02-12 23:20:59  No: 29781

BOOL GetTitleBarInfo(HWND hwnd, PTITLEBARINFO pti); で


Fusa  URL  2008-02-14 01:03:45  No: 29782

ありがとうございます。
次のようにしてできました。

タイトルバー無しのページは、高さを0にしてもいいところですが
今回は、タイトルバー領域とみなして
上部を普通のタイトルバーと同じ分Rectとして取得してみました。

function GetBarRect(WinHandle: HWND): TRect;
var
  Style: Integer;
begin
  //ウインドウサイズ取得
  GetWindowRect(WinHandle, Result) ;
  With Result do
  begin
    Style := GetWindowLong(WinHandle, GWL_STYLE);

    if (Style and WS_THICKFRAME) = 0 then
    //一重線のウインドウ場合
    begin
      Right  := Right - GetSystemMetrics(SM_CXSIZEFRAME)+1  ;
      Left   := Left + GetSystemMetrics(SM_CXSIZEFRAME)-1;
      Top    := Top + GetSystemMetrics(SM_CYSIZEFRAME)-1;
    end else
    //二重線のウインドウかタイトル無しウィンドウの場合
    begin
      Right  := Right - GetSystemMetrics(SM_CXSIZEFRAME);
      Left   := Left + GetSystemMetrics(SM_CXSIZEFRAME);
      Top    := Top + GetSystemMetrics(SM_CYSIZEFRAME);
    end;

    Style := GetWindowLong(WinHandle, GWL_EXSTYLE);
    if (Style and WS_EX_TOOLWINDOW) > 0 then
    //ツールウインドウの場合
    begin
      Bottom := Top+GetSystemMetrics(SM_CYSMCAPTION) -1
    end else
    begin
    //標準のウインドウの場合
      Bottom := Top+GetSystemMetrics(SM_CYCAPTION)-1;
    end;
  end;
end;

>>nさん
教えていただいて、組んだのですが
これ、上記と同じような値は取得できないですね。
function GetBarRect2(WinHandle: HWND): TRect;
var
  TitleBarInfo :TTitlebarInfo;
begin
  GetTitleBarInfo(WinHandle, TitleBarInfo);
  Result := TitleBarInfo.rcTitleBar;
end;

GetTitleBarInfo(Win 98)
http://www.geocities.jp/asumaroyuumaro/program/winapi/window.html#25

Win98用なのかな?
動作確認はXPで行いました。


ばな〜な  2008-02-14 03:01:25  No: 29783

>function GetBarRect2(WinHandle: HWND): TRect;
>var
>  TitleBarInfo :TTitlebarInfo;
>begin
   ZeroMemory(@TitleBarInfo, sizeof(TitleBarInfo));
   // ↓これがなくちゃネ。 ※結果は、スクリーン座標
   TitleBarInfo.cbSize := sizeof(TitleBarInfo);
>  GetTitleBarInfo(WinHandle, TitleBarInfo);
>  Result := TitleBarInfo.rcTitleBar;
>end;

>Win98用なのかな?
そんなBANANA!


ばな〜な  2008-02-14 04:58:01  No: 29784

>>Fusaさん
どのDelphiバージョンをお使いでしょうか?
Windows.pasの中のGetTitleBarInfoの定義はどうなってますか?


Fusa  2008-02-14 10:21:22  No: 29785

ありがとうございます。
下記で動きました。
こちらはタイトルバーの左上のアイコンがあれば
それをのぞいたRectの部分になりますね。

function GetBarRect2(WinHandle: HWND): TRect;
var
  TitleBarInfo :TTitlebarInfo;
begin
  FillChar(TitleBarInfo, SizeOf(TitleBarInfo), 0);
  TitleBarInfo.cbSize := SizeOf(TitleBarInfo);
  GetTitleBarInfo(WinHandle, TitleBarInfo);
  Result := TitleBarInfo.rcTitleBar;
end;

環境はVista、Delphi2007です。


ばな〜な  2008-02-14 21:52:13  No: 29786

GetTitleBarInfo関数が正常に動いてるということは、定義のバグが修正されているわけですね。
実は、Delphiの古いバージョン(D6以前かな?)には、GetTitleBarInfo関数の定義ミスがあって、実行するとエラーになってしまうのです。
「Windows.Pas内のミス定義」
function GetTitleBarInfo; external user32 name 'GetTitleInfo';←関数名の間違い(Barが抜けている単純ミス)

こちら↓が、古いバージョンを使っている場合のエラーの回避策。
http://qc.borland.com/wc/qcmain.aspx?d=6890


Fusa  2008-02-15 05:24:46  No: 29787

だから、宣言について聞く内容だったのですね。

windows.pasはこのようになっています。
修正されたのですね。

function GetTitleBarInfo(hwnd: HWND; var pti: TTitleBarInfo): BOOL; stdcall;

function GetTitleBarInfo; external user32 name 'GetTitleBarInfo';


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加