まずはじめに、WTLを使わずにATLだけを使ってテンプレートライブラリによる
Windowsプログラミングの基本を見てみたいと思います。
ATLにおける最も基本的なウィンドウ関連クラスはCWindowです。
CWindowクラスはウィンドウハンドルをカプセル化し、ウィンドウに関するWin32APIをラップする
多くのメンバ関数を持ちます。これはちょうどMFCのCWndクラスと似ています。
CWindowでウィンドウを作成するには、Create()を使ったり、既存のウィンドウハンドルを
Attach()でアタッチする必要があります。
ところで、CWindowクラスはメッセージへの反応を定義することはできません。
ここで、もしMFCならばCWndの派生クラスを作り、例えばWM_CREATEメッセージへの反応を
定義するためにはOnCreate()をオーバーライドするところですが、
ATLでは、CWindowImplという名前のクラステンプレートから派生クラスを作り、そのクラス内で
メッセージへの応答を定義します。
以下の示すのは、ウィンドウ中央に「Hello, ATL/WTL」と表示するだけの簡単なプログラムのソースコードです。
このプログラムでは、CWindowImplクラステンプレートから派生クラスCMainWindow(これがメインウィンドウとなります)を作り、
CMainWindowクラス内でWM_PAINTメッセージとWM_DESTROYメッセージへの応答を定義します。
なお、このプログラムは「Win32 プロジェクト」でビルドします。
// stdafx.h
#pragma once
#include <atlbase.h>
#include <atlwin.h>
|
// MainWindow.h
#pragma once
// CWindowImplの派生クラスでメッセージへの反応を定義
class CMainWindow : public CWindowImpl<CMainWindow>
{
public:
// ウィンドウクラス名を登録
DECLARE_WND_CLASS(_T("Hello"));
// メッセージマップ
BEGIN_MSG_MAP(CMainWindow)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
END_MSG_MAP()
LRESULT OnPaint(UINT, WPARAM, LPARAM, BOOL&){
PAINTSTRUCT ps;
HDC hDC = BeginPaint(&ps);
RECT rect;
GetClientRect(&rect);
DrawText(hDC, _T("Hello, ATL/WTL"),
-1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(&ps);
return 0;
}
LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL&){
PostQuitMessage(0);
return 0;
}
};
|
// SampleProject.cpp
#include "stdafx.h"
#include "MainWindow.h"
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// 独自ウィンドウを作成
CMainWindow wnd;
wnd.Create(NULL, CWindow::rcDefault,
_T("Hello, ATL/WTL"), WS_OVERLAPPEDWINDOW | WS_VISIBLE);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
|
まず、stdafx.hヘッダではATLを使用するためにatlbase.hヘッダとatlwin.hヘッダをインクルードします。
CMainWindowクラスはCWindowImplクラステンプレートから派生していますが、CWindowImplの第1テンプレート引数にも
CMainWindowという名前を渡します(第2、第3テンプレート引数は省略可能です。ここでは省略しています。)。
CMainWindowクラスでは、DECLARE_WND_CLASSマクロでウィンドウクラス名を登録し、
メッセージマップでメッセージとそれに対するハンドラ関数を結びつけます。
今回の例では、ハンドラ関数内の処理はSDKスタイルとほぼ同等です。
|