Eclipse で Win32 API プログラミング (その2)
前回はメッセージボックスを表示しただけなので、今回はウィンドウを表示してみます。
Windowsアプリケーション
前回は触れませんでしたが、Windowsアプリケーションとしてリンクするために、gcc のオプションに -mwindows を指定する必要があります。
Eclipse の場合、以下の方法で gcc のリンカオプションを指定します。
- プロジェクト・エクスプローラでプロジェクト名を右クリック
- 「プロパティー」をクリック
- 設定ウィンドウが開くので、「C/C++ ビルド」->「設定」->「MinGW C Linker」->「その他」にある、「リンカー・フラグ」に -mwindows と入力します
- OKボタンをクリックで完了
コンパイラオプション、リンカオプションなどは、この設定ウィンドウから行うことができます。
空のウィンドウを表示する
ハードディスクを漁ったら、ちょうどいいサンプルが出てきたのでそれを使います。
これは昔どこかのサイトを参考に作ったもので、なにやら処理が関数わけされています。
/* WinMain.c */ #include <windows.h> const char APP_NAME[32] = "Test"; // アプリケーション名 const char CLASS_NAME[32] = "TestWndClass"; // ウィンドウクラス名 HINSTANCE g_hInstance; LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); BOOL RegisterWindowClass(); BOOL CreateAndShowWindow(int nCmdShow); int MessageLoop(); //////////////////////////////////////////////////////////////////// // アプリケーションのエントリポイントです int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // インスタンスハンドルをグローバル変数へ g_hInstance = hInstance; // ウィンドウクラスを登録 if (RegisterWindowClass() == FALSE) { return FALSE; } // ウィンドウを表示 if (CreateAndShowWindow(nCmdShow) == FALSE) { return FALSE; } // メッセージループ return MessageLoop(); } //////////////////////////////////////////////////////////////////// // ウィンドウプロシージャです LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: { PostQuitMessage(0); return 0; } default: { break; } } return DefWindowProc(hWnd, uMsg, wParam, lParam); } //////////////////////////////////////////////////////////////////// // ウィンドウクラスを登録します BOOL RegisterWindowClass() { WNDCLASS wndclass; ZeroMemory(&wndclass, sizeof(WNDCLASS)); wndclass.style = CS_BYTEALIGNWINDOW | CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = g_hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = CLASS_NAME; // ウィンドウクラスを登録 if (RegisterClass(&wndclass) == 0) { return FALSE; } return TRUE; } //////////////////////////////////////////////////////////////////// // ウィンドウを作成して表示します BOOL CreateAndShowWindow(int nCmdShow) { HWND hWnd; // ウィンドウを作成 hWnd = CreateWindow( CLASS_NAME, APP_NAME, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, NULL, NULL, g_hInstance, NULL); if (hWnd == NULL) { return FALSE; } // ウィンドウを表示 ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } //////////////////////////////////////////////////////////////////// // メッセージループです int MessageLoop() { BOOL bRes; MSG stMsg; while (TRUE) { // メッセージをキューから取り出す bRes = GetMessage(&stMsg, NULL, 0, 0); if (bRes == 0 || bRes == -1) { break; // 終了する } TranslateMessage(&stMsg); // メッセージを変換 DispatchMessage(&stMsg); // ウィンドウプロシージャに送る } return stMsg.wParam; }