ここで、雛形を作ります。 仮想関数を利用します。
メンバーが仮想関数の 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" に書く。