ウィンドウをいじくろう

さて、今回はウィンドウをいろいろいじくります。 具体的には、以下のことをやります。当たり前のことですが基本なので覚えてないと後々面倒です。


1:位置&サイズ変更

ではまずはウィンドウの位置変更&サイズ変更からです。 これだけでもいろいろな関数があります、MoveWindow,SetWindowPlacement,SetWindowPos関数がそうです。 一番よく使われるのはMoveWindowだと思います、これは位置とサイズを変更する手軽な関数です。
SetWindowPlacementは変数にWINDOWPLACEMENT構造体を取り、プログラム起動時に使ったりします。
SetWindowPosは詳細にサイズと位置、さらにZオーダー(ウィンドウの前後関係)まで設定できます。 ここでは最後のSetWindowPos関数を説明します。


BOOL SetWindowPos(
  HWND hWnd,             // 変更したいウィンドウのハンドル
  HWND hWndInsertAfter,  // Zオーダー指定のためのハンドル
  int X,                 // 左上のX位置
  int Y,                 // 左上のY位置
  int cx,                // 横幅
  int cy,                // 高さ
  UINT uFlags            // いろいろなフラグ
);
フラグ系を説明します。
hWndInsertAfter
HWND_BOTTOM ウィンドウを一番後ろにおきます。
最前面ウィンドウの場合は解除されて一番後ろへ行きます。
HWND_NOTOPMOSTウィンドウを最前面ウィンドウじゃなくします。
HWND_TOP ウィンドウを一番前に置きます(最前面ウィンドウからは後ろ)。
HWND_TOPMOST ウィンドウを最前面ウィンドウにします。

uFlags
SWP_DRAWFRAME ウィンドウを囲む枠を描画します。
SWP_FRAMECHANGEDウィンドウサイズが変更されてなくても、WM_NCCALCSIZEを送ります。
SWP_HIDEWINDOWウィンドウを非表示にします。
SWP_NOACTIVATEウィンドウをアクティブ化しません。
SWP_NOCOPYBITSクライアント領域の内容を破棄します。
SWP_NOMOVE 現在の位置を保持し、サイズのみを変更します。(x,yを無視します)
SWP_NOOWNERZORDER オーナーウィンドウのZオーダーを維持します。
SWP_NOREDRAW ウィンドウを再描画しません。
SWP_NOREPOSITION SWP_NOOWNERZORDERと同じです。
SWP_NOSENDCHANGEINGウィンドウにWM_WINDOWPOSCHANGINGを送らないようにします。
SWP_NOSIZE 現在のサイズを保持し、位置のみを変更します。(cx,cyを無視します)
SWP_NOZORDER 現在のZオーダーを保持します。(hWndInsertAfterを無視します)
SWP_SHOWWINDOWウィンドウを表示します。


ちょっとややこしいですが、使える物だけを理解すればOKです。 それにしても高機能な関数ですね、SWP_NOMOVESWP_NOSIZEで、サイズのみ、位置のみを変更できるし、 SWP_HIDEWINDOWSWP_SHOWWINDOWで消したり出したりできるし、HWND_TOPMOSTで最前面ウィンドウにもできます。

2:タイトル変更

さて、お馴染みのタイトル変更です( ̄□ ̄;)!!いまさらでもないですがSetWindowText関数ですね。 似た関数にGetWindowTextがあります、その名の通りウィンドウのタイトルを取得する関数です。簡単ですね。


BOOL SetWindowText(
  HWND hWnd,         // ウィンドウのハンドル
  LPCTSTR lpString   // 文字列
);

int GetWindowText(
  HWND hWnd,        // 取得したいウィンドウのハンドル
  LPTSTR lpString,  // 保存先の文字列
  int nMaxCount     // lpStringの長さ
);

int GetWindowTextLength( // 戻り値はタイトルの長さ
  HWND hWnd   // タイトルの長さを取得したいウィンドウのハンドル
);



3:最大化&最小化&元に戻す

さて、ウィンドウといえば最大化&最小化ですね(?)サイズ変更や位置変更と似ています。 ShowWindow関数を使うと表示方法をいろいろ変更することが出来ます。 IsZoomed関数は最大化ならTRUEを返し、IsIconic関数は最小化してればTRUEを返します。


BOOL ShowWindow(
  HWND hWnd,     // ウィンドウのハンドル
  int nCmdShow   // どう表示するか
);

BOOL IsZoomed( // 最大化してればTRUE
  HWND hWnd   // ウィンドウのハンドル
);

BOOL IsIconic( // 最小化してればTRUE
  HWND hWnd   // ウィンドウのハンドル
);
nCmdShow
SW_HIDE ウィンドウを非表示にします。
SW_MAXIMIZEウィンドウを最大化します。
SW_MINIMIZEウィンドウを最小化します。
SW_RESTORE ウィンドウを元の大きさに戻します。
SW_SHOW ウィンドウを表示します。
SW_SHOWDEFAULT CreateProcess関数で起動したとき、そこから渡された値を元に表示します。
SW_SHOWMAXIMIZEDウィンドウをアクティブにして、最大化します。
SW_SHOWMINIMIZEDウィンドウをアクティブにして、最小化します。
SW_SHOWMINNOACTIVEウィンドウを最小化します。非アクティブウィンドウそのまま最小化します。
SW_SHOWNA ウィンドウを現在の状態で表示します。
SW_SHOWNOACTIVATE ウィンドウを直前の位置とサイズで表示します。
SW_SHOWNORMAL ウィンドウを元に戻して表示します。

これで最大化&最小化を自由自在に出来ますね。この関数でも表示、非表示を行えます。

4:おまけいろいろ

ウィンドウの操作は他にもいろいろあります。ここではいろいろ紹介します。 GetDesktopWindowはデスクトップウィンドウのハンドルを取得します。デスクトップもウィンドウの一部なんですね。 SetForegroundWindow関数は、指定したウィンドウをフォアグラウンド、つまりアクティブにします。 EnableWindow関数は、その名の通りウィンドウを有効や無効にします。 有効、無効というのはキーボードやマウスの入力を受け取るかどうかです。普通のウィンドウは有効になってますね。


HWND GetDesktopWindow(VOID) // デスクトップウィンドウのハンドルが返ります。

HWND GetForegroundWindow(VOID) // フォアグラウンドのウィンドウのハンドルが返ります。

BOOL SetForegroundWindow(
  HWND hWnd   // フォアグラウンドにしたいウィンドウのハンドル
);

BOOL EnableWindow(
  HWND hWnd,     // ウィンドウのハンドル
  BOOL bEnable   // 有効ならTRUE、無効ならFALSE。
);

BOOL IsWindowEnabled( // 有効ならTRUE
  HWND hWnd   // ウィンドウハンドル
);



5:ウィンドウのサイズいろいろ

ウィンドウには見ての通りサイズがあります、これを取得するときには次の関数を使います。 GetClientRect関数は、指定したウィンドウのクライアント領域の矩形、つまり四角形を取得できます。 GetWindowRect関数はそれに似たもので、ウィンドウのサイズをRECT構造体に取得できます。 AdjustWindowRectEx関数は、RECT構造体に設定したいクライアント領域のサイズをいれ、ウィンドウのスタイルなどをセットして呼び出すと、 そのRECT構造体に目的のクライアント領域サイズに設定するためのウィンドウのサイズがかえって来るという物です。 ややこしいですが実際に使ってみると分かると思うので後で使ってみます。


BOOL GetClientRect(
  HWND hWnd,      // ウィンドウのハンドル
  LPRECT lpRect   // クライアント領域の矩形を受け取るRECT構造体のポインタ
);

BOOL GetWindowRect(
  HWND hWnd,      // ウィンドウのハンドル
  LPRECT lpRect   // クライアント領域の矩形を受け取るRECT構造体のポインタ
);

BOOL AdjustWindowRectEx(
  LPRECT lpRect,    // セットしたいクライアント領域サイズ
  DWORD dwStyle,    // ウィンドウのスタイル
  BOOL bMenu,       // メニューの有無
  DWORD dwExStyle   // 拡張ウィンドウスタイル
);

ところで初登場のRECT構造体とは何でしょうか?これは上下左右を持っている構造体で、矩形を表すのに使います。 主にGDIというグラフィック描画のときに使用します。他にもPOINT構造体SIZE構造体などがありますが、GDIのときに説明します。

ではさっき言ったとおり、AdjustWindowRect関数で目的のクライアント領域サイズに設定してみようと思います。 また、GetWindowRect関数などいろいろな関数を使用して画面の中央に表示してみようと思います。 ソースコードの一部(要点だけ)をひょうじします。tipsって感じですね。


	// ウィンドウサイズを設定
	RECT rc={0,0,256,256};
	AdjustWindowRectEx(&rc,WS_OVERLAPPEDWINDOW,TRUE,NULL);

	int cx=rc.right  - rc.left;
	int cy=rc.bottom - rc.top ;
	SetWindowPos(hwnd,HWND_TOP,0,0,cx,cy,SWP_NOMOVE);

	// ウィンドウを画面中央に表示
	HWND hwndDesk=GetDesktopWindow();

	RECT rcDesk,rcWnd;
	GetWindowRect(hwndDesk,&rcDesk);
	GetWindowRect(hwnd    ,&rcWnd );

	int x=rcDesk.right /2 - rcWnd.right /2;
	int y=rcDesk.bottom/2 - rcWnd.bottom/2;

	SetWindowPos(hwnd,HWND_TOP,x,y,0,0,SWP_NOSIZE);

DownLoad!サンプルソースファイルをDownLoad!

解説しますと、AdjustWindowRectで目的のクライアント領域サイズをセットしたRECTを渡し、戻ってきたRECTで(このためにポインタで渡してます) SetWindowPosをNOMOVE(移動しない)設定でウィンドウサイズを設定しているわけです。こうすればクライアント領域サイズが256*256になります。

次の画面中央表示は、デスクトップのサイズと自分のウィンドウのサイズを取得し、ちょっとした計算をして(なぜこうなるかは考えてね) それを今度はNOSIZE(サイズはそのまま)で、ウィンドウの位置を設定しているわけです。

さぁ今回はどうだったかな? 次回はアイドル処理(基本?)とかクラス化(本格的!)をやります。ではまたっ( ̄□ ̄;)


★INDEX★

Copyright(C) へぽぽ