メインウィンドウ

ここで、雛形を作ります。 仮想関数を利用します。

雛形

共通ファイル

メンバーが仮想関数の 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

解説

MyMainWnd.h

ウィンドウメッセージを処理するためのメソッドです。 この後、メソッドは増えていきますが減らすことはしません。 それは、仮想関数だから、増えても困らないのです。

MyDlgMain.cpp と MyWndMain.cpp

WinMain関数の入ったものです。 ダイアログボックス版とWNDCLASSEX構造体を使った2つあります。 どちらかを選んで使います。 これを共通ファイルフォルダ "src" に保存し、BccDeveloper では、追加します。

MyMainWndクラスを継承した MyApp クラスの変数を用意しました。

// グローバル変数
MyApp wnd;

そして、必要なところにメンバーをおきます。 ですから、MyApp クラスを作らなければいけません。 しかし、このファイルも追加はあっても減ることはしません。 これで、前に作ったアプリケーションにも影響を与えません。 ですから、雛形として使えます。

使用例(win137)

では、"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" に書く。


[前] [目次] [次]