なんとなくMCIウインドウ
昔、ウインドウズプログラミングを始めた頃
マルチメディア関連の処理を検討した時に
MCIだけでプレイヤーが作れるかなとやってみたが
上手くいかなかった…。
MCIWndCreate(NULL,hInstance,MCIWNDF_SHOWALL,NULL)
で、「NULL」にするとMCIが自前でウインドウを作成する。
そのメニューも実際に動作するのだが…。
ファイルをロードする項目が動作しない。
当時、動作させる方法が分からなかった。
最近そのコードを発掘したので再度挑戦!
で、ボケ的には、満足できる出来になった。
チョットは、進歩した俺を確認。
チョット嬉しい。
で、チョット公開。
MCIは、たったこれだけでマルチメディアが
再生できる便利なルーチンなのだ。
手軽に再生するのなら結構使えると思うのだが…。
VC++6のWin32アプリケーションで作成。
//------------------------------------------------------------------------------
// MCIウインドウのもっとも簡単な使い方
//------------------------------------------------------------------------------
#pragma comment(lib,"vfw32.lib")
//--------------------------------------
#include<windows.h>
#include<vfw.h>
//--------------------------------------
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR,int)
{
MSG msg={0,};
HWND hWnd=NULL;
LPSTR FileName="Test.avi";
// HWND OwnerWnd=NULL;// MCIウインドウを作成。
HWND OwnerWnd=GetDesktopWindow();// ディスクトップに映像を貼り付けます。
if((hWnd=MCIWndCreate(OwnerWnd,hInstance,MCIWNDF_NOMENU|MCIWNDF_NOPLAYBAR|MCIWNDF_SHOWNAME|MCIWNDF_NOTIFYALL|0,FileName))!=NULL){
if(OwnerWnd!=NULL){
// ディストップなら大きさに合わせます。
RECT OwnerRect,Rect;
int Zoom;
GetClientRect(OwnerWnd,&OwnerRect);
MCIWndGetSource(hWnd,&Rect);
Zoom=OwnerRect.right*100/Rect.right;
MCIWndSetZoom(hWnd,Zoom);
SetWindowPos(hWnd,0,0,(OwnerRect.bottom-Rect.bottom*Zoom/100)/2,0,0,SWP_NOSIZE|SWP_NOZORDER);
}
MCIWndPlay(hWnd);
while(IsWindow(hWnd)&&(GetMessage(&msg,NULL,0,0)>0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
// メディアの停止を検出します。
// 「MCIWNDF_NOTIFYALL」を指定すると「WM_TIMER」が
// 実行されるので定期的にチェック可能になります。
if(MCIWndGetMode(hWnd,NULL,0)==MCI_MODE_STOP)
break;
}
}
MCIWndStop(hWnd);
MCIWndClose(hWnd);
MCIWndDestroy(hWnd);
return msg.wParam;
}
//------------------------------------------------------------------------------
で、こちらが本命。
//------------------------------------------------------------------------------
// MCIウインドウを利用したムービー&サウンドプレイヤー
//------------------------------------------------------------------------------
#pragma comment(lib,"vfw32.lib")
//--------------------------------------
#include<windows.h>
#include<vfw.h>
//--------------------------------------
LRESULT (CALLBACK*OriginalMicWndProc)(HWND,UINT,WPARAM,LPARAM);
char Directory[MAX_PATH];
//------------------------------------------------------------------------------
LRESULT CALLBACK MicWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case WM_COMMAND:
// 開く
if(wParam==0x68){
char FileName[MAX_PATH];
OPENFILENAME OpenFileName;
*FileName=0;
ZeroMemory(&OpenFileName,sizeof(OpenFileName));
OpenFileName.lStructSize=sizeof(OpenFileName);
OpenFileName.hwndOwner=hWnd;
OpenFileName.lpstrFilter="マルチメディア(*.avi;*.wav;*.aif;*.mid;*.mp3)\0*.avi;*.wav;*.aif;*.mid;*.mp3\0";
OpenFileName.lpstrFile=FileName;
OpenFileName.nMaxFile=MAX_PATH;
OpenFileName.lpstrInitialDir=Directory;
OpenFileName.Flags=OFN_HIDEREADONLY|OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST;
if(!GetOpenFileName(&OpenFileName))
return 0;
// ディレクトリの更新
strcpy(Directory,FileName);
// MCIへ登録し再生します。
MCIWndClose(hWnd);
if(MCIWndOpen(hWnd,FileName,0)==0)
MCIWndPlay(hWnd);
return 0;
}
break;
case WM_INITMENU:
// 正しく処理されないメニュー項目
// 「構成(0x6E)」と「コマンド(0x6F)」を削除します。
{
HMENU Menu=(HMENU)wParam;
DeleteMenu(Menu,0x6E,MF_BYCOMMAND);
DeleteMenu(Menu,0x6F,MF_BYCOMMAND);
}
break;
case WM_CLOSE:
// ムービーの再生中にウインドウを閉じると
// 別のウインドウフレームが左上に表示されます。
// ここで、停止しする事で表示されなくなります。
MCIWndStop(hWnd);
MCIWndClose(hWnd);
break;
}
return CallWindowProc(OriginalMicWndProc,hWnd,uMsg,wParam,lParam);
}
//--------------------------------------
// 使用しない引数名を削除したのはレベル4のエラーチェックに対応するため。
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR,int)
{
MSG msg={0,};
HWND hWnd=NULL;
if(GetCurrentDirectory(MAX_PATH,Directory)==0)
goto EXIT;
// MCIバージョンを調べます。
if(HIWORD(VideoForWindowsVersion())<ICVERSION)
goto EXIT;
// MCIウインドウを作成します。
if((hWnd=MCIWndCreate(NULL,hInstance,MCIWNDF_SHOWALL,NULL))==NULL)
goto EXIT;
// プロシージャを差し替えます。
// ファイルのロード部分のみ実装されていません。
// サブクラス化しロード等の処理を追加します。
OriginalMicWndProc=(WNDPROC)GetWindowLong(hWnd,GWL_WNDPROC);
SetWindowLong(hWnd,GWL_WNDPROC,(DWORD)MicWndProc);
// 「TranslateMessage/DispatchMessage」の
// 後でないと「IsWindow」は、正常に動作しません。
// 「while((GetMessage(&msg,NULL,0,0) > 0) && IsWindow(hWnd))」
// では、希望した通りに動作しません。
while(IsWindow(hWnd)&&(GetMessage(&msg,NULL,0,0)>0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
// エラー時の処理
EXIT:
MessageBox(hWnd,"エラーが発生しました。\n強制的に終了します。","MCI Window - ERROR",MB_OK|MB_ICONSTOP);
MCIWndClose(hWnd);
MCIWndDestroy(hWnd);
return 0;
}
//------------------------------------------------------------------------------
何で、こんなのを公開したかと言うと…
無かったから。
自分と同じ所で詰まっている人が居るかもしれない!
…居ないかもしれない。
まあ、ボケもいろいろ貰っているので
たまには、還元。
でな所。
| 固定リンク
コメント
コメントどうも♪
ちょっと還元されたのを確認できたので
ちょっと幸せ♪
アリガトね♪
投稿: kouyou | 2007年10月23日 (火) 23時45分
WinMainでMCIウインドウを作成する方法をずっと探してた。
参考になったよ。
このブログ内容がね。
ありがとう。
投稿: MCI初心者 | 2007年10月23日 (火) 06時55分