DIB を使用したアニメーションビットマップボタン

元サイト

この記事は Chris Copenhaver の投稿です。

What it is:

アニメーションビットマップボタンは256色のビットマップをボタンのようにするクラスです。

Screen Shot of Example:


History:

アニメーションビットマップクラス(CAniButton)は無邪気に始まりました。同僚と私は標準ビットマップボタンで遊んでいて256色DIBを使ったボタンを作りたくなりました。
作成されたクラスは CBitmapButtonEx と呼ばれ、DIB機能以外は CBitmapButton のように機能しました。最初に作ったボタンは"地球"ボタンで本当にうまくいきました。
世界を回すお決まりのジョークがありました。このジョークから CAniButton クラスは生まれました。

The Idea:

標準の Windows ボタンのように動作するボタンが欲しかったのですが、そうはなりませんでした。有効に、また無効にされたときにボタンはアニメーションします。
標準の Windows ボタンは4つの状態、「押されていない」、「押されている」、「フォーカスがある」、「無効になっている」があります。
「押されていない」、 「押されている」、「フォーカスがある」の状態のときボタンはアニメーションになります。これらの状態のいずれでも1つのビットマップがロードされます。 ビットマップは特定のフォーマットでなければなりません。
ビットマップには3つの列が必要です。1つ1つの列が3つの状態のそれぞれを表します。
イメージの最初の列は「押されていない」状態です。続いて「押されている」、「フォーカスがある」の状態となります。
行の数はアニメーションのフレームの数に依存します。
「無効になっている」状態のビットマップはかなり小さいでしょう。なぜならそれは1つのイメージしか含みません。
これが終わったらビットマップは下のようになると思います。

                         
「押されてない」、「フォーカスがある」、「押されている」ビットマップ      「無効になっている」ビットマップ
それぞれに5つのイメージがあります。.

下はアメリカ国旗ボタンの実際の例です。
最初の列は「押されていない」状態であることに注意してください。
2番目は「フォーカスがある」状態です。これは上の列と似ているようですが、旗の周りに赤い境界があります。
3番目の列は「押されている」状態です。これは真ん中の列と似ていますが、影が取り除かれ、旗が下と右に動かされています。


 

How To Use:

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 Creation Syntax:

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

Download source - 186 KB

Date Posted: September 6, 1998