ホーム ATL/WTL
ツールバー
ドキュメント種別 ATL/WTL に関する文書
最終更新日 2004/05/11
PR
 WTLではコモンコントロールのツールバーコントロールをCToolBarCtrlT というテンプレートクラスでカプセル化しています。 テンプレート引数にはクラスを指定しますが、 そのクラスはCToolBarCtrlTクラスの基底クラスとして使用されます。 atlctrls.hヘッダではtypedefによって次のように宣言されています。

// atlctrls.h内
typedef CToolBarCtrlT<ATL::CWindow>   CToolBarCtrl;
			

これは、CToolBarCtrlクラスはCWindowクラスの派生クラスであることを意味します。

 WTLのCToolBarCtrlクラスは、MFCの同名のクラスとほぼ同じメンバ関数を用意しています。 以下に示すのは、CToolBarCtrlクラスを使用する例です。 フレームウィンドウを作成してツールバーを追加し、 ツールバー上の最初のボタンをドロップダウンスタイルにします。


// stdafx.h内
#include <atlbase.h>
#include <atlapp.h>
extern CAppModule _Module;
#include <atlwin.h>

#include <atlcrack.h>
#include <atlmisc.h>
#include <atlctrls.h>
#include <atlframe.h>
			

// mainfrm.h内
class CMainFrame : public CFrameWindowImpl<CMainFrame>,
    public CUpdateUI<CMainFrame>, public CMessageFilter, public CIdleHandler
{
public:
    DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME)

    virtual BOOL PreTranslateMessage(MSG* pMsg){
        return CFrameWindowImpl<CMainFrame>::PreTranslateMessage(pMsg);
    }

    virtual BOOL OnIdle(){
        UIUpdateToolBar();
        return FALSE;
    }

    BEGIN_UPDATE_UI_MAP(CMainFrame)
        // エントリなし
    END_UPDATE_UI_MAP()

    BEGIN_MSG_MAP_EX(CMainFrame)
        MSG_WM_CREATE(OnCreate)
        NOTIFY_CODE_HANDLER_EX(TBN_DROPDOWN, OnToolbarDropdown)
        COMMAND_ID_HANDLER_EX(ID_BUTTON_MSG, OnButtonMsg)
        COMMAND_ID_HANDLER_EX(ID_MENUITEM_HELLOATL, OnMenuHelloATL)
        COMMAND_ID_HANDLER_EX(ID_MENUITEM_HELLOWTL, OnMenuHelloWTL)
        COMMAND_ID_HANDLER_EX(ID_APP_EXIT, OnMenuExit)
        CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
        CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
    END_MSG_MAP()

    LRESULT OnCreate(LPCREATESTRUCT lpcs){
        // ツールバーを作成
        CreateSimpleToolBar();
        UIAddToolBar(m_hWndToolBar);

        // ツールバーのスタイル変更
        CToolBarCtrl bar = m_hWndToolBar;
        bar.SetStyle(bar.GetStyle() | TBSTYLE_FLAT);
        bar.SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);

        // ツールバー上のボタンのスタイルを変更
        TBBUTTONINFO bi = {sizeof(bi), TBIF_STYLE};
        bar.GetButtonInfo(ID_BUTTON_MSG, &bi);
        bi.fsStyle |= TBSTYLE_DROPDOWN;
        bar.SetButtonInfo(ID_BUTTON_MSG, &bi);

        // メッセージループにメッセージフィルタとアイドルハンドラを追加
        CMessageLoop* pLoop = _Module.GetMessageLoop();
        pLoop->AddMessageFilter(this);
        pLoop->AddIdleHandler(this);

        return 0;
    }

    LRESULT OnToolbarDropdown(LPNMHDR pnmh){
        LPNMTOOLBAR pnmtb = (LPNMTOOLBAR)pnmh;
        if(pnmtb->iItem == ID_BUTTON_MSG){
            CToolBarCtrl bar = pnmtb->hdr.hwndFrom;

            // ドロップダウンメニューを表示する位置を取得
            CRect rcButton;
            bar.GetRect(ID_BUTTON_MSG, rcButton);
            bar.MapWindowPoints(HWND_DESKTOP, rcButton);

            TPMPARAMS tpm = {sizeof(tpm)};
            tpm.rcExclude = rcButton;

            // ドロップダウンメニュー表示
            CMenu menuDropdown;
            menuDropdown.LoadMenu(IDR_MENU_DROPDOWN);
            menuDropdown.GetSubMenu(0).TrackPopupMenuEx(
                TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL,
                rcButton.left, rcButton.bottom, m_hWnd, &tpm);
        }

        return TBDDRET_DEFAULT;
    }

    void OnButtonMsg(UINT uNotifyCode, int nID, HWND hWndCtl){
        MessageBox(_T("Hello World"));
    }

    void OnMenuHelloATL(UINT uNotifyCode, int nID, HWND hWndCtl){
        MessageBox(_T("Hello ATL"));
    }

    void OnMenuHelloWTL(UINT uNotifyCode, int nID, HWND hWndCtl){
        MessageBox(_T("Hello WTL"));
    }

    void OnMenuExit(UINT uNotifyCode, int nID, HWND hWndCtl){
        PostMessage(WM_CLOSE);
    }
};
			

// app.cpp内
#include "stdafx.h"

#include "resource.h"

#include "mainfrm.h"

CAppModule _Module;

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR lpCmdLine, int nCmdShow)
{
    HRESULT hRes = ::CoInitialize(NULL);
    ATLASSERT(SUCCEEDED(hRes));

    ::DefWindowProc(NULL, 0, 0, 0L);

    AtlInitCommonControls(ICC_COOL_CLASSES | ICC_WIN95_CLASSES);

    hRes = _Module.Init(NULL, hInstance);
    ATLASSERT(SUCCEEDED(hRes));

    int nRet = 0;
    // BLOCK: アプリケーション実行
    {
        CMessageLoop theLoop;
        _Module.AddMessageLoop(&theLoop);

        CMainFrame wnd;
        wnd.CreateEx();
        wnd.ShowWindow(nCmdShow);
        wnd.UpdateWindow();

        nRet = theLoop.Run();

        _Module.RemoveMessageLoop();
    }

    _Module.Term();
    ::CoUninitialize();

    return nRet;
}
			

 まず、プロジェクトにIDR_MAINFRAMEというIDのツールバーリソースを追加し、 次のようなボタンを追加します。ボタンのIDはID_BUTTON_MSGとします。



さらに、ドロップダウン用のメニューリソースを追加します。 メニューリソースのIDはIDR_MENU_DROPDOWNとし、トップレベルに[index0]を、 その下に[Hello ATL]メニューアイテムと[Hello WTL]メニューアイテムを追加します。 [Hello ATL]メニューアイテムにはID_MENUITEM_HELLOATL、 [Hello WTL]メニューアイテムにはID_MENUITEM_HELLOWTLというIDを設定します。



 次に、stdafx.h内では、CToolBarCtrlクラスを使用するためにatlctrls.hヘッダをインクルードします。

 CMainFrameクラスでは一般的なフレームウィンドウを作成します。 WM_CREATEメッセージハンドラで、まずCreateSimpleToolBar()を呼び出してツールバーを作成します。 これにより、フレームウィンドウのメンバ変数であるm_hWndToolBarにツールバーのハンドルが設定されます。 次にCToolBarCtrlクラスのインスタンスをこのツールバーのハンドルで初期化し、 ツールバーのスタイルを変更します。 ここではツールバー上のドロップダウンボタンに矢印を追加するため、 TBSTYLE_EX_DRAWDDARROWSスタイルを設定します。 また、IDがID_BUTTON_MSGのボタンにドロップダウンスタイルを追加します。

 次に、通知コードがTBN_DROPDOWNの通知メッセージハンドラを追加します。 このハンドラはドロップダウンボタンの矢印部分をクリックするたびに呼び出されます。 ここではボタンのIDを確認し、ドロップダウンメニューを表示しています。

 次に、コマンドメッセージハンドラを追加します。 OnButtonMsg()はドロップダウンボタンを押した時に呼び出され、 OnMenuHelloATL()OnMenuHelloWTL()はドロップダウンメニュー項目を実行した時に呼び出されます。 これらのハンドラではメッセージボックスを表示しているだけです。

 最後に、_tWinMain()内でICC_WIN95_CLASSESフラグを指定して AtlInitCommonControls()を呼び出します。 これによりツールバーコントロールが使用可能になります。