この記事は Chris Copenhaver の投稿です。
標準の Windows ボタンのように動作するボタンが欲しかったのですが、そうはなりませんでした。有効に、また無効にされたときにボタンはアニメーションします。
標準の Windows ボタンは4つの状態、「押されていない」、「押されている」、「フォーカスがある」、「無効になっている」があります。
「押されていない」、 「押されている」、「フォーカスがある」の状態のときボタンはアニメーションになります。これらの状態のいずれでも1つのビットマップがロードされます。
ビットマップは特定のフォーマットでなければなりません。
ビットマップには3つの列が必要です。1つ1つの列が3つの状態のそれぞれを表します。
イメージの最初の列は「押されていない」状態です。続いて「押されている」、「フォーカスがある」の状態となります。
行の数はアニメーションのフレームの数に依存します。
「無効になっている」状態のビットマップはかなり小さいでしょう。なぜならそれは1つのイメージしか含みません。
これが終わったらビットマップは下のようになると思います。
「押されてない」、「フォーカスがある」、「押されている」ビットマップ 「無効になっている」ビットマップ
それぞれに5つのイメージがあります。.
下はアメリカ国旗ボタンの実際の例です。
最初の列は「押されていない」状態であることに注意してください。
2番目は「フォーカスがある」状態です。これは上の列と似ているようですが、旗の周りに赤い境界があります。
3番目の列は「押されている」状態です。これは真ん中の列と似ていますが、影が取り除かれ、旗が下と右に動かされています。
CAniButton クラスの使い方は簡単です。最初に CAniButton.h(cpp) ファイル、CDib.h(cpp) ファイルをプロジェクトに追加します。クラスウィザードが新しいクラスを認識するようにクラスウィザードをリビルドしてください。
次にオーナードローボタンをダイアログに追加してください。クラスウィザードを使い、変数タイプを CAniButton クラスを使用したボタンのメンバ変数を追加してください。
ダイアログの OnInitDialog メソッドに、ボタンの AutoLoad メソッドを呼ぶコードを追加すればボタンは作成されます。
ON_WM_PALETTECHANGED とON_WM_QUERYNEWPALETTE メッセージをハンドルします。
詳しくはサンプルコードを見てください。
BOOL CBtnTestDlg::OnInitDialog() { // Initialize all of our CAniButtons before we // do anything else! m_btnGlobe.AutoLoad(IDC_GLOBE2, // Resource ID this, // Parent Window IDB_GLOBE_BUTTON, // Main Bitmap Resource ID IDB_GLOBE_DISABLED, // Disabled Bitmap Resource ID 10, // 10 Frames per Second 0, // Calculate Number of Frames FALSE, // Do NOT Stretch to fit TRUE, // Replace Face Color IDC_PLANE_CURSOR); // Cursor Resourse ID CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon return TRUE; // return TRUE unless you set the focus to a control } void CBtnTestDlg::OnPaletteChanged(CWnd* pFocusWnd) { // // If this window is not the window getting focus, // redraw the AniButtons... // if(pFocusWnd != this) { // A simple call to Invalidate will cause the // button to be redrawn and it's palette realized. m_btnGlobe.Invalidate(); } } BOOL CBtnTestDlg::OnQueryNewPalette() { // Make sure the AniButton's Palette // becomes the foreground palette. m_btnGlobe.RealizePalette(); return CDialog::OnQueryNewPalette(); }
CAniButton::AutoLoad
BOOL CAniButton::AutoLoad(UINT nID,
CWnd* pParent,
UINT nBitmapID,
UINT nDisabledID,
UINT nFramesPerSecond,
UINT nNumFrames = 0,
BOOL bStretchToFit = FALSE,
BOOL bChangeFaceColor = TRUE,
UINT nCursorID = 0);
BOOL CAniButton::AutoLoad(UINT nID,
CWnd* pParent,
const char* szFilename,
const char* szDisabledFilename,
UINT nFramesPerSecond,
UINT nNumFrames,
BOOL bStretchToFit,
BOOL bChangeFaceColor,
UINT nCursorID);
戻り値
成功したら0以外。そうでなければ0
パラメータ
nID ボタンのコントロールID
pParent ボタンを所有するオブジェクトへのポインタ
nBitmapID 3状態のメインビットマップの リソースID。必要。
nDisabledID 「無効になっている」状態のビットマップのリソースID
szFilename 3状態のためにメインビットマップのファイル名。必要。
szDisabledFilename 「無効になっている」状態のビットマップのファイル名
nFramesPerSecond 1秒にサイクルするアニメーションのフレーム数
nNumFrames アニメーション中にあるトータルのフレーム数。もしこれを 0 にすると、フレーム数は無効ビットマップの幅とメインビットマップの幅を比較することで決めます。 例えば、無効ビットマップの幅が50ピクセルでメインビットマップの幅が250ピクセルなら、250/50 = 5 がアニメーションのフレーム数です。
bStretchToFit このフラグを TRUE にすると、ビットマップはボタンのサイズに合わせるように伸縮します。FALSE にするとビットマップはボタンの中心にきます。
bChangeFaceColor このフラグを TRUE にすると、ビットマップの最初のピクセルと同じ色の全てのピクセルは、windows
の3Dカラーになります。
これによりボタンは透明になります。FALSE にするとピクセルは変更されません。
nCursorID カーソルがボタンの上にきたとき表示されるカーソルのリソースID。0 にするとカーソルは変わりません。
Download demo project - 176 KB
Date Posted: September 6, 1998