ズームスクロールウィンドウ
ズームスクロールウィンドウとは、ズームイン/ズームアウト機能を備えたスクロールウィンドウのことです。WTLはズームスクロールウィンドウを作成するためにCZoomScrollWindowImplを用意しています。
次に示すのは、先ほどペインコンテナを追加したプログラムの右ペインを、ズームスクロールウィンドウに変更した例です。メニューで[ズームイン](または[ズームアウト])を選択してビューウィンドウをクリックすると、フォントがズームイン(またはズームアウト)表示されます。


#include <atlbase.h> #include <atlapp.h> extern CAppModule _Module; #include <atlwin.h> #include <atlcrack.h> #include <atlmisc.h> #include <atlctrls.h> #include <atlctrlx.h> #include <atlctrlw.h> #include <atlframe.h> #include <atlsplit.h> #include <atlscrl.h> // CZoomScrollWindowImplを使用するため
class CFontPreviewView : public CZoomScrollWindowImpl<CFontPreviewView> { CString m_strFontName; public: BOOL PreTranslateMessage(MSG* pMsg){ return FALSE; } // メッセージマップ BEGIN_MSG_MAP_EX(CFontPreviewView) MSG_WM_CREATE(OnCreate) CHAIN_MSG_MAP(CZoomScrollWindowImpl<CFontPreviewView>) END_MSG_MAP() LRESULT OnCreate(LPCREATESTRUCT lpcs){ LRESULT lRet = DefWindowProc(); SetScrollSize(640, 480); SetScrollLine(10, 10); SetScrollPage(100, 100); SetMsgHandled(false); return lRet; } void DoPaint(CDCHandle dc){ // サイズ20ポイントのフォントを作成し、選択 CFont font; font.CreatePointFont(200, m_strFontName); HFONT hOldFont = dc.SelectFont(font); // ビューウィンドウにフォント名を描画 CSize size; GetScrollSize(size); CRect rect(0, 0, size.cx, size.cy); dc.DrawText(m_strFontName, -1, rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); // 元のフォントを選択 dc.SelectFont(hOldFont); } void SetFontName(LPCTSTR lpszFontName){ m_strFontName = lpszFontName; Invalidate(); } };
class CMainFrame : public CFrameWindowImpl<CMainFrame>, public CUpdateUI<CMainFrame>, public CMessageFilter, public CIdleHandler { public: DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME) CSplitterWindow m_wndSplitter; // スプリッタウィンドウ CPaneContainer m_painContainer; // ペインコンテナ CFontListView m_viewFontList; // 左ペイン CFontPreviewView m_viewFontPreview; // 右ペイン CCommandBarCtrl m_CmdBar; // コマンドバー CMultiPaneStatusBarCtrl m_wndStatusBar; // マルチステータスバー virtual BOOL PreTranslateMessage(MSG* pMsg){ if(CFrameWindowImpl<CMainFrame>::PreTranslateMessage(pMsg)) return TRUE; // 左ペインのPreTranslateMessageを呼び出す if(m_viewFontList.PreTranslateMessage(pMsg)) return TRUE; // 右ペインのPreTranslateMessageを呼び出す return m_viewFontPreview.PreTranslateMessage(pMsg); } virtual BOOL OnIdle(){ UIUpdateToolBar(); UIUpdateStatusBar(); CString strCount; strCount.Format(_T("フォント数:%d"), m_viewFontList.GetCount()); m_wndStatusBar.SetPaneText(IDS_PANE_COUNT, strCount); return FALSE; } BEGIN_UPDATE_UI_MAP(CMainFrame) UPDATE_ELEMENT(ID_MENUITEM_CHANGEVIEW, UPDUI_MENUPOPUP | UPDUI_TOOLBAR) UPDATE_ELEMENT(ID_MENUITEM_ZOOMIN, UPDUI_MENUPOPUP | UPDUI_TOOLBAR) UPDATE_ELEMENT(ID_MENUITEM_ZOOMOUT, UPDUI_MENUPOPUP | UPDUI_TOOLBAR) END_UPDATE_UI_MAP() BEGIN_MSG_MAP_EX(CMainFrame) MSG_WM_CREATE(OnCreate) COMMAND_CODE_HANDLER_EX(LBN_SELCHANGE, OnListSelChange) COMMAND_ID_HANDLER_EX(ID_PANE_CLOSE, OnMenuChangeView) COMMAND_ID_HANDLER_EX(ID_MENUITEM_CHANGEVIEW, OnMenuChangeView) COMMAND_ID_HANDLER_EX(ID_MENUITEM_ZOOMIN, OnMenuZoomIn) COMMAND_ID_HANDLER_EX(ID_MENUITEM_ZOOMOUT, OnMenuZoomOut) COMMAND_ID_HANDLER_EX(ID_APP_EXIT, OnFileExit) CHAIN_MSG_MAP(CUpdateUI<CMainFrame>) CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>) END_MSG_MAP() LRESULT OnCreate(LPCREATESTRUCT lpcs){ // コマンドバーを作成 HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE); // コマンドバーに現在のメニューバーのアイテムと画像をセット m_CmdBar.AttachMenu(GetMenu()); m_CmdBar.LoadImages(IDR_MAINFRAME); // メニューバーを削除 SetMenu(NULL); // ツールバーを作成 HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE); // リバーを作成 CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE); // リバーのバンドにコマンドバーとツールバーを追加 AddSimpleReBarBand(hWndCmdBar); AddSimpleReBarBand(hWndToolBar, NULL, TRUE); // ステータスバーを作成 m_hWndStatusBar = m_wndStatusBar.Create(m_hWnd); int nPanes[] = {ID_DEFAULT_PANE, IDS_PANE_COUNT}; m_wndStatusBar.SetPanes(nPanes, sizeof(nPanes)/sizeof(nPanes[0])); UIAddToolBar(hWndToolBar); UIAddStatusBar(m_hWndStatusBar); UISetCheck(ID_MENUITEM_CHANGEVIEW, 1); UISetCheck(ID_MENUITEM_ZOOMIN, 1); UISetCheck(ID_MENUITEM_ZOOMOUT, 0); // スプリッタウィンドウを作成 m_wndSplitter.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); // スプリッタウィンドウ拡張スタイルを設定 m_wndSplitter.SetSplitterExtendedStyle(0); // ペインコンテナを作成 m_painContainer.Create(m_wndSplitter, _T("フォント名")); // 左ペインのビューウィンドウを作成 m_viewFontList.Create(m_painContainer, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VSCROLL | LBS_NOINTEGRALHEIGHT | LBS_NOTIFY | LBS_WANTKEYBOARDINPUT | LBS_SORT, WS_EX_CLIENTEDGE); m_painContainer.SetClient(m_viewFontList); m_wndSplitter.SetSplitterPane(SPLIT_PANE_LEFT, m_painContainer); // 右ペインのビューウィンドウを作成 m_viewFontPreview.Create(m_wndSplitter, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE); m_viewFontPreview.SetZoomMode(ZOOMMODE_IN); m_wndSplitter.SetSplitterPane(SPLIT_PANE_RIGHT, m_viewFontPreview); m_hWndClient = m_wndSplitter; UpdateLayout(); // 分割バーの位置を設定 m_wndSplitter.SetSplitterPos(120); // メッセージループにメッセージフィルタとアイドルハンドラを追加 CMessageLoop* pLoop = _Module.GetMessageLoop(); pLoop->AddMessageFilter(this); pLoop->AddIdleHandler(this); return 0; } void OnListSelChange(UINT uNotifyCode, int nID, HWND hWndCtl){ // 現在選択されているアイテムを取得 int nIndex = m_viewFontList.GetCurSel(); if(nIndex != LB_ERR){ CString strText; m_viewFontList.GetText(nIndex, strText); // 取得した文字列を右ペインに設定 m_viewFontPreview.SetFontName(strText); } } void OnMenuChangeView(UINT uNotifyCode, int nID, HWND hWndCtl){ if(m_wndSplitter.GetSinglePaneMode() == SPLIT_PANE_RIGHT){ // 両ペイン表示 m_wndSplitter.SetSinglePaneMode(SPLIT_PANE_NONE); UISetCheck(ID_MENUITEM_CHANGEVIEW, 1); }else{ // 右ペインのみ表示 m_wndSplitter.SetSinglePaneMode(SPLIT_PANE_RIGHT); UISetCheck(ID_MENUITEM_CHANGEVIEW, 0); } } void OnMenuZoomIn(UINT uNotifyCode, int nID, HWND hWndCtl){ m_viewFontPreview.SetZoomMode(ZOOMMODE_IN); UISetCheck(ID_MENUITEM_ZOOMIN, 1); UISetCheck(ID_MENUITEM_ZOOMOUT, 0); } void OnMenuZoomOut(UINT uNotifyCode, int nID, HWND hWndCtl){ m_viewFontPreview.SetZoomMode(ZOOMMODE_OUT); UISetCheck(ID_MENUITEM_ZOOMIN, 0); UISetCheck(ID_MENUITEM_ZOOMOUT, 1); } void OnFileExit(UINT uNotifyCode, int nID, HWND hWndCtl){ PostMessage(WM_CLOSE); } };
まず、CZoomScrollWindowImplを使用するために「stdafx.h」で「atlscrl.h」をインクルードします。
次に、CFontPreviewViewクラスを変更します。CFontPreviewViewクラスの基底クラスをCZoomScrollWindowImplに変更し、メッセージマップにCZoomScrollWindowImplへのチェーンを追加します。
WM_CREATEメッセージハンドラではスクロールサイズを設定し、DoPaint()でフォント名を描画します。DoPaint()はCZoomScrollWindowImplのメンバ関数で、CZoomScrollWindowImpl内のWM_PAINTメッセージハンドラから呼び出されます。
これでズーム機能を備えたビューウィンドウは完成です。CZoomScrollWindowImplでは、デフォルトで左クリックによって自動的にズームイン/ズームアウトするコードが含まれています。
後はフレームウィンドウにズームイン/ズームアウトのメニューとツールボタンを追加し、そのハンドラ関数(OnMenuZoomIn()/OnMenuZoomOut())でSetZoomMode()を呼び出してズームモードを切り換えます。SetZoomMode()には次のズームモードを指定できます。
| 種類 | 説明 |
ZOOMMODE_OFF | ズーム機能オフ(デフォルト) |
ZOOMMODE_IN | ズームイン |
ZOOMMODE_OUT | ズームアウト |
最後に
本稿では、WTLのGUIクラスであるマルチペインステータスバー、ペインコンテナ、ズームスクロールウィンドウを使用しました。
