FC2ブログ

ホーム > ANIファイルフォーマット > ANIファイルの動画の再生

ANIファイルの動画の再生



前回の「ANIファイルの読み込み」で作成したCANIFileクラスを、実際に動かしてみます。動画を動かすのに必要なタイマーとして、マルチメディアタイマーを使用するため、CMMTimerクラスを独自に作成しました。そしてANIファイルを読み込んで作成したCANIFileクラスはこのCMMTimerクラス基底クラスとして継承することにして、更にタイマーに関連したメンバー変数/関数をいくつか追加しました。尚タイマーイベント処理CMMTimerクラスOnTimer関数オーバーライドしたCANIFileクラスOnTimer関数アニメーションステップ値を変更した後、同じくCANIFileクラスのメンバー関数であるInvalidateOwnerWindow関数によりMFCビュークラスOnDraw関数を呼び出して、画像を再描画させています。



マルチメディアタイマー関数を使用するために必要なインクルードファイルとライブラリーです。

#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")


ANIファイルには複数のアイコン/カーソルがグループアイコン形式で格納されており、これらのアイコン/カーソルを読み込むために「アイコンファイルの読み込み」で解説したCGroupIconクラスStreamIn関数を使用するためのインクルード定義が必要です。

//グループアイコンクラスのインクルード
#include "GroupIcon.h"


このGroupIcon.hの中のアイコン/カーソルを読み込み関数では更に「PNGファイルの読み込み」で解説した_PNGStreamIn関数を呼び出しているため、「libpngのインストール」でダウンロードしたlibpngを使用するためのインクルード定義が必要です。

#include "png.h"
#include "PNGFile.h"
#include "DIBFile.h"


上記インクルード定義で必要となるファイルです。

GroupIcon.h GroupIcon.cpp
PNGFile.h PNGFile.cpp
DIBFile.h DIBFile.cpp
Rle.h Rle.cpp
MedianCut.h MedianCut.cpp
Dither.h Dither.cpp


動画を動かすのに必要なマルチメディアタイマー関数を使いやすくするため、CMMTimerクラスを独自に定義しました。

//CMMTimerクラス

class CMMTimer : public CObject
{
public:
CMMTimer();
virtual ~CMMTimer();

//タイマーの設定
UINT_PTR SetTimer(UINT uDelay,LPTIMECALLBACK lpTimeCallBack=0,DWORD_PTR dwUser=0,
UINT fuEvent=TIME_PERIODIC);
//インターバルタイマーの設定
UINT_PTR SetIntervalTimer(UINT uDelay,LPTIMECALLBACK lpTimeCallBack=0,DWORD_PTR dwUser=0);

//マルチメディアタイマーの停止
void KillTimer();

protected:
//スタティックタイマーイベント処理
static void __stdcall StaticOnTimer(UINT uTimerID,UINT uMsg,DWORD_PTR dwUser,
DWORD_PTR dw1,DWORD_PTR dw2);
//マルチメディアタイマーイベント関数
//このクラスを基底クラスとして継承した派生クラスで、
//タイマー起動時にユーザー定義のコールバック関数を指定しない場合は、
//この関数をオーバーライドしてタイマーイベントを処理して下さい。

virtual void OnTimer();

public:
TIMECAPS m_TimeCaps; //最大/最小タイマー分解能を格納した構造体
UINT m_uTimerID; //タイマーID
private:
BOOL m_bKillTimer; //タイマーの破棄フラグ
BOOL m_bDestruct; //デストラクターが呼び出された。
};


CMMTimerクラスのコンストラクタ/デストラクタです。

// CMMTimer

//コンストラクタ
CMMTimer::CMMTimer()
{
::ZeroMemory(&m_TimeCaps, sizeof(TIMECAPS));
m_uTimerID=0;
m_bKillTimer=FALSE;
m_bDestruct=FALSE;
}

//デストラクタ
CMMTimer::~CMMTimer()
{
m_bDestruct=TRUE;
KillTimer();
}


CMMTimerクラスのメンバー関数です。

// CMMTimerクラスのメンバー関数


//マルチメディアタイマーの停止
void CMMTimer::KillTimer()
{
//タイマーの破棄フラグをセットして、OnTimer関数の呼び出しを防ぐ。
m_bKillTimer=TRUE;
if(m_uTimerID){
//タイマーIDのタイマーを削除する
::timeKillEvent(m_uTimerID);
m_uTimerID=0;
}
if(m_TimeCaps.wPeriodMin){
//設定済みの最小タイマ分解能を削除する。
::timeEndPeriod(m_TimeCaps.wPeriodMin);
::ZeroMemory(&m_TimeCaps, sizeof(TIMECAPS));
}
}

//マルチメディアタイマーイベント関数
//このクラスを基底クラスとして継承した派生クラスで、
//タイマー起動時にユーザー定義のコールバック関数を指定しない場合は、
//この関数をオーバーライドしてタイマーイベントを処理して下さい。

void CMMTimer::OnTimer()
{
}

//スタティックタイマーイベント処理
void __stdcall CMMTimer::StaticOnTimer(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser,
DWORD_PTR dw1, DWORD_PTR dw2)
{
//CMMTimerクラスへのポインタを取り出す。
CMMTimer* pTimer=(CMMTimer*)dwUser;

//CMMTimerクラスへのポインタが有効で、デストラクタ中ではなく、
//たいまー破棄中でもなく、タイマーIDが既知のものと一致する場合は、
//OnTimer関数を呼び出す。

if ((AfxIsValidAddress(pTimer,sizeof(CMMTimer),0))&&
(!pTimer->m_bDestruct)&&(!pTimer->m_bKillTimer)&&
(pTimer->m_uTimerID==uTimerID))
pTimer->OnTimer();
}

//タイマーの設定
UINT_PTR CMMTimer::SetTimer(UINT uDelay,LPTIMECALLBACK lpTimeCallBack,
DWORD_PTR dwUser,UINT fuEvent)
{
//タイムアウト値が0ならFALSEを返して終了する。
if (!uDelay) return FALSE;

//最小タイマー分解能がまだ取得されていない場合。
if (!m_TimeCaps.wPeriodMin){
::ZeroMemory(&m_TimeCaps, sizeof(TIMECAPS));
MMRESULT mmResult;
//タイマデバイスを照会して、分解能を調べます。
mmResult=::timeGetDevCaps(&m_TimeCaps,sizeof(TIMECAPS));
//分解能の取得に失敗した時は、FALSEを返して終了する。
if (mmResult!=TIMERR_NOERROR) return FALSE;
}

//最小タイマ分解能を設定する。
MMRESULT mmResult=::timeBeginPeriod(m_TimeCaps.wPeriodMin);
if (mmResult!=TIMERR_NOERROR) return FALSE;

//コールバック関数が指定されていなければ、
//このクラスとStaticOnTimer関数を設定する。

if (!lpTimeCallBack) {
dwUser=(DWORD_PTR)this;
lpTimeCallBack=StaticOnTimer;
}

//このクラスがデストラクタ中なら、
//設定済みの最小タイマ分解能を削除し、FALSEを返して終了する。

if (m_bDestruct){
KillTimer();
return FALSE;
}

//タイマー破棄フラグをクリア
m_bKillTimer=FALSE;

//指定された値で、タイマイベントを開始します。
mmResult=::timeSetEvent(uDelay,m_TimeCaps.wPeriodMin,lpTimeCallBack,dwUser,fuEvent);
if (!mmResult) return FALSE;

//タイマーIDを保存しておく
m_uTimerID=(UINT)mmResult;

return (UINT_PTR)mmResult;
}

//インターバルタイマーの設定
UINT_PTR CMMTimer::SetIntervalTimer(UINT uDelay,LPTIMECALLBACK lpTimeCallBack,DWORD_PTR dwUser)
{
//タイマー作動中なら停止しておく。
KillTimer();
//タイマーの設定
return SetTimer(uDelay,lpTimeCallBack,dwUser,TIME_ONESHOT);
}


前回の「ANIファイルの読み込み」で作成したCANIFileクラス基底クラスCMMTimerクラスに変更したものです。動画操作に必要なメンバー変数や関数を新たに追加してありますので、合わせてご確認ください。

//表示時間の最小単位(ms)
#define ANI_PERIOD 16.67

//四捨五入した整数を求める
#define ROUND(data) ((int)((double)data+(double)0.5))


//CAniFileクラス
class CANIFile : public CMMTimer
{
public:
CANIFile(CWnd* pWndOwner=NULL);
virtual ~CANIFile();

void Init(); //メンバー変数の初期化
void Delete(); //メンバー変数の削除

//ANIファイルの読み込み
//bDeleteDIB TRUE:アイコン作成時に使用したDIBを削除する。

BOOL LoadFile(LPCTSTR pszFileName,BOOL bDeleteDIB=TRUE);
//ANIストリームからの読み込み
//bDeleteDIB TRUE:アイコン作成時に使用したDIBを削除する。

BOOL StreamIn(HMMIO hmmio,BOOL bDeleteDIB);

//リソースを格納しているファイル(DLL、EXEファイル)を開いて
//リソースハンドルを取得し、リソースを読み込みます。
//bDeleteDIB TRUE:アイコン作成時に使用したDIBを削除する。

BOOL LoadResource(LPCTSTR lpszExeName,LPCTSTR lpName,LPCTSTR lpType,BOOL bDeleteDIB=TRUE);
//リソースからの読み込み
//lpNameはリソース名で、リソースIDをMAKEINTRESOURCEマクロで型キャストした値が入ります。
//lpTypeはリソース形式で、この関数では以下の2種類のリソースが読み込めます。
// アニメーションカーソル:RT_ANICURSOR(21)
// アニメーションアイコン:RT_ANIICON(22)
//bDeleteDIB TRUE:アイコン作成時に使用したDIBを削除する。

BOOL LoadResource(HMODULE hModule,LPCTSTR lpName,LPCTSTR lpType,BOOL bDeleteDIB);
//メモリーからの読み込み
//bDeleteDIB TRUE:アイコン作成時に使用したDIBを削除する。

BOOL LoadFromMem(HPSTR pchBuffer,LONG memSize,BOOL bDeleteDIB);

//ANIファイルの書き込み
//bDeleteDIB TRUE:ファイル書き込みに使用したDIBを削除する。
//iPNGMinimumSize 0:PNG圧縮しない。
// 1~256:アイコンサイズが指定されたサイズ以上ならPNG圧縮する。
// それ以外:CIcon::m_bCompressedPNGに従って処理する。

BOOL SaveFile(LPCTSTR pszFileName,BOOL bDeleteDIB=TRUE,int iPNGMinimumSize=256);
//ANIストリームへの書き込み
BOOL StreamOut(HMMIO hmmio,BOOL bDeleteDIB,int iPNGMinimumSize);

//指定コマの表示時間の取得
LONG GetRate(UINT nStep);
//指定コマのアイコン番号の取得
LONG GetSeq(UINT nStep);
//指定コマの表示時間の設定
void SetRate(UINT nStep,LONG nRate);
//指定コマのアイコン番号の設定
void SetSeq(UINT nStep,LONG nFrame);
//指定コマのCGroupIconクラスの取得
CGroupIcon* GetGroupIcon(UINT nStep);
//現在選択されているCGroupIconクラスの取得
CGroupIcon* GetActiveGroupIcon(){return GetGroupIcon(m_nStep);};
//現在選択されているCIconクラスの取得
CIcon* GetActiveIcon(){return GetActiveGroupIcon()->GetActiveIcon();};
//コマ数の取得
DWORD GetCount();
//フレーム数の取得
DWORD GetFrames();

ANIHEADER m_AniHeader; //ヘッダー
LONG* m_pRate; //表示時間配列
LONG* m_pSeq; //シーケンスデータ
CString m_strFileName; //ファイル名
CString m_strAuthorName;//著者名
CPtrArray m_listGrpIcon; //CGroupIconクラスのリスト

//MMタイマー関連-------------------------------------------------

public:

UINT m_nStep; //現在のステップ位置
CRect* m_lpRect; //描画する領域

private:
BOOL m_bActivate; //動画再生中
BOOL m_bPause; //一時停止中
CWnd* m_pWndOwner; //オーナーウィンドウ

public:
//現在アニメーション動作中かどうか
BOOL IsActivate(){return m_bActivate;};
//現在アニメーション一時停止中かどうか
BOOL IsPaused(){return m_bPause;};

//タイマーにセットする時間を取得する
UINT GetDelayTime();
//オーナーウィンドウの描画領域の無効化
void InvalidateOwnerWindow();

public:
//タイマーの停止
void KillTimer();
//アニメーションの再生
void Play(CWnd* pWndOwner=NULL);
//アニメーションの停止
void Stop();
//アニメーションの一時停止
void Pause();
//アニメーションのコマ送り(前進)
void Next();
//アニメーションのコマ送り(後退)
void Prev();

//現在選択されているアイコンの表示
void OnDraw(CDC* pDC,int x,int y,int cx,int cy);

protected:
//CMMTimerクラスオーバーライド
virtual void OnTimer();

//リソース関連---------------------------------------------------
public:
LPCTSTR m_lpType; //リソースタイプ(RT_ANICURSOR/RT_ANIICON)
LPCTSTR m_lpName; //リソース名


//リソース名の取得/設定
LPCTSTR GetName(){return m_lpName;}
void SetName(LPCTSTR lpName);
//リソースタイプの取得/設定
LPCTSTR GetType(){return m_lpType;};
void SetType(LPCTSTR lpType);

};


今回新たに追加するCANIFileクラスのインライン関数です。

//指定コマのCGroupIconクラスの取得
inline CGroupIcon* CANIFile::GetGroupIcon(UINT nStep)
{
int index=GetSeq(nStep);
return (CGroupIcon*)m_listGrpIcon.GetAt(index);
}

//フレーム数の取得
inline DWORD CANIFile::GetFrames()
{
if (m_AniHeader.dwSize!=sizeof(ANIHEADER)) return FALSE;
return m_AniHeader.dwFrames;
}

//現在選択されているアイコンの表示
inline void CANIFile::OnDraw(CDC* pDC,int x,int y,int cx,int cy)
{
CIcon* pIcon=GetActiveIcon();
if (pIcon) pIcon->OnDraw(pDC,x,y,cx,cy);
}

//リソース名の設定
inline void CANIFile::SetName(LPCTSTR lpName)
{
if (HIWORD(m_lpName)) delete[]m_lpName;
if (HIWORD(lpName)){
m_lpName=new TCHAR[::lstrlen(lpName)+1];
::lstrcpy((LPTSTR)m_lpName,lpName);
}
else m_lpName=lpName;
}

//リソース形式の設定
inline void CANIFile::SetType(LPCTSTR lpType)
{
if (HIWORD(m_lpType)) delete[]m_lpType;
if (HIWORD(lpType)){
m_lpType=new TCHAR[::lstrlen(lpType)+1];
::lstrcpy((LPTSTR)m_lpType,lpType);
}
else m_lpType=lpType;
}


//タイマーコントロール-----------------------------------------------

//タイマーにセットする時間を取得する
inline UINT CANIFile::GetDelayTime()
{
LONG rate=GetRate(m_nStep);
return ROUND(((double)rate)*ANI_PERIOD);
}

//タイマーの停止
inline void CANIFile::KillTimer()
{
m_bActivate=FALSE;
CMMTimer::KillTimer();
}

//アニメーションの再生
inline void CANIFile::Play(CWnd* pWndOwner)
{
if (pWndOwner) m_pWndOwner=pWndOwner;
if ((m_bActivate)&&(!m_bPause)) return;
m_bActivate=TRUE;
m_bPause=FALSE;
CMMTimer::SetIntervalTimer(GetDelayTime());
InvalidateOwnerWindow();
}

//アニメーションの停止
inline void CANIFile::Stop()
{
KillTimer();
m_nStep=0;
InvalidateOwnerWindow();
}

//アニメーションの一時停止
inline void CANIFile::Pause()
{
if (m_bPause) Play();
else{
KillTimer();
m_bPause=TRUE;
InvalidateOwnerWindow();
}
}

//アニメーションのコマ送り(前進)
inline void CANIFile::Next()
{
m_nStep++;
if (m_nStep>=m_AniHeader.dwSteps) m_nStep=0;
InvalidateOwnerWindow();
}

//アニメーションのコマ送り(後退)
inline void CANIFile::Prev()
{
if (m_nStep>0) m_nStep--;
else m_nStep=m_AniHeader.dwSteps-1;
InvalidateOwnerWindow();
}

//CMMTimerクラスオーバーライド---------------------------------------

//タイマーイベント

inline void CANIFile::OnTimer()
{
Next();
if ((m_bActivate)&&(!m_bPause)) SetIntervalTimer(GetDelayTime());
}


今回変更のあったCANIFileクラスのコンストラクタ/デストラクタです。

//コンストラクタ
CANIFile::CANIFile(CWnd* pWndOwner)
{
m_pWndOwner=pWndOwner;
Init();
}

//デストラクタ
CANIFile::~CANIFile()
{
//基底クラスのデストラクタを先に呼ぶ。
CMMTimer::~CMMTimer();
Delete();
}


今回新たに変更/追加するCANIFileクラスのメンバー関数です。

//メンバー変数の初期化
void CANIFile::Init()
{
::ZeroMemory(&m_AniHeader,sizeof(ANIHEADER));
m_pRate=m_pSeq=0;
m_strFileName.Empty();
m_strAuthorName.Empty();
m_listGrpIcon.RemoveAll();
m_nStep=0;
m_bActivate=FALSE;
m_bPause=FALSE;
m_lpRect=0;

m_lpType=RT_ANICURSOR;
m_lpName=0;
}

//メンバー変数の削除
void CANIFile::Delete()
{
if (m_bActivate) KillTimer();
if (m_pRate) delete[]m_pRate;
if (m_pSeq) delete[]m_pSeq;

for(int i=0;i<m_listGrpIcon.GetCount();i++)
delete ((CGroupIcon*)m_listGrpIcon.GetAt(i));
if (HIWORD(m_lpType)) delete[]m_lpType;
if (HIWORD(m_lpName)) delete[]m_lpName;
Init();
}

//オーナーウィンドウの描画領域の無効化
void CANIFile::InvalidateOwnerWindow()
{
//オーナーウィンドウが表示中の場合
if ((AfxIsValidAddress(m_pWndOwner,sizeof(CWnd),0))&&
(m_pWndOwner->IsWindowVisible()))
{
//オーナーウィンドウの表示領域へのポインタがある場合
if (m_lpRect){
CRect rect=*m_lpRect;
//オーナーウィンドウがCScrollViewクラスの場合
if (m_pWndOwner->IsKindOf(RUNTIME_CLASS(CScrollView))){
//スクロール値を取得して座標から差し引く
int cx=m_pWndOwner->GetScrollPos(SB_HORZ);
int cy=m_pWndOwner->GetScrollPos(SB_VERT);
rect.OffsetRect(-cx,-cy);
}
//オーナーウィンドウの指定領域を無効化する。
m_pWndOwner->InvalidateRect(&rect,FALSE);
}
//オーナーウィンドウの表示領域へのポインタがない場合は、全面を無効化する。
else m_pWndOwner->Invalidate(FALSE);
}
}


CANIFileクラスを定義しているMFCドキュメントクラスのヘッダーの一部分と、実際にボタンコントロールイベントを処理して画像の動作をコントロールしているイベント関数です。

// 生成された、メッセージ割り当て関数
protected:
DECLARE_MESSAGE_MAP()
public:
virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
virtual void DeleteContents();

//ここにCANIFileクラスを定義します。
CANIFile* m_pAni;

afx_msg void OnControlPlay();
afx_msg void OnUpdateControlPlay(CCmdUI *pCmdUI);
afx_msg void OnControlStop();
afx_msg void OnUpdateControlStop(CCmdUI *pCmdUI);
afx_msg void OnControlPause();
afx_msg void OnUpdateControlPause(CCmdUI *pCmdUI);
afx_msg void OnControlNext();
afx_msg void OnUpdateControlNext(CCmdUI *pCmdUI);
afx_msg void OnControlBack();
afx_msg void OnUpdateControlBack(CCmdUI *pCmdUI);
};

//再生ボタンが押された時のイベント処理です。
void CANIFileTestDoc::OnControlPlay()
{
// TODO: Add your command handler code here
if ((m_pAni)&&(m_pAni->GetCount())&&(!m_pAni->IsActivate()))
m_pAni->Play();
}

//再生ボタンの表示状態を更新します。
void CANIFileTestDoc::OnUpdateControlPlay(CCmdUI *pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable((m_pAni)&&(m_pAni->GetCount())&&(!m_pAni->IsActivate()));
}

//停止ボタンが押された時のイベント処理です。
void CANIFileTestDoc::OnControlStop()
{
// TODO: Add your command handler code here
if (m_pAni) m_pAni->Stop();
}

//停止ボタンの表示状態を更新します。
void CANIFileTestDoc::OnUpdateControlStop(CCmdUI *pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(m_pAni!=0);
}

//一時停止ボタンが押された時のイベント処理です。
void CANIFileTestDoc::OnControlPause()
{
// TODO: Add your command handler code here
if ((m_pAni)&&(
((m_pAni->IsActivate())&&(!m_pAni->IsPaused()))||
((!m_pAni->IsActivate())&&(m_pAni->IsPaused()))))
m_pAni->Pause();
}

//一時停止ボタンの表示状態を更新します。
void CANIFileTestDoc::OnUpdateControlPause(CCmdUI *pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable((m_pAni)&&(
((m_pAni->IsActivate())&&(!m_pAni->IsPaused()))||
((!m_pAni->IsActivate())&&(m_pAni->IsPaused()))));
}

//コマ送りボタンが押された時のイベント処理です。
void CANIFileTestDoc::OnControlNext()
{
// TODO: Add your command handler code here
if ((m_pAni)&&(m_pAni->GetCount())&&(!m_pAni->IsActivate()))
m_pAni->Next();
}

//コマ送りボタンの表示状態を更新します。
void CANIFileTestDoc::OnUpdateControlNext(CCmdUI *pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable((m_pAni)&&(m_pAni->GetCount())&&(!m_pAni->IsActivate()));

}

//コマ戻しボタンが押された時のイベント処理です。
void CANIFileTestDoc::OnControlBack()
{
// TODO: Add your command handler code here
if ((m_pAni)&&(m_pAni->GetCount())&&(!m_pAni->IsActivate()))
m_pAni->Prev();
}

//コマ戻しボタンの表示状態を更新します。
void CANIFileTestDoc::OnUpdateControlBack(CCmdUI *pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable((m_pAni)&&(m_pAni->GetCount())&&(!m_pAni->IsActivate()));

}


画像を実際に表示するMFCのビュークラスのコンストラクタ、OnDraw関数と画像表示を準備するOnInitialUpdate関数です。

//画像を表示する領域を宣言します。
protected:
CRect m_rectDraw;

// CANIFileTestView コンストラクション/デストラクション

CANIFileTestView::CANIFileTestView()
{
// TODO: 構築コードをここに追加します。
//画像表示領域を初期設定します。
m_rectDraw.SetRect(100,100,200,200);
}

// CANIFileTestView 描画

void CANIFileTestView::OnDraw(CDC* pDC)
{
CANIFileTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

// TODO: この場所にネイティブ データ用の描画コードを追加します。

//メモリーDCを作成して、画像描画時のちらつきを抑えます。
//また同時に背景画像として、前の画像を消去します。


CDC MemDC;
MemDC.CreateCompatibleDC(pDC);
//クライアント領域の取得
CRect rect;
GetClientRect(&rect);
UINT width =rect.Width(); //ビューウィンドウの幅
UINT height=rect.Height(); //ビューウィンドウの高さ
//背景ビットマップの作成

CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC,width,height);
//背景ビットマップをメモリーDCに貼り付けます。
CBitmap* pOldBmp=MemDC.SelectObject(&bmp);
//背景を白で塗りつぶす
MemDC.PatBlt(0,0,width,height,WHITENESS);
//アニメーションカーソルを書き込みます。
if (pDoc->m_pAni)
pDoc->m_pAni->OnDraw(&MemDC,m_rectDraw.left,m_rectDraw.top,
m_rectDraw.Width(),m_rectDraw.Height());
//ビューウィンドウのDCにメモリーDCの内容をコピーします。
pDC->BitBlt(0,0,width,height,&MemDC,0,0,SRCCOPY);

//後片付け
MemDC.SelectObject(pOldBmp);
MemDC.DeleteDC();
bmp.DeleteObject();
//ダイヤログバーの内容を更新します。
CMainFrame* pFrame=(CMainFrame*)AfxGetMainWnd();
pFrame->m_dlgBarAniCtrl.Update();

}

void CANIFileTestView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize sizeTotal;
// TODO: このビューのサイズの合計を計算します。

CANIFileTestDoc* pDoc = GetDocument();
if ((pDoc)&&(pDoc->m_pAni)){
//アイコンのサイズを求める
CANIFile* pAni=pDoc->m_pAni;
int cx=pAni->GetActiveIcon()->Width();
int cy=pAni->GetActiveIcon()->Height();
//CViewクラスの描画領域に設定する
m_rectDraw.right=m_rectDraw.left+cx;
m_rectDraw.bottom=m_rectDraw.top+cy;
//CANIFileクラスの描画領域ポインタに設定する
pAni->m_lpRect=&m_rectDraw;
}
sizeTotal.cx=m_rectDraw.Width();
sizeTotal.cy=m_rectDraw.Height();

SetScrollSizes(MM_TEXT, sizeTotal);
}

サンプルプログラム(VisualC++net2003ソリューション)ANIFileTest02A.zip

上記のzipファイルをダウンロードしてからWinRAR等で解凍し、ANIFileTest02Aフォルダー内にある「ANIFileTest.sln」を開きます。「F5」キーを押すと、ビルド確認のダイヤログが表示されるので「Yes」を選択してソリューションをビルドします。



ビルドが終わると、直ちにプログラムが自動起動してウィンドウが表示されます。メニューから「ファイル」/「開く」を選択して、「ファイルを開く」ダイヤログを表示させます。



resフォルダー内の「aero_working_xl.ani」を選択し、「開く」ボタンを押して読み込みます。画像が表示されたところで、画像にカーソルを合わせてから左クリックして動画が再生されるか確認してください。



上記と同じ要領で「res」フォルダー内にある後二つのANIファイルについても、正しく動作するか確かめてみてください。



スポンサーサイト



コメント: 0

この記事へのコメント
ブログ著者にのみ知らせます。

Trackback+Pingback: 0

TrackBack URL for this entry
http://hiroshi0945.blog75.fc2.com/tb.php/31-09e5690b
Listed below are links to weblogs that reference
ANIファイルの動画の再生 from マルチメディアファイルフォーマット

Home > ANIファイルフォーマット > ANIファイルの動画の再生

タグクラウド
ブロとも申請フォーム

この人とブロともになる

ブロとも一覧

このページの先頭へ戻る