WTLでエクスプローラ形式のウインドウを作る

test98_01.gif
Windows XPまでのエクスプローラのように左側がツリー、右側がリストビューのウインドウをWTLを利用して作成する。



ATL/WTLアプリケーションウイザードを使ってプロジェクトのひな型を作る。

「ファイル」メニューの「新規作成」から「プロジェクト」を選択して新しいプロジェクトのテンプレートとして「ATL/WTLアプリケーションウイザード」を選択する。

test98_02.gif
アプリケーションウイザードではデフォルトの設定のまま「完了」ボタンを押す。

test98_03.gif
生成したソースコードの中から~View.hを開く。

ここではプロジェクト名を「Test98」としたので「Test98View.h」というファイル名になっている。

test98_04.gif 既存のビュークラスは必要がないので全部消してしまい、リストビュースタイルのCRightViewとツリービュースタイルのCLeftViewを定義する。
class CRightView : public CWindowImpl<CRightView, CListViewCtrl>
{
public:
	DECLARE_WND_SUPERCLASS(NULL, CListViewCtrl::GetWndClassName())

	BOOL PreTranslateMessage(MSG* pMsg)
	{
		pMsg;
		return FALSE;
	}

	BEGIN_MSG_MAP(CRightView)
	END_MSG_MAP()

// ハンドラーのプロトタイプ (引数が必要な場合はコメントを外してください):
//	LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
//	LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
//	LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
};


class CLeftView : public CWindowImpl<CLeftView, CTreeViewCtrl>
{
public:
	DECLARE_WND_SUPERCLASS(NULL, CTreeViewCtrl::GetWndClassName())

	BOOL PreTranslateMessage(MSG* pMsg)
	{
		pMsg;
		return FALSE;
	}

	BEGIN_MSG_MAP(CLeftView)
	END_MSG_MAP()

// ハンドラーのプロトタイプ (引数が必要な場合はコメントを外してください):
//	LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
//	LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
//	LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
};

test98_05.gif
次に「MainFrm.h」を開く。ここでは赤枠で示した部分を書き換えるとともに若干追加する。

test98_06.gif まず先頭部分に1行インクルード設定を追加する。
そして上で示した2箇所の赤枠部分を書き換える。それぞれメンバークラス定義とプリトランスレートのメッセージ処理に当たる。
#include <atlsplit.h>
	CSplitterWindow		_wndSplitter;
	CRightView			_viewRight;
	CLeftView			_viewLeft;
		// 左ペインのPreTranslateMessageを呼び出す
		if(_viewLeft.PreTranslateMessage(pMsg))
			return TRUE;

		// 右ペインのPreTranslateMessageを呼び出す
		return _viewRight.PreTranslateMessage(pMsg);

test98_07.gif
さらに同じく「MainFrm.h」のOnCreate内のビューを作成する部分を次の図のように書き換える。


test98_08.gif ここではもともとあったビューの作成の代わりに、スプリッターウインドウと左右のビューを作成している。
		// スプリッタウィンドウを作成
		_wndSplitter.Create (m_hWnd, rcDefault, NULL,WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);

		// スプリッタウィンドウ拡張スタイルを設定
		_wndSplitter.SetSplitterExtendedStyle(0);

		// 左ペインのビューウィンドウを作成
		_viewLeft.Create(_wndSplitter);
		_wndSplitter.SetSplitterPane(SPLIT_PANE_LEFT,_viewLeft);

		// 右ペインのビューウィンドウを作成
		_viewRight.Create(_wndSplitter, rcDefault, NULL,LVS_REPORT | LVS_SHOWSELALWAYS | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,WS_EX_CLIENTEDGE);
		_wndSplitter.SetSplitterPane(SPLIT_PANE_RIGHT,_viewRight);

		m_hWndClient = _wndSplitter;
		UpdateLayout();

		// 分割バーの位置を設定
		_wndSplitter.SetSplitterPos(250);

test98_09.gif
これで実行するとこのような左右2つの部分に分けられたウインドウになる。

test98_10.gif 上のままでは本当にエクスプローラのようなスタイルのウインドウになっているかどうかわかりづらいのでテスト用のコードをOnCreate内に追加する。
		_viewRight.SetViewType(LVS_REPORT);
		_viewRight.SetExtendedListViewStyle(LVS_EX_INFOTIP | LVS_EX_FULLROWSELECT);
		_viewRight.InsertColumn(0, _T("カラム1"), LVCFMT_LEFT, 190, -1);
		_viewRight.AddItem(0,0,_T("アイテム1"));
		_viewRight.AddItem(1,0,_T("アイテム2"));


		_viewLeft.ModifyStyle(0,TVS_HASLINES);
		HTREEITEM	hItem;
		hItem = _viewLeft.InsertItem(_T("ルート1"),0,0,TVI_ROOT,TVI_ROOT);
		_viewLeft.InsertItem(_T("チャイルド1"),0,0,hItem,hItem);
		_viewLeft.InsertItem(_T("チャイルド2"),0,0,hItem,hItem);
		_viewLeft.Expand(hItem);

test98_11.gif
これで実行するときちんと左側がツリー、右側がリストビューのエクスプローラスタイルのウインドウになっていることが分かる。

プロジェクトファイルをダウンロード


カテゴリー「WTL」 のエントリー