WM_CREATEメッセージ

CreateWindow()関数を使ってウィンドウを生成する時、
ウィンドウプロシージャにはWM_CREATEメッセージが送信されます。
WM_CREATEメッセージはウィンドウが表示される前に、ウィンドウの生成を続けるかどうかを問い合わせています。
WM_CREATEメッセージに対して0を返せばウィンドウの生成を続け、
-1を返せばウィンドウを破棄することを表します。
ウィンドウがWM_CREATEメッセージによって破棄された場合、
CreateWindow()関数は失敗しNULLを返します。
Windows > ウィンドウプロシージャ | comments (0) | trackbacks (0)

WindowProc()関数


LRESULT CALLBACK WindowProc(
 HWND hwnd,
 UINT uMsg,
 WPARAM wParam,
 LPARAM lParam
);

hWndウィンドウを識別するハンドル。
uMsgウィンドウに送られたメッセージ。
wParamメッセージ固有の追加情報。
lParamメッセージ固有の追加情報。


・関数名は自由に命名することができますが、戻り値と引数の型はこれを守らなければなりません。
・ウィンドウプロシージャを呼び出すのはアプリケーションではなくWindowsです。
・メッセージキューに新しいメッセージをエンキューする場合は、メッセージを「Postする」、キューではなく直接プロシージャにメッセージを送る事を「Sendする」と表現します。
・重要ではあるが興味の無いメッセージはDefWindowProc()関数に渡すようにします。
・4つの引数は、いずれもMSG構造体のメンバーに対応しています。MSG構造体のtimeとptメンバーに対応する引数が無いのは、これらの値を利用することがめったにないためと考えれます。必要なら、それぞれGetMessageTime、GetMessagePosというAPIを使って取得します。

記述例

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

 switch ( message ) {
 case WM_PAINT:
  hdc = BeginPaint(hWnd, &ps);
  // TODO: 描画コードをここに追加してください...
  EndPaint(hWnd, &ps);
  break;
 case WM_DESTROY:
  PostQuitMessage(0);
  break;
 default:
  return DefWindowProc(hWnd, message, wParam, lParam);
 }
 return 0;
}

Windows > ウィンドウプロシージャ | comments (0) | trackbacks (0)

MSG構造体


typedef struct tagMSG {
 HWND hwnd;
 UINT message;
 WPARAM wParam;
 LPARAM lParam;
 DWORD time;
 POINT pt;
} MSG;

MSG構造体は、スレッドのメッセージキューからのメッセージ情報を保持します。

hwndメッセージを受け取るウィンドウプロシージャを持つウィンドウを識別します。
messageメッセージ番号を指定します。
wParamメッセージの付加情報を示します。意味はmessageメンバの値によって特定されます。
lParamメッセージの付加情報を示します。意味はmessageメンバの値によって特定されます。
timeメッセージがポストされた時間を示します。
ptメッセージがポストされたときのカーソル位置を画面座標で示します。


一般的なメッセージはwinuser.hの中で、「WM_」で始まるシンボルとして数百個が定義されています。
メッセージはmessageメンバに格納され、そのパラメータがwParamとlParamメンバに格納されます。
WPARAMとLPARAMは単純な整数型ですが、情報が多い場合は構造体へのポインタをパラメータとすることもあります。
Windows > ウィンドウプロシージャ | comments (0) | trackbacks (0)

WM_L(R)BUTTONDOWNメッセージ


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

 switch ( message ) {
 case WM_LBUTTONDOWN:
  wsprintf( str, "左クリックされた" );
  hdc = GetDC( hWnd ); // デバイスコンテキスト生成
  TextOut( hdc, 1, 1, str, lstrlen( str ) );
  ReleaseDC( hWnd, hdc ); // デバイスコンテキスト解放
  break;
 case WM_RBUTTONDOWN:
  wsprintf( str, "右クリックされた" );
  hdc = GetDC( hWnd ); // デバイスコンテキスト生成
  TextOut( hdc, 1, 1, str, lstrlen( str ) );
  ReleaseDC( hWnd, hdc ); // デバイスコンテキスト解放
  break;
 }
 return 0;
}

Windows > ウィンドウプロシージャ | comments (0) | trackbacks (0)

WM_MOUSEMOVEメッセージ


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

 switch ( message ) {
 case WM_MOUSEMOVE:
  xPos = ( int )LOWORD( lParam );
  yPos = ( int )HIWORD( lParam );
  wsprintf( str, "x=%03d y=%03d", xPos, yPos );
  hdc = GetDC( hWnd ); // デバイスコンテキスト生成
  TextOut( hdc, 1, 1, str, lstrlen( str ) );
  ReleaseDC( hWnd, hdc ); // デバイスコンテキスト解放
  break;
 }
 return 0;
}

Windows > ウィンドウプロシージャ | comments (0) | trackbacks (0)

WM_KEYDOWNメッセージ


LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
 HDC hdc; // デバイスコンテキストのハンドル
 static char str[128] = "";
 static int position = 0;

 switch ( message ) {
 case WM_KEYDOWN:
  str[ position++ ] = ( char )wParam;
  hdc = GetDC( hWnd ); // デバイスコンテキスト生成
  TextOut( hdc, 1, 1, str, position );
  ReleaseDC( hWnd, hdc ); // デバイスコンテキスト解放
  break;
 }
 return 0;
}



LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
 PAINTSTRUCT ps;
 HDC hdc;
 static int xPos = 1;
 static int yPos = 1;
 static int delta = 10; // 増減幅
 LPCSTR target = "+";

 switch ( message ) {
 case WM_KEYDOWN:
  switch ( wParam ) {
  case VK_RIGHT:
   xPos += delta;
   InvalidateRect( hWnd, NULL, 1 );
   break;
  case VK_LEFT:
   xPos -= delta;
   InvalidateRect( hWnd, NULL, 1 );
   break;
  case VK_UP:
   yPos -= delta;
   InvalidateRect( hWnd, NULL, 1 );
   break;
  case VK_DOWN:
   yPos += delta;
   InvalidateRect( hWnd, NULL, 1 );
   break;
  }
  break;
 case WM_PAINT: // メイン ウィンドウの描画
  hdc = BeginPaint( hWnd, &ps );
  // TODO: 描画コードをここに追加してください...
  TextOut( hdc, xPos, yPos, target, lstrlen( target ) );
  EndPaint( hWnd, &ps );
  break;
 }
 return 0;
}


InvalidateRectでウインドウのクライアント領域を破棄する命令を
Windowsに対して出します。
WindowsはWM_PAINTメッセージを発行するので、結果として描画できます。
Windows > ウィンドウプロシージャ | comments (0) | trackbacks (0)

WM_PAINTメッセージ


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

 switch ( message ) {
 case WM_PAINT: // メイン ウィンドウの描画
  hdc = BeginPaint( hWnd, &ps );
  // TODO: 描画コードをここに追加してください...
  TextOut( hdc, 1, 1, str, ( int )strlen( str ) );
  EndPaint( hWnd, &ps );
  break;
 }
 return 0;
}


このメッセージは、自分の作成したウインドウが再描画された場合に
使用するメッセージで、プログラマが「ウインドウ画面が再描画されたら〜したい」
という場合にこのメッセージを使用する事になります。

<主にウインドウが再描画される場合>
・ウインドウのサイズを変更した場合
・最初にウインドウが作成されWM_CREATEが検出された後
・自分の作成したウインドウがアクディブ・ウインドウに切り替わった場合
Windows > ウィンドウプロシージャ | comments (0) | trackbacks (0)