子ウィンドウの作成1


#include <windows.h>
#define CLASSNAME "MyWindowClass"

// グローバル変数:
HINSTANCE hInst;
// このコード モジュールに含まれる関数の宣言を転送します:
ATOM MyRegisterClass( HINSTANCE );
BOOL InitInstance( HINSTANCE, int );
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
//----------------------------------------------------------------
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
 MSG msg;

 MyRegisterClass( hInstance );
 if ( !InitInstance( hInstance, nCmdShow ) ) return FALSE;

 // メイン メッセージ ループ:
 while ( GetMessage( &msg, NULL, 0, 0 ) ) {
  TranslateMessage( &msg );
  DispatchMessage( &msg );
 }

 return ( int )msg.wParam;
}
//----------------------------------------------------------------
ATOM MyRegisterClass( HINSTANCE hInstance ) {(省略)}
//----------------------------------------------------------------
BOOL InitInstance( HINSTANCE hInstance, int nCmdShow )
{
 HWND hWnd, hWndChild, hWndOwned;

 hInst = hInstance;

 // メインウィンドウ
 hWnd = CreateWindow( CLASSNAME, "Main Window",
  WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
  300, 200, NULL, NULL, hInstance, NULL );
 if ( !hWnd ) return FALSE;

 // 子ウィンドウ
 hWndChild = CreateWindow( CLASSNAME, "Child Window",
  WS_CHILD | WS_CAPTION | WS_VISIBLE,
  0, 0, 150, 100, hWnd, NULL, hInstance, NULL );
 if ( !hWndChild ) return FALSE;

 // 被所有ウィンドウ
 hWndOwned = CreateWindow( CLASSNAME, "Owned Window",
  WS_POPUP | WS_CAPTION | WS_VISIBLE,
  0, 0, 150, 100, hWnd, NULL, hInstance, NULL );
 if ( !hWndOwned ) return FALSE;

 // ウィンドウを表示する
 ShowWindow( hWnd, nCmdShow );
 UpdateWindow( hWnd );

 return TRUE;
}
//----------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) {(省略)}


<親子関係>
ウィンドウ・スタイルにWS_CHILDを指定して、hWndParentに親ウィンドウのハンドルを指定する。
・子ウィンドウは親ウィンドウのクライアント領域の外側に表示したり移動することができない。
・親ウィンドウを移動すると子ウィンドウも一緒に移動する。
・親ウィンドウを最小化すると子ウィンドウも見えなくなる。
・自由に親ウィンドウを変更することができる。

<所有/被所有>
ウィンドウ・スタイルにWS_CHILDを指定せず、hWndParentにオーナー・ウィンドウのハンドルを指定する。
・被所有ウィンドウの移動や表示が、所有ウィンドウの内部に限定されない。
・所有ウィンドウを移動しても被所有ウィンドウは移動しない。
・所有ウィンドウを最小化すると被所有ウィンドウも見えなくなる。
・オーナー・ウィンドウはいったん設定すると、後から変更できない。

071210.jpg
Windows > ウィンドウの作成 | comments (0) | trackbacks (0)

子ウィンドウの作成2

アプリケーションのウィンドウの内部に配置するボタンなどのGUI部品も、
通常は子ウィンドウの形で作ります。


LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
 PAINTSTRUCT ps;
 HDC hdc;
 char str[256];

 static HWND hwButton0, hwButton1;
 static int iMode =0;

 switch (message) {
 case WM_CREATE:
  hwButton0 = CreateWindow( "Button", "Button0", WS_CHILD | WS_VISIBLE, 16, 8, 80, 24, hWnd, ( HMENU )0, hInst, NULL);
  hwButton1 = CreateWindow( "Button", "Button1", WS_CHILD | WS_VISIBLE, 108, 8, 80, 24, hWnd, ( HMENU )1, hInst, NULL);
  break;
 case WM_COMMAND:
  switch ( LOWORD( wParam ) ) { // クリックされたボタン判別
  case 0: // hwButton0
   iMode = 0;
   InvalidateRect( hWnd, NULL, TRUE );
   break;
  case 1: // hwButton1
   iMode = 1;
   InvalidateRect( hWnd, NULL, TRUE );
   break;
  }
  break;
 case WM_PAINT:
  hdc = BeginPaint(hWnd, &ps);
  // TODO: 描画コードをここに追加してください...
  wsprintf( str, "押されたボタンは%d", iMode );
  TextOut( hdc, 16, 40, str, ( int )strlen( str ) );
  EndPaint(hWnd, &ps);
  break;
 case WM_DESTROY:
  PostQuitMessage(0);
  break;
 default:
  return DefWindowProc( hWnd, message, wParam, lParam );
 }
 return 0;
}


ButtonなどWindowsに用意されているGUI部品のウィンドウを作る際には
Windowsにあらかじめ用意されているウィンドウクラスを使います。

追加されたボタンはWM_COMMANDメッセージを送ってきます。
hMenuの値がwParamの下位ワードに入っているので、
この値からクリックされたボタンを特定できます。

070403.jpg
Windows > ウィンドウの作成 | comments (0) | trackbacks (0)

CreateWindowEx関数


HWND CreateWindowEx(
 DWORD dwExStyle,
 LPCTSTR lpClassName,
 LPCTSTR lpWindowName,
 DWORD dwStyle,
 int x,
 int y,
 int nWidth,
 int nHeight,
 HWND hWndParent,
 HMENU hMenu,
 HINSTANCE hInstance,
 LPVOID lpParam
);

拡張ウィンドウ・スタイルを指定して、ウィンドウを作成する為には、CreateWindowの代わりに、その機能拡張版であるCreateWindowExを利用する。
CreateWindowExのプロトタイプは、先頭に拡張ウィンドウ・スタイルを指定するdwExStyleが追加されている点を除けばCreateWindowと同じである。

WS_EX_ACCEPTFILESこのスタイルで作成されたウィンドウでは、ファイルをドラッグ アンド ドロップできます。
WS_EX_APPWINDOW一番上にあるウィンドウを表示するときに、強制的にタスクバーに含みます。
WS_EX_CLIENTEDGEウィンドウを 3 次元で表示することを指定します。つまり、ウィンドウには、くぼんだ境界線が付きます。
WS_EX_CONTEXTHELPウィンドウのタイトル バーに疑問符 (?) を追加します。ユーザーが疑問符 (?) をクリックすると、カーソルがポインタの付いた疑問符 (?) に変わります。続いてユーザーが子ウィンドウをクリックすると、その子ウィンドウが WM_HELP メッセージを受け取ります。
WS_EX_CONTROLPARENTユーザーが、Tab キーを使ってウィンドウ内の子ウィンドウ間を移動できるようにします。
WS_EX_DLGMODALFRAME二重の境界を持つウィンドウを指定します。パラメータ dwStyle に WS_CAPTION スタイル フラグを指定することにより、タイトル バーを追加することもできます。
WS_EX_LEFTウィンドウに汎用左揃えプロパティを指定します。これは、既定の設定です。
WS_EX_LEFTSCROLLBARクライアント領域の左に垂直スクロール バーを配置します。
WS_EX_LTRREADING左から右への読み取り順序でウィンドウのテキストを表示します。これは、既定の設定です。
WS_EX_MDICHILDMDI 子ウィンドウを作成します。
WS_EX_NOPARENTNOTIFYこのスタイルを指定されている子ウィンドウは、作成または破棄されるときに親ウィンドウに WM_PARENTNOTIFY メッセージを送りません。
WS_EX_OVERLAPPEDWINDOWWS_EX_CLIENTEDGE スタイルと WS_EX_WINDOWEDGE スタイルを組み合わせます。
WS_EX_PALETTEWINDOWWS_EX_WINDOWEDGE スタイルと WS_EX_TOPMOST スタイルを組み合わせます。
WS_EX_RIGHTウィンドウに汎用右揃えプロパティを指定します。このスタイルは、ウィンドウ クラスに依存します。
WS_EX_RIGHTSCROLLBARクライアント領域の右に垂直スクロール バー (存在する場合) を配置します。これは、既定の設定です。
WS_EX_RTLREADING右から左への読み取り順序でウィンドウのテキストを表示します。
WS_EX_STATICEDGE3 次元の境界線スタイルを持つウィンドウを作成します。このウィンドウは、ユーザーの入力を受け付けない項目用に使用します。
WS_EX_TOOLWINDOWツール ウィンドウを作成します。このウィンドウは、フローティング ツール バーとして使用します。ツール ウィンドウのタイトル バーは通常よりも短く、ウィンドウのタイトルはより小さいフォントで描画されます。タスク バーや、ユーザーが Alt キーを押しながら Tab キーを押して表示したウィンドウには、ツール ウィンドウは表示されません。
WS_EX_TOPMOSTこのスタイルで作成されたウィンドウは、すべてのウィンドウの上に配置され、アクティブでなくなった場合でも、引き続きほかのウィンドウの上に表示されたままになります。アプリケーションは、SetWindowPos メンバ関数を使って、この属性を追加および削除できます。
WS_EX_TRANSPARENTこのスタイルで作成されたウィンドウは透明になります。つまり、このウィンドウの下にあるウィンドウが見えなくなることはありません。このスタイルで作成されたウィンドウは、そのウィンドウの下にある兄弟ウィンドウがすべて更新された後にだけ、WM_PAINT メッセージを受け取ります。
WS_EX_WINDOWEDGE縁の浮き出した境界線を持つウィンドウを指定します。

・ウィンドウの外見や振る舞いを指定するパラメータには、ウィンドウ・スタイルの他に拡張ウィンドウ・スタイルがある。
これは、Windows95が登場した際に新たに定義されたもので、クライアント領域をウィンドウ枠よりもへこませて立体的に見せるかどうかといった点を指定できる。
・CreateWindowを使ってウィンドウを作成するのは、CreateWindowExの引数dwExStyleに0を指定して呼び出すのと同じである。
Windows > ウィンドウの作成 | comments (0) | trackbacks (0)