« オーディオプレイヤ開発記 その12 | メイン | サイン色紙? »

2006/02/15(水)

●オーディオプレイヤ開発記 その13


 今回から、ツールバーを作成・管理・破棄する CToolBar クラスを作っていきます。ツールバーにはビットマップを表示させるので、ついでに、ビットマップを管理する CBitmap クラスも作っておきます。

 それではまずは、CBitmap クラスです。

//----------------------------------------------------------------------------
// Bitmap.h : ビットマップの管理を行う
//----------------------------------------------------------------------------
#ifndef BitmapH
#define BitmapH
//----------------------------------------------------------------------------
// ビットマップの管理を行うクラス
//----------------------------------------------------------------------------
class CBitmap
{
public: // 関数

    CBitmap(): m_hBitmap(0) { }
    virtual ~CBitmap() { Destroy(); }

    virtual void Destroy() {
        if(m_hBitmap) DeleteObject(m_hBitmap), m_hBitmap = 0;
    }
    virtual void Load(LPCTSTR lpszName, UINT fuLoad) {
        Destroy();
        m_hBitmap = (HBITMAP)LoadImage(GetModuleHandle(NULL), lpszName, IMAGE_BITMAP, 0, 0, fuLoad);
    }

protected: // メンバ変数

    HBITMAP m_hBitmap;

public: // メンバ変数の取得・設定

    operator HBITMAP() const { return m_hBitmap; }
};
//----------------------------------------------------------------------------

#endif

 続いて、CToolBar クラスです。

//----------------------------------------------------------------------------
// ToolBar.h :ツールバーの作成・管理・破棄を行う
//----------------------------------------------------------------------------
#ifndef ToolBarH
#define ToolBarH

#include "Wnd.h"
#include "Bitmap.h"
//----------------------------------------------------------------------------
// ツールバーの作成・管理・破棄を行うクラス
//----------------------------------------------------------------------------
class CToolBar : public CWnd
{
public: // 関数

    CToolBar() { }
    virtual ~CToolBar() { }

    virtual BOOL Create(HWND hParentWnd);
    virtual void LoadBitmap(LPCTSTR lpszResourceName);
    virtual void SetButtons(const UINT* lpIDArray, int nIDCount);

protected: // メンバ変数

    CBitmap m_bitmap;
};
//----------------------------------------------------------------------------

#endif
//----------------------------------------------------------------------------
// ToolBar.cpp : ツールバーの作成・管理・破棄を行う
//----------------------------------------------------------------------------
#include <windows.h>
#include <commctrl.h>
#include "ToolBar.h"
//----------------------------------------------------------------------------
// 作成
//----------------------------------------------------------------------------
BOOL CToolBar::Create(HWND hParentWnd)
{
    INITCOMMONCONTROLSEX icc;
    ZeroMemory(&icc, sizeof(INITCOMMONCONTROLSEX));
    icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
    icc.dwICC = ICC_BAR_CLASSES;
    InitCommonControlsEx(&icc);

    m_hWnd = CreateWindow(TOOLBARCLASSNAME, "", WS_CHILD, CW_USEDEFAULT,
                            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                            hParentWnd, 0, GetModuleHandle(NULL), NULL);
    if(!m_hWnd) return FALSE;
    SetProc();
    return TRUE;
}
//----------------------------------------------------------------------------
// ビットマップの読み込み
//----------------------------------------------------------------------------
void CToolBar::LoadBitmap(LPCTSTR lpszResourceName)
{
    m_bitmap.Load(lpszResourceName, LR_LOADMAP3DCOLORS);

    SendMessage(m_hWnd, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);

    BITMAP bitmap;
    GetObject((HBITMAP)m_bitmap, sizeof(BITMAP), &bitmap);
    TBADDBITMAP tbab;
    ZeroMemory(&tbab, sizeof(TBADDBITMAP));
    tbab.nID = (UINT_PTR)(HBITMAP)m_bitmap;
    SendMessage(m_hWnd, TB_ADDBITMAP, bitmap.bmWidth / bitmap.bmHeight,
                (LPARAM)&tbab);
}
//----------------------------------------------------------------------------
// ボタンの設定
//----------------------------------------------------------------------------
void CToolBar::SetButtons(const UINT* lpIDArray, int nIDCount)
{
    if(nIDCount < 1) return; // 1個未満の場合はそのまま返す
    SendMessage(m_hWnd, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);

    // ボタンの追加
    TBBUTTON btn;
    ZeroMemory(&btn, sizeof(TBBUTTON));
    btn.fsState = TBSTATE_ENABLED;
    btn.fsStyle = TBSTYLE_BUTTON;
    if(lpIDArray) // 普通のボタンか区切り線
    {
        // ボタンを順次追加していく
        for(int i = 0, iBitmap = 0; i < nIDCount; i++, lpIDArray++)
        {
            btn.idCommand = *lpIDArray;
            if(btn.idCommand == 0) // 区切り線
                btn.fsStyle = TBSTYLE_SEP;
            else // 普通のボタン
            {
                btn.fsStyle = TBSTYLE_BUTTON;
                btn.iBitmap = iBitmap;
                iBitmap++;
            }
            SendMessage(m_hWnd, TB_ADDBUTTONS, 1, (LPARAM)&btn);
        }
    }
    else // 空白のボタン
    {
        // ボタンを順次追加していく
        for(int i = 0; i < nIDCount; i++)
            SendMessage(m_hWnd, TB_ADDBUTTONS, 0, (LPARAM)&btn);
    }

    SendMessage(m_hWnd, TB_AUTOSIZE, 0, 0);
}
//----------------------------------------------------------------------------

 この CToolBar クラスを継承した CToolBar_MainWnd などというクラスを作成し、メインウィンドウ用のツールバーを管理させます。その前にまず、ツールバー用のリソースを作成しておく必要がありますね。VC++ であれば、リソースの追加からツールバーを作成すればオッケーです。

 それでは、CToolBar_MainWnd クラスです。

//----------------------------------------------------------------------------
// ToolBar_MainWnd.h : メインウィンドウ用ツールバーの作成・管理を行う
//----------------------------------------------------------------------------
#ifndef ToolBar_MainWndH
#define ToolBar_MainWndH

class CApp;
class CMainWnd;
#include "../Common/ToolBar.h"
//----------------------------------------------------------------------------
// メインウィンドウ用ツールバーの作成・管理を行うクラス
//----------------------------------------------------------------------------
class CToolBar_MainWnd : public CToolBar
{
public: // 関数

    CToolBar_MainWnd(CApp & app, CMainWnd & mainWnd)
        : m_rApp(app), m_rMainWnd(mainWnd) { }
    virtual ~CToolBar_MainWnd() { }

    virtual BOOL Create();

private: // メンバ変数

    CApp & m_rApp;
    CMainWnd & m_rMainWnd;

public: // 定数

    // コマンド ID
    enum {
        ID_HEAD = 11,
        ID_PLAY,
        ID_PAUSE,
        ID_STOP,
        ID_NEXT,
        ID_OPENFILE,
        ID_SLOOP,
        ID_ALOOP,
        ID_RANDOM,
        ID_ABLOOP_A,
        ID_ABLOOP_B,
        ID_CONTROLBAR,
        ID_LIST,
    };
};
//----------------------------------------------------------------------------

#endif
//----------------------------------------------------------------------------
// ToolBar_MainWnd.cpp : メインウィンドウ用ツールバーの作成・管理を行う
//----------------------------------------------------------------------------
#include <windows.h>
#include <commctrl.h>
#include "../resource.h"
#include "../App.h"
#include "MainWnd.h"
#include "ToolBar_MainWnd.h"
//----------------------------------------------------------------------------
// 作成
//----------------------------------------------------------------------------
BOOL CToolBar_MainWnd::Create()
{
    CToolBar::Create(m_rMainWnd);
    if(!m_hWnd) return FALSE;
    SetStyle(GetStyle() | CCS_TOP | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT);
    LoadBitmap(MAKEINTRESOURCE(IDR_TOOLBAR1));
    UINT id[17] = {
        ID_HEAD,
        ID_PLAY,
        ID_PAUSE,
        ID_STOP,
        ID_NEXT,
        0,
        ID_OPENFILE,
        0,
        ID_SLOOP,
        ID_ALOOP,
        ID_RANDOM,
        0,
        ID_ABLOOP_A,
        ID_ABLOOP_B,
        0,
        ID_CONTROLBAR,
        ID_LIST,
    };
    SetButtons(id, 17);
    Show(SW_SHOW);
    return TRUE;
}
//----------------------------------------------------------------------------

 これで、MainWnd.h で ToolBar_MainWnd.h をインクルードしておき、CToolBar_MainWnd m_toolBar; メンバ変数を持つようにし、コンストラクタで、

CMainWnd(CApp & app): m_rApp(app), m_menu(app, *this), m_toolBar(app, *this) { }

CMainWnd::OnCreate 関数内で、

// ツールバーの作成
if(!m_toolBar.Create())
{
    MessageBox(m_hWnd, TEXT("ツールバーの作成に失敗しました。"
                "アプリケーションを終了します。"), TEXT("エラー"), MB_ICONERROR);
    Destroy();
    return FALSE;
}

などとすれば、ツールバーが表示されるようになりました。ここまでのソースコードはこちら ( Hayaemon20060215_src.lzh ) 。

 次に、ウィンドウのサイズが変更されたときにツールバーのサイズもそれにあわせて変更するようにします。ウィンドウプロシージャには、ウィンドウのサイズが変更されると WM_SIZE というメッセージが飛んできますので、それが来たら、ツールバーのサイズを変更するようにします。まず、CWnd クラスに、

virtual void OnSize(UINT state, int cx, int cy) {
    WindowProc(WM_SIZE, (WPARAM)state, MAKELPARAM(cx, cy));
}

という関数を追加し、CWnd::WndProc の

case WM_COMMAND:
    pWnd->OnCommand((int)LOWORD(wParam), (HWND)lParam, (UINT)HIWORD(wParam));
    return 0;
case WM_CREATE:
    return pWnd->OnCreate((LPCREATESTRUCT)lParam);

となっているところを、

case WM_COMMAND:
    pWnd->OnCommand((int)LOWORD(wParam), (HWND)lParam, (UINT)HIWORD(wParam));
    return 0;
case WM_CREATE:
    return pWnd->OnCreate((LPCREATESTRUCT)lParam);
case WM_SIZE:
    pWnd->OnSize((UINT)wParam, (int)LOWORD(lParam), (int)HIWORD(lParam));
    return 0;

に変更します。そして CMainWnd に、先ほどの OnSize 関数をオーバーライドした、

virtual void OnSize(UINT state, int cx, int cy) {
    m_toolBar.OnSize(state, cx, cy);
    CFrameWnd::OnSize(state, cx, cy);
}

のような関数を追加します。これで、ウィンドウのサイズにあわせてツールバーのサイズも変更されるようになりました。ここまでのソースコードはこちら ( Hayaemon20060215_2_src.lzh ) 。

 次は、ツールバー上に一定時間カーソルがあわせられたときに、ツールチップを出すようにします。

トラックバックURL

このエントリーのトラックバックURL:
http://www.edolfzoku.com/diary/mt-tb.cgi/136

コメントする