ここで、雛形を作ります。 仮想関数を利用します。
メンバーが仮想関数の MyMainWnd クラスを作ります。 ファイル名は、"MyMainWnd.h" です。 必要になったら、メンバーを増やします。 減らすことはしません。 これは、"include" フォルダへ保存します。
#pragma once /* メインウィンドウ */ #include <MyWndClass.h> #include <MyCreateStruct.h> class MyMainWnd{ public: // WNDCLASSEX用 virtual void setMyWnd(MyWndClass& wc, MyCreateStruct& cs){} virtual void wmCreate(){} // DlgMain用 virtual void wmInitDialog(){} // 共通 virtual void wmClose(){} virtual void wmPaint(HDC hdc){} virtual void wmCommand(WPARAM wp){} // メニュー virtual void OnMenuAbout(){} };
次は、WinMain 関数が入った "MyDlgMain.cpp" です。 これは、"src" フォルダへ保存します。
//
// Windows プログラム
//
#include <windows.h>
#include <tchar.h>
#include "resource.h"
#include <MyAboutBox.h>
#include <MyMainWnd.h>
#include "MyApp.h"
// グローバル変数
MyApp wnd;
// ダイアログプロシージャ
INT_PTR CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
// アプリケーション開始位置
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int nCmdShow)
{
hInst = hInstance; // インスタンスハンドル保存
DialogBox(hInst, L"MyDlgMain", NULL, DlgProc);
}
// ダイアログプロシージャ
INT_PTR CALLBACK DlgProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
hWnd = hwnd; // ウィンドウハンドル保存
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (msg)
{
case WM_INITDIALOG:
wnd.wmInitDialog();
wnd.wmCreate();
return (INT_PTR)TRUE;
case WM_CLOSE:
wnd.wmClose();
EndDialog(hWnd, LOWORD(wp));
return (INT_PTR)TRUE;
break;
case WM_COMMAND:
wmId = LOWORD(wp);
switch(wmId)
{
case IDM_EXIT:
SendMessage(hWnd, WM_CLOSE, 0, 0L);
return (INT_PTR)TRUE;
case IDM_ABOUT:
DialogBox(hInst, L"MyAboutBox", hWnd, About);
return (INT_PTR)TRUE;
default:
wnd.wmCommand(wmId);
return (INT_PTR)TRUE;
}
return (INT_PTR)TRUE;
case WM_TIMER:
InvalidateRect(hWnd, NULL, FALSE);
return (INT_PTR)TRUE;
case WM_SIZE:
InvalidateRect(hWnd, NULL, FALSE);
return (INT_PTR)TRUE;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
wnd.wmPaint(hdc);
EndPaint(hWnd, &ps);
return (INT_PTR)TRUE;
}
return (INT_PTR)FALSE;
}
MyWndMain.cpp
/* よくあるウィンドウズプログラム */ #include <windows.h> #include <tchar.h> #include "Resource.h" // メインウィンドウ #include <MyMainWnd.h> // アプリケーション #include "MyApp.h" #define MAX_LOADSTRING 100 // グローバル変数 MyApp wnd; // アプリケーション開始位置 int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int nCmdShow) { hInst = hInstance; // インスタンスハンドル保存 TCHAR AppName[MAX_LOADSTRING]; // メインウィンドウのクラス名 TCHAR AppTitle[MAX_LOADSTRING]; // タイトル // リソース LoadString(hInst, IDC_APP_NAME, AppName, MAX_LOADSTRING); LoadString(hInst, IDS_APP_TITLE, AppTitle, MAX_LOADSTRING); MSG msg; // MSG構造体 MyWndClass wc(AppName); // WNDCLASSEX構造体 MyCreateStruct cs; // CREATESTRUCT構造体 HACCEL hAccelTable; cs.Name(AppName); // クラス名 cs.Text(AppTitle); // キャプション // ToDo ウィンドウの定義 wnd.setMyWnd(wc, cs); // ウインドウクラスの登録 if(RegisterClassEx(&wc) == 0) return 0; // ウインドウの作成 hWnd = cs.Create(); if(hWnd == NULL) return 0; // ウィンドウの表示 ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDC_APP_NAME)); // メッセージループ while(GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)){ TranslateMessage(&msg); DispatchMessage(&msg); } } return msg.wParam; } // ウインドウプロシージャ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { hWnd = hwnd; // ウィンドウハンドル保存 int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch(msg) { case WM_COMMAND: wmId = LOWORD(wp); wmEvent = HIWORD(wp); // 選択されたメニューの解析: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, L"MyAboutBox", hWnd, About); break; case IDM_EXIT: SendMessage(hWnd, WM_CLOSE, 0, 0L); break; default: wnd.wmCommand(wp); break; } break; case WM_CREATE: wnd.wmCreate(); break; case WM_TIMER: InvalidateRect(hWnd, NULL, FALSE); break; case WM_SIZE: InvalidateRect(hWnd, NULL, FALSE); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); wnd.wmPaint(hdc); EndPaint(hWnd, &ps); break; case WM_CLOSE: wnd.wmClose(); DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); // メッセージループの終了 break; default: return DefWindowProc(hWnd, msg, wp, lp); // 既定のウィンドウプロシージャ } return 0; }
resource.h
#ifndef IDC_STATIC #define IDC_STATIC (-1) #endif #define IDC_APP_NAME 40000 #define IDM_EXIT 40000 #define IDM_ABOUT 40001 #define IDS_APP_TITLE 40001
win137.rc
#include <windows.h> #include "resource.h" // // Menu resources // MyMenu MENU BEGIN POPUP "ファイル(&F)" BEGIN MENUITEM "終了(&X)", IDM_EXIT END POPUP "ヘルプ(&H)" BEGIN MENUITEM "バージョン情報(&A)", IDM_ABOUT END END // // Dialog resources // MyAboutBox DIALOG 0, 0, 186, 95 STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU CAPTION "バージョン情報" FONT 8, "Ms Shell Dlg" BEGIN DEFPUSHBUTTON "OK", IDOK, 129, 7, 50, 14 LTEXT "win117, Version 1.0", IDC_STATIC, 39, 43, 114, 8, SS_LEFT | SS_NOPREFIX LTEXT "Copyright (C) 2010", IDC_STATIC, 39, 55, 114, 8, SS_LEFT END MyDlgMain DIALOG 0, 0, 186, 95 STYLE DS_3DLOOK | DS_CENTER | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_GROUP | WS_TABSTOP | WS_THICKFRAME | WS_SYSMENU CAPTION "Windowsプログラム" FONT 9, "MS UI Gothic" BEGIN END // // String Table resources // STRINGTABLE BEGIN IDC_APP_NAME "win00" IDS_APP_TITLE "よくある Windows プログラム" END
ウィンドウメッセージを処理するためのメソッドです。 この後、メソッドは増えていきますが減らすことはしません。 それは、仮想関数だから、増えても困らないのです。
WinMain関数の入ったものです。 ダイアログボックス版とWNDCLASSEX構造体を使った2つあります。 どちらかを選んで使います。 これを共通ファイルフォルダ "src" に保存し、BccDeveloper では、追加します。
MyMainWndクラスを継承した MyApp クラスの変数を用意しました。
// グローバル変数 MyApp wnd;
そして、必要なところにメンバーをおきます。 ですから、MyApp クラスを作らなければいけません。 しかし、このファイルも追加はあっても減ることはしません。 これで、前に作ったアプリケーションにも影響を与えません。 ですから、雛形として使えます。
では、"MyApp.h" を作ります。ファイル名はこれでなければいけません。 メニューの付いたアプリケーションです。 ところで、"MyWndMain.cpp" と "MyDlgMain.cpp" のどちらかを追加します。 どちらでも動きます。
// // MyApp.h // class MyApp : public MyMainWnd{ public: };
実行画面です。
勿論、本体用に、"MyApp.cpp" を作ってもいいでしょう。
フォルダは次のようでした。
"include" と "src" フォルダには、共通となるファイルを保存します。 "win111" などは、アプリケーションごとのフォルダです。 プロジェクトのフォルダということです。 ここには、"resource.h"、"***.rc"、"MyApp.h" を保存することになりました。
新しくアプリケーションを作るときは次のようになります。
"win137" フォルダにある、"MyApp.h"、"resource.h"、"win137.rc" をコピーする。 リソースファイルの名前を変える。 プログラムは、"MyApp.h" に書く。