この記事はAM Productions の Anish Mistry からの投稿です。
Environment: VC6 SP4, W2K SP1 - 透明ビットマップ描画のため DirectX&Win95 ではうまく動かない
1年半、このコードを書いた後、他の人のアプリケーションにも使えると感じるほど、コードが仕上がってきたと感じた。
CCaptionButton クラスの基本はキャプション領域に「ボタンのような」ツールバーを作ることだ。
私の最初のアイディアはウィンドウズのキャプションのインターフェース(最小化、最大化、閉じる)を作ることだったが、より創造的な道を行くため、同じような古い面白みの無いキャプションを作るよりは、ユニークなインターフェースを作るためビットマップを使うことにした。
こうして CCaptionButton がうまれた。キャプションあたり2つのビットマップ(と1つの共通のマウスダウンビットマップ)を使う。キャプションに
HICON を使えるが HBITMAP によってカバーされる。
特徴
クラスを眺めているとあると思っていた関数のいくつかが無いことに気づくだろう。これは簡単な理由だ。このクラスでプログラムを作る際にそれらを使わなかったからだ。それらは簡単に追加できるだろう。
初期化は複雑に見えるかもしれないが、実際は簡単だ。あなたはほとんどの時間をビットマップ作りに費やすだろう。最初の3つのキャプションで、マウスがのったときの効果を作るためにビットマップを結合する技を使っている。これは必要ではないが、.exe の中で多くのメモリーを節約する。 なぜなら異なるマウスオーバービットマップをそれぞれのキャプションについて保存しなくて良いからだ。.
// クラス変数 CCaptionButton cbExtra; // ウィンドウのサブクラス化 cbExtra.Init(hWnd); // 標準キャプションの数をセット(最小化/最大化/閉じる) cbExtra.SetNumOfDefaultCaptions(3); // イメージの透明色をセット COLORREF crTransparent = RGB(255,0,255); cbExtra.SetTransparentColor(crTransparent); // 表示されるビットマップをセット cbExtra.SetSelectionBitmap((HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_SELECTION), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS|LR_DEFAULTCOLOR)); // マウスオーバービットマップを作る (直接ロードすることも出来るが、 // この方法はメモリーを節約する) HBITMAP hMouseOverBitmap = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_MOUSEOVER), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS|LR_DEFAULTCOLOR); // AM Productions のキャプション HBITMAP hCaptionAMBitmap = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_BITMAP_AM), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS|LR_DEFAULTCOLOR); HBITMAP hCaptionAMBitmapHilite = CCaptionButton::CombineBitmaps(hCaptionAMBitmap, hMouseOverBitmap, crTransparent); // キャプション2 HBITMAP hCaption2Bitmap = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_BITMAP2), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS|LR_DEFAULTCOLOR); HBITMAP hCaption2BitmapHilite = CCaptionButton::CombineBitmaps(hCaption2Bitmap, hMouseOverBitmap,crTransparent); // キャプション3 HBITMAP hCaption3Bitmap = (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_BITMAP3), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS|LR_DEFAULTCOLOR); HBITMAP hCaption3BitmapHilite = CCaptionButton::CombineBitmaps(hCaption3Bitmap, hMouseOverBitmap,crTransparent); // ID = 1 のキャプションを作る, hCaptionAMBitmapHilite のマウスオーバー効果ビットマップ // hCaptionAMBitmap 標準ビットマップ // "AM Productions - Visit Now!"のツールチップテキスト cbExtra.New(1,hCaptionAMBitmapHilite,hCaptionAMBitmap, "AM Productions - Visit Now!"); cbExtra.New(2,hCaption2BitmapHilite,hCaption2Bitmap,"Caption 2"); cbExtra.New(3,hCaption3BitmapHilite,hCaption3Bitmap,"Caption 3"); // ビットマップリソースから直接ロード cbExtra.New(4, (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_BITMAP5), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS|LR_DEFAULTCOLOR), (HBITMAP)LoadImage(hInstance, MAKEINTRESOURCE(IDB_BITMAP6), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS|LR_DEFAULTCOLOR), "Caption 4");
ここで「それは素晴らしい。だがキャプションが押されたことをどう知るんだ?」と言うかもしれない。これが答えだ。キャプションがクリックされたとき、WM_CBLBUTTONCLICKED がキャプションのついたウィンドウに送られる。WPARAM は押されたキャプションのIDを保持していて、LPARAM はキャプションが押されたときのカーソルのスクリーン座標を保持している。
「動的」特徴は?CCaptionButton クラスは実行時に追加、置き換え、削除することができる。キャプションを追加したければ New() を呼ぶ。しかし5番目のパラメータはキャプションを挿入したい位置(右から左に数える)の0から始まるインデックスを指定する。存在するキャプションの置換は難しくない。
// キャプションの置換
cbExtra.Replace(nCurrentCaptionID,
nNewCaptionID,
hNewMouseoverBitmap,
hNewNormalBitmap,
pNewToolTipText);
キャプションの削除は次のようになる。
// キャプションの削除
cbExtra.Delete(nCurrentCaptionID);
知られている問題点:
アップデート:
改良の余地がたくさんあることはわかっているので、気軽にメールを送って欲しい。