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

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

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

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


プロジェクトファイル ダウンロード
// stdafx.h
#pragma once

#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
#pragma once

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(CMainFrame)
        MSG_WM_CREATE(OnCreate)
        MSG_WM_DESTROY(OnDestroy)
        NOTIFY_CODE_HANDLER_EX(TBN_DROPDOWN, OnToolbarDropdown)
        COMMAND_ID_HANDLER_EX(ID_HELLO_WORLD, OnHelloWorld)
        COMMAND_ID_HANDLER_EX(ID_HELLO_ATL, OnHelloATL)
        COMMAND_ID_HANDLER_EX(ID_HELLO_WTL, OnHelloWTL)
        COMMAND_ID_HANDLER_EX(ID_APP_EXIT, OnFileExit)
        CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
        CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
    END_MSG_MAP()

    int OnCreate(LPCREATESTRUCT lpCreateStruct){
        // ツールバーを作成
        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_HELLO_WORLD, &bi);
        bi.fsStyle |= TBSTYLE_DROPDOWN;
        bar.SetButtonInfo(ID_HELLO_WORLD, &bi);

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

        return 0;
    }

    void OnDestroy(){
        // メッセージループからメッセージフィルタとアイドルハンドラを削除
        CMessageLoop* pLoop = _Module.GetMessageLoop();
        pLoop->RemoveMessageFilter(this);
        pLoop->RemoveIdleHandler(this);
        SetMsgHandled(false);
    }

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

            // ドロップダウンメニューを表示する位置を取得
            CRect rcButton;
            bar.GetRect(ID_HELLO_WORLD, 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 OnHelloWorld(UINT uNotifyCode, int nID, CWindow wndCtl){
        MessageBox(_T("Hello World"));
    }

    void OnHelloATL(UINT uNotifyCode, int nID, CWindow wndCtl){
        MessageBox(_T("Hello ATL"));
    }

    void OnHelloWTL(UINT uNotifyCode, int nID, CWindow wndCtl){
        MessageBox(_T("Hello WTL"));
    }

    void OnFileExit(UINT uNotifyCode, int nID, CWindow wndCtl){
        PostMessage(WM_CLOSE);
    }
};
			

// SampleProject.cpp
#include "stdafx.h"
#include "resource.h"
#include "MainFrm.h"

CAppModule _Module;

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

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

    AtlInitCommonControls(ICC_WIN95_CLASSES);

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

    CMessageLoop theLoop;
    _Module.AddMessageLoop(&theLoop);

    CMainFrame wndMain;
    wndMain.CreateEx();
    wndMain.ShowWindow(nCmdShow);

    int nRet = theLoop.Run();

    _Module.RemoveMessageLoop();

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

    return nRet;
}
			

 まず、プロジェクトにツールバーリソースを追加し、[ID]と[Prompt]を次のように設定します。

リソース名 ID Prompt
ツールバー IDR_MAINFRAME -
ツールバーボタン ID_HELLO_WORLD 「Hello World」メッセージボックスを表示します。\nHello World



さらに、ドロップダウン用のメニューリソースを追加し、[ID]、[Caption]、[Prompt]を次のように設定します。

リソース名 ID Caption Prompt
メニュー IDR_MENU_DROPDOWN - -
メニューアイテム(トップレベル) - index0 -
メニューアイテム ID_HELLO_ATL Hello ATL(&A) 「Hello ATL」メッセージボックスを表示します。\nHello ATL
メニューアイテム ID_HELLO_WTL Hello WTL(&W) 「Hello WTL」メッセージボックスを表示します。\nHello WTL



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

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

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

 次に、WM_COMMANDメッセージハンドラを追加します。 OnHelloWorld()はドロップダウンボタンを押した時に呼び出され、 OnHelloATL()OnHelloWTL()はドロップダウンメニューアイテムを実行した時に呼び出されます。 これらのハンドラ関数ではメッセージボックスを表示します。

 最後に_tWinMain()で、引数にICC_WIN95_CLASSESを指定して AtlInitCommonControls()を呼び出します。