ビットマップとテキストつきのボタン

元サイト

この記事は Michael Santoro の投稿です。

CSXButton クラスは MFC CButton にイメージとテキストを同じボタンに置けるようにしたクラスです。MFC CButton はイメージかテキストの一方しか置けません。下のダイアログでは不必要なグラフィックで圧倒されるが、CSXButton でできるアイディアがわくかもしれない。

 

 

ソースのダウンロード

注:このソースコードはGeorg Schreiberによりアップデートされ、メインモジュールの外(DLLなど)のビットマップとアイコンをロードする際の不具合が修正されています。アップデートされた箇所は"GS980730"とマークされています。

技術背景

CSXButton は次のことに気をつけたオーナードローボタンです。

1. リソースからアイコンやビットマップをロードする

アイコンの場合、よく見逃される ::LoadImage 関数によりなされる。::LoadImage は標準の CWinApp::LoadIcon がもってない1つの重要な機能をもちます。リソースからイメージをロードする際、::LoadImage はアイコンを任意の幅、高さにサイズを変更します。CWinApp::LoadIcon はシステムメトリクス(通常32x32)のサイズにロードします。
注:上の"View" と "Super View"アイコンは1つの 32x32 アイコンです。

ビットマップの場合、イメージは ::CreateMappedBitmap でロードされます。この関数を使うと、特定の色をシステムボタンのフェースカラー(これは GetSysColor(COLOR_BTNFACE)で取得します)にマップし、ビットマップは透明になります。
ビットマップをマスクするとき、無効なイメージはRGB(255,255,255)の白でマスクして作られます。これはマスクされた領域を無視する錯覚を与える、windows の浮き上がらせてみせる効果です。

2. 有効/無効状態のイメージの描画

3. 有効/無効状態のイメージの描画

これらは両方とも、しばしば見落とされる関数 CDC::DrawState 関数を使用します。この関数を使えば、CSXButton は「浮き上がらせた」無効化アイコンやテキストに悩む必要は無い。CDC::DrawState はまたボタンのショートカットとして使われる下線付き文字もサポートします。 すべてのテキスト描画関数がこれをサポートするわけではありません。

4. 特殊な「標準ボタン」の描画

オーナードローボタンを使うと残念なことに、もはやオーナードローボタンを「標準ボタン」にできないことです。そういうわけで CSXButton は SetDefaultButton メンバ関数を持っています。 この関数は2つのことをします。関数は余分に標準ボタンの境界を作成し、CDialog::SetDefID() 関数を使って ボタンをもつダイアログに、それを標準のアイテムにするように要求する。

5. フォーカス時の矩形描画

DrawFocusRect() を使用するだけです。

使用方法

CSXButton を使うには下記のステップに従ってください。

1. ソースファイルをプロジェクトに追加します。

2. ダイアログにボタンを作成し、下のように「オーナードロー」プロパティをチェックしてください。

3.ボタンのメンバ変数を作成して下さい。

オプション1.クラスウィザードでボタンのメンバ変数を追加し下に示すように変数タイプを CSXButton にしてください。
注:クラスウィザードから CSXButton を作成していないのならば、クラスウィザードファイル .clw を再構築する必要があります。このやり方は VC++ヘルプで「ClassWizard ファイル (.clw) のリビルド」で検索してください。

オプション2.CSXButton タイプのメンバ変数をダイアログに作成したら、変数をサブクラス化します。例えば…


	// In Dialog Class Header File
	CSXButton	m_brock; 

	// In Dialog OnInitDialog()
	m_brock.SubclassDlgItem( IDC_BUTTON_ROCK, this /*parent*/);

4. イメージをボタンにつけるために次の関数のいずれかを呼びます。nWidth と nHeight はイメージの実際のサイズである必要はありません。イメージは指定されたサイズに伸縮します。16色以下のビットマップ、256色以下のアイコンのみが使用できます。使おうとしたイメージのカラーパレットをマシンがサポートせず、正しく表示していないかもしれないので注意をしてください。


CSXButton::SetIcon( nID, nWidth, nHeight );
CSXButton::SetBitmap( nID, nWidth, nHeight );
CSXButton::SetMaskedBitmap( nID, nWidth, nHeight, crTransparentMask );

例:


	m_brock.SetIcon( IDI_ROCK, 40, 150 );
	m_bhelp.SetIcon( IDI_HELP, 16, 16 );
	m_brock.SetBitmap( IDB_ROCK, 40, 150 );
	m_brock.SetBitmap( IDB_ROCK, 12, 67 );

	// Use the bitmap IDB_ROCK, and replace any instance of 
	// RGB( 255, 0, 0 ) (bright red), with the system
	// color of the button face.
	m_brock.SetMaskedBitmap( IDB_ROCK, 40, 150, RGB( 255, 0, 0 ) );

5. 標準ボタンにするのなら CSXButton::SetDefaultButton() を呼んでください。アクティブでなくしたいとか標準ボタンにしたいときは CSXButton::SetDefaultButton(FALSE); を呼んでください。

例:


	m_bok.SetDefaultButton( FALSE );	// Deactivate
	m_brock.SetDefaultButton(); 		// Activate

6. イメージとテキストの配置の設定。デフォルトの配置では、イメージは左辺から4ピクセル、テキストではイメージの右から8ピクセルのオフセットとなる。イメージとテキストは垂直方向に中央に配置されます。上の例ではボタンは、"This Space For Rent" を除いてこのデフォルトの配置を使っています。これらのオフセットは CSXButton::SetTextOffset(nPixelsFromLeftOfImage)、CSXButton::SetTextOffset( nPixelsFromLeftOfImage) を使って変更できます。

細かく設定したい場合は、 CSXButton::SetTextPos( CPoint p) と CSXButton::SetImagePos( CPoint p) を使いボタンの左上からの位置を設定して下さい。また #define SXBUTTON_CENTER を CPoint の x か y に対して用いて自動的にテキストまたはイメージを中央にすることができます。上の例で"This Space For Rent" ボタンはこのメソッドを使用しています。

例:


	m_bplanet.SetIcon( IDI_PLANET, 32, 32 );
	m_bplanet.SetImagePos( CPoint( SXBUTTON_CENTER, 6 ) );
	m_bplanet.SetTextPos( CPoint( SXBUTTON_CENTER, 42 ) );

拡張

次のリストは CSXButton クラスに追加されうる機能です。ほかにもまだまだあるはずです。これらの拡張を追加したければこのサイトに送ってください。そして前のバージョンの CSXButton との互換性を一生懸命に維持してください。

1. マルチラインテキスト
2. デフォルトのイメージサイズの使用
3. CBitmapButton のような状態イメージ

CodeGuru のメッセージエリアでそのようなボタンを要求してくれたMark Findlay に感謝します。

最新のバグフィックス

  1. フォーカス矩形の描画
  2. リソースの解放

Last updated: 12 August 1998