●オーディオプレイヤ開発記 その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 ) 。
次は、ツールバー上に一定時間カーソルがあわせられたときに、ツールチップを出すようにします。