C言語だけでプログラムを書くことができます。 しかし、C++を混ぜてもコンパイルできます。 特に、クラスを使いたいので、クラスの説明をします。
WNDCLASSEX構造体は、次のように定義されています。
typedef struct { UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; HICON hIconSm; } WNDCLASSEX;
これは、よくあるWindowsプログラムに出てきました。 これを例に使って説明していきます。
さて、C++になって、C言語の構造体は大幅に拡張されました。 まず、次のように書くことができます。
struct WNDCLASSEX{
UINT cbSize;
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
HICON hIconSm;
};
変数宣言は次のようにします。
WNDCLASSEX wc;
このため、wc は、WNDCLASSEX型の変数といいます。 WNDCLASSEX構造体の変数ともいいます。
メンバーにアクセスするのはC言語と同じで、ドット"."を使います。
wc.lpszClassName = "win125";
話はそれますが、文字コードが unicode の場合、次のように "L" を付けて書かなければいけません。
wc.lpszClassName = L"win125";
また、TEXT() マクロを使い、次のように書きます。
wc.lpszClassName = TEXT("win125");
さて、C++では struct だけでなく、class と書くこともできます。
class WNDCLASSEX{
UINT cbSize;
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
HICON hIconSm;
};
struct と class をあわせてクラスといいます。 C++ では、構造体とクラスは同じです。 ただ、新しい書き方では class を使うのが一般的です。
次は、"public:" と "private:" が導入されました。 "private:" を使うと、クラスの外から見えなくなります。 "public:" は、その逆です。 ところで、これを省略して書くと、struct の場合は public、class の場合は private になります。 この点を除いて、struct と class は同じです。
class WNDCLASSEX{ public: UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; private: HBRUSH hbrBackground; LPCTSTR lpszMenuName; public: LPCTSTR lpszClassName; HICON hIconSm; };
"private:" の後のメンバーは、このクラスの外からアクセスできません。 ですから、つぎのように書けばコンパイルエラーとなります。
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
これでは意味がないように思えますが、 クラスでは、メンバーに関数も入れることができます。 これをメソッドといいます。 では、"BackColor" というメソッドを作ってみます。
class WNDCLASSEX{
public:
UINT cbSize;
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
private:
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
public:
LPCTSTR lpszClassName;
HICON hIconSm;
void BackColor(HBRUSH col){
hbrBackground = col;
}
};
メソッドは、普通の関数と同じように書きます。 使うときも、他のメンバーと同じように使います。
wc.BackColor((HBRUSH)(COLOR_BACKGROUND + 1));
これで、hbrBackground の値を変えることができます。
次は、別名です。WNDCLASSEX型を、MyWndClass型として使うときは、継承という機能を使います。 次のように書きます。
// MyWndClass クラス
class MyWndClass : public WNDCLASSEX{
};
MyWndClass クラスは、WNDCLASSEX 構造体と同じメンバーを持ちます。 このとき、WNDCLASSEX をスーパークラスとか、親クラスといいます。 MyWndClass の方は、子クラスといいます。 さらに、子クラスでは、メンバーを追加することができます。
次は、コンストラクタです。 変数宣言時に、自動で1度だけ実行してくれます。 必ず、public にして次のように書きます。 クラス名を用いて、関数のように書きます。 引数も付けることができます。
class MyWndClass : public WNDCLASSEX{ public: // コンストラクタ MyWndClass(LPCTSTR AppName){ // ウィンドウの定義 cbSize = sizeof(WNDCLASSEX); // WNDCLASSEXのサイズ style = 0; // 拡張スタイル lpfnWndProc = WndProc; // ウィンドウプロシージャ cbClsExtra = 0; // 追加領域 cbWndExtra = 0; // 追加領域 hInstance = hInst; // インスタンス hIcon = LoadIcon(NULL,IDI_APPLICATION); // アイコン hCursor = LoadCursor(NULL,IDC_ARROW); // カーソル hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); // 背景ブラシ lpszMenuName = NULL; // メニュー lpszClassName = AppName; // クラス名 hIconSm = LoadIcon(NULL, IDI_WINLOGO); // 小さなアイコン } };
ですから、メンバーの初期化に使えます。 上の場合、よくあるWindowsプログラムと同じ値を代入しました。 また、アプリケーション名を引数にしました。
変数の宣言は、次のように書きます。 引数があるので、変な感じがします。 この時点で自動的にコンストラクタを実行するので、よくあるWindowsプログラムと同じ値になります。
MyWndClass wc(TEXT("win125"));
使うときは構造体と同じで、ドット"." を使って、wc.style のように使います。
さて、上のように書く以外に、宣言だけ書いて、中身は外に書くこともできます。 外に書くときは、かならず "MyWndClass::" を付けます。
class MyWndClass : public WNDCLASSEX{ public: // コンストラクタ MyWndClass(LPCTSTR AppName); }; //-------------------------------------------------------------------------------------- // コンストラクタ MyWndClass::MyWndClass(LPCTSTR AppName){ // ウィンドウの定義 cbSize = sizeof(WNDCLASSEX); // WNDCLASSEXのサイズ style = 0; // 拡張スタイル lpfnWndProc = WndProc; // ウィンドウプロシージャ cbClsExtra = 0; // 追加領域 cbWndExtra = 0; // 追加領域 hInstance = hInst; // インスタンス hIcon = LoadIcon(NULL,IDI_APPLICATION); // アイコン hCursor = LoadCursor(NULL,IDC_ARROW); // カーソル hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); // 背景ブラシ lpszMenuName = NULL; // メニュー lpszClassName = AppName; // クラス名 hIconSm = LoadIcon(NULL, IDI_WINLOGO); // 小さなアイコン }
このように書けば、2つのファイルに分割することができます。 ファイル名は、"MyWndClass.h" と "MyWndClass.cpp"とすればわかり易いです。