|
さて、まず初めに言っておきます。
アニメートコントロールの実装に失敗しました!!! VC4.0時代にサンプルを作った時はできたのに、5.0だと動かない。。。。なんで? 色々試したのだが、やはりできない。 CAnimateCtrl::Play()や、CAnimeteCtrl::Open()がFALSEを返しやがる。 だめだこりゃ・・・ |
|
|
|
と言うわけで、今回は「自作アニメートコントロール」に挑戦だ!(半ばむちゃくちゃ) まず、アニメさせる絵を作ってみた(これが一番時間かかった(涙)) ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
|
|
|
|
ほぅら!リネームしているようにみえるでしょ!(見えないって?俺絵心ないからなあ・・・・(がっくり)) 実際はこれとは少し違う。上記のファイルはアニメーションGIFだが、アプリケーションでは BMP ファイルであるし、動かすのはプログラムで動かすので AVI ファイルは用いない。 本当は AVI ファイルでやろうと思ったのだが、時間が無いと言うのとせっかく見つけた AVI ファイルのフォーマットを無くしてしまった為である(ヲイヲイ) |
|
|
|
実装方法は非常に簡単である。 タイマーをセットして、一定時間ごとに絵を差し替える。 これでできるはずである。 タイマーのセットの仕方は、非常に簡単なのであるが、一つ不可解な事があった。 タイマー関数の引数並び等はヘルプを参照していただきたい。
void CALLBACK TimerProc( HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime )
{
if( NowBmpNum == TotalBmpNum )
NowBmpNum = 0;
else
NowBmpNum++;
//この関数は静的関数の為、直接メンバー関数をコールする事ができない。
//ゆえにメインダイアログのポインタを取得する事にする。
//メインダイアログの取得
CAnimateDlg* d = (CAnimateDlg*)AfxGetMainWnd();
ASSERT_VALID( d );
d->EACtrl.Invalidate();
}
void EAnimateCtrl::StartAction()
{
TimerID = SetTimer( TIMER_ID, 100, TimerProc );
}
void EAnimateCtrl::EndAction()
{
KillTimer( TimerID );
}
上記のようにして実装したのだが、デストラクタでEndAction()を呼ぶと処理できない例外でアプリケーションがおっこってしまう。
タイマーはセットしたら殺してやらないといけないはずなのだが、殺そうとするとエラーになってしまう(^^;;;
しかし、次回起動時に同じタイマーIDが取得できる事からどこかで殺されているらしいのだが・・・どこで殺されているかが分からない。 誰かご存知の方御教授ください。 |
|
|
|
表示ルーチンの方は、以下のようである。
int NowBmpNum;
void EAnimateCtrl::InitAnimation( short* index, short totalbmpnum )
{
if( m_pBitmap )
delete []m_pBitmap;
m_pBitmap = new CBitmap[ totalbmpnum ];
int i;
for( i = 0; i < totalbmpnum; i++ )
m_pBitmap[ i ].LoadBitmap( index[ i ] );
TotalBmpNum = totalbmpnum;
NowBmpNum = 0;
}
void EAnimateCtrl::First( CDC& dc )
{
//初期化ルーチン
dc.SetBkColor( RGB( 0, 0, 0 ) );
m_pdcDisplayMemory.CreateCompatibleDC( &dc );
m_pdcDisplayMemory.SelectObject( m_pBitmap[ 0 ] );
m_pBitmap[ 0 ].GetObject( sizeof( bm ), &bm );
m_sizeSource.cx = bm.bmWidth;
m_sizeSource.cy = bm.bmHeight;
m_sizeDest = m_sizeSource;
dc.DPtoLP(&m_sizeDest);
}
void EAnimateCtrl::OnPaint()
{
CPaintDC dc(this); // 描画用のデバイス コンテキスト
if( !m_pBitmap )
return;
static BOOL FirstFlag = TRUE;
if( FirstFlag == TRUE ){
First( dc );
FirstFlag = FALSE;
}
else{
m_pdcDisplayMemory.SelectObject( m_pBitmap[ NowBmpNum ] );
}
//
dc.StretchBlt( 0, 0,
m_sizeDest.cx,
m_sizeDest.cy,
&m_pdcDisplayMemory,
0, 0,
m_sizeSource.cx,
m_sizeSource.cy,
SRCCOPY
);
}
|
|
|
|
上記のようにして、一応はアニメートするようにはなった。 本来はもっとカスタマイズしたり、デバッグしなければならないのであるが、ひとまずこのままでいけるのでよしとしよう(ほんとか?) 今回のサンプルはここからダウンロードできる。読者の方も是非試してみてはいかがだろうか? バグレポート等お待ちしています(はっきり言って自信ありません) |