この記事は Girish Pandit の投稿です。

ボタンは CWnd クラスから派生した CButton のメンバーとして実体となる。このクラスはラジオボタンとチェックボックスを含む。ここではコマンドボタンに注目する。
コマンドボタンを含むダイアログボックスはプロパティとスタイルをもつ。ボタンスタイルは BS_Prefix により識別される。ボタンスタイルのいくつかを下に示す。
BS_PUSHBUTTON BS_RADIOBUTTON BS_AUTORADIOBUTTON BS_3STATE BS_AUTOSTATE BS_CHECKBOX BS_AUTOCHECKBOX BS_DEFPUSHBUTTON BS_GROUPBOX BS_LEFTTEXT BS_OWNERDRAW
上記のスタイルの中で、ビットマップボタンを作るために BS_OWNERDRAW に集中する。
コマンドボタンにエレガントさを加えるには、単なるテキストよりビットマップを描くのが簡単だ。これは単純なだけでなく、リソースの消費から考えても悪くない。ビットマップは必要なときにロードされ、閉じられれば捨てられる。
ビットマップをコマンドボタンに使うとアプリケーションの感じを変える。このテクニックの中心は CBitmapButton クラスだ。このクラスのオブジェクトは4つのビットマップからなり、ボタンの可能な状態に対応している。
1. 押されていない 2. 押されている 3. フォーカスがある 4. 無効
「押されていない」状態のビットマップのみが必要である。残りは開発者の自由だ。シンプルな「OK」「キャンセル」ボタンにとってこれだけが必要だ。より複雑なダイアログボックスでは他の状態も必要だろう。例えば、アクションが終わる前にユーザーがコンボボックスやリストボックスから選ばなければいけない場合、選択されるまでアプリケーションはOKボタンを向こうにすることができる。もちろんキャンセルボタンはいつも使用可能にすべきだ。
ユーザーがボタン用にビットマップを作る際、イメージの境界に注意して欲しい。なぜなら視覚的フィードバックをユーザーに与え、ボタンの状態がわかるからである。
どうすればできるか見ていこう。6つのステップからなる。
ここでは App Studio はビットマップを描くツールとして使う。プロパティやリソースIDの議論が簡単になるからだ。ビットマップを描くとき、16x16 か 16x32 ピクセルでおさめるよう努力せよ。でもビットマップはどんなサイズでもいい。すべては「押されてない状態」のビットマップと同じように扱われる。ダイアログボックスの置かれ方によっては、テストの後、ボタンの位置を調整する必要がある。
App Studio の中でボタンにユニークなIDを割り当て、BS_OWNERDRAW スタイルにする。ボタンのキャプションを決める(これはビットマップで隠されるのだが…)。キャプションはビットマップの名前に関係しているのでこれはとても重要だ。フレームワークはキャプションについた(Up, Down, Focused, Disableを表す)U,D,F,Xの文字を探す。ボタンのキャプションを「CANCEL」としよう。リソースファイルの中で、ビットマップのIDに「CANCELU」(押されてない)、「CANCELD」(押されてる)、「CANCELF」(フォーカスがある)、「CANCELX」(無効)というIDをつけなければならない。こうしてRCファイルは次のようになる:
CANCELUBITMAP DISCARDABLE "RES\\CANCELU.BMP" CANCELDBITMAP DISCARDABLE "RES\\CANCELD.BMP" CANCELFBITMAP DISCARDABLE "RES\\CANCELF.BMP" CANCELXBITMAP DISCARDABLE "RES\\CANCELX.BMP"
ボタンのIDがデフォルトの IDCANCEL だったら、1つのビットマップだけ作り次のようにする。
CANCELUBITMAP DISCARDABLE "RES\\CANCELU.BMP"
同様にボタンIDが IDOK なら
OKUBITMAP DISCARDABLE "RES\\OKU.BMP"
どのようにこのようにするかを見ていこう。
プロジェクトでダイアログボックスに2つのボタンを追加し、「OK」のIDには IDOK、「CANCEL」のIDには IDCANCEL とする。これはOK,CANCELに対するデフォルトのリソースIDである。
OKU と CANCELU のビットマップで 16x32 あるいは好きなサイズのビットマップを追加する。OKD, OKF, OKX, CANCELD, CANCELF, CANCELX のビットマップを作ってもいい。
CDialog から CBitmapDlg クラスを派生させた。
BitmalDlg.h ファイルで太字部分を変更した。
class CBitmapDlg : public CDialog
{
// Construction
public:
// standard constructor
CBitmapDlg(CWnd* pParent = NULL);
// Dialog Data
//{{AFX_DATA(CBitmapDlg)
enum { IDD = IDD_BITMAPDLG };
CBitmapButton m_Cancel;
CBitmapButton m_Ok;
//}}AFX_DATA
// Implementation
}
最後に CBitmapDlg の OnInitDialog() を変更する。
BOOL CBitmapDlg::OnInitDialog()
{
m_Ok.AutoLoad(IDOK, this);
m_Cancel.AutoLoad(IDCANCEL, this);
// Additional statement goes here
}
ダイアログボックスがアクティブになったら、ボタンにはビットマップがついてるだろう。開発者は明示的にビットマップをそれぞれの状態にロードする必要は無く、AutoLoad() によってフレームワークが自動的に扱ってくれるのに注意せよ。AutoLoad が何をしているのか知りたければ、私にメールを送って欲しい。完全な内部のコンセプトを送るから。
ボタンを有効にしたり無効にしたりするには次のようにするといい。
// OKUビットマップを表示する m_Ok.EnableWindow(TRUE); // OKFビットマップを表示する m_OK.EnableWindow(FALSE);
こうすればダイアログボックスが違った概観になるはずだ。
in this way user can have a new look to the Dialog Box.