DirectShowを用いたmpgファイルの再生が上手くいかないのですが

このQ&Aのポイント
  • 趣味でゲームを作っているものです。ゲームのオープニングムービーでmpgファイルを再生したいのですが上手くいきません。
  • mpgファイルの再生中にウインドウが再描画されたとき(他のウインドウに隠されてた後、再びアクティブにしたり、最小化後最大化など)ムービーの一部あるいは全部が黒い画面になってしまいます。再描画されなければ上手くいきます。また、aviファイルであれば、問題なく動作します。
  • 使用しているライブラリはDirectX9.0bで、ビデオボードはGeForce7900GTです。ドライバは最新のものを使用しています。
回答を見る
  • ベストアンサー

DirectShowを用いたmpgファイルの再生が上手くいかないのですが

趣味でゲームを作っているものです。ゲームのオープニングムービーでmpgファイルを再生したいのですが上手くいきません。詳細は以下の通りです。よろしくお願いします。 ゲームはウインドウモードで作成 ゲームウインドウ内にmpgファイルを再生 DirectXのバージョン DirectX9.0b ビデオボード GeForce7900GT (ドライバは最新のものを使用) 不具合点  mpgファイルの再生中にウインドウが再描画されたとき(他のウインドウに隠されて た後、再びアクティブにしたり、最小化後最大化など)ムービーの一部あるいは全部 が黒い画面になってしまいます。再描画されなければ上手くいきます。  また、aviファイルであれば、問題なく動作します。 具体的コード <初期処理部> RECT rc; long w,h; //COMライブラリの初期化 CoInitialize(NULL); //GraphBuilder オブジェクトの作成 if(FAILED(CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,IID_IGraphBuilder,(void **)&pBuilder))){ MessageBox(NULL, "GraphBuilder オブジェクトの作成に失敗しました", NULL, MB_OK); return E_FAIL; } //フィルタ・グラフの作成 if(FAILED(pBuilder->RenderFile(L"sample.mpg",NULL))){ MessageBox(NULL, "フィルタ・グラフの作成に失敗しました", NULL, MB_OK); return E_FAIL; } // AVI描画用ウインドウを作成し... if(FAILED(pBuilder->QueryInterface(IID_IVideoWindow,(void **)&pVideoWindow))){ MessageBox(0,"AVI描画用ウインドウの作成に失敗しました",NULL,MB_OK); return E_FAIL; } // メインウインドウの子ウインドウに設定する // ウインドウハンドルの設定 if(FAILED(pVideoWindow->put_Owner((OAHWND)hwnd))){ MessageBox(0,"AVI描画用ウインドウを子ウインドウにすることに失敗しました",NULL,MB_OK); return E_FAIL; } // ウインドウスタイルの設定 if(FAILED(pVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS ))){ MessageBox(0,"AVI描画用ウインドウを子ウインドウにすることに失敗しました",NULL,MB_OK); return E_FAIL; } // ウインドウサイズの設定(メインウインドウに合わせる) GetClientRect(hwnd,&rc); w=rc.right; h=rc.bottom; if(FAILED(pVideoWindow->SetWindowPosition(0,0,w,h))){ MessageBox(0,"ウインドサイズの変更に失敗しました",NULL,MB_OK); return E_FAIL; } // メディアコントロールの取得 if(FAILED(pBuilder->QueryInterface(IID_IMediaControl,(void **)&pMediaControl))){ MessageBox(0,"メディアコントロールの取得に失敗しました",NULL,MB_OK); return 0; } // メディアイベントの取得 if(FAILED(pBuilder->QueryInterface(IID_IMediaEvent,(void **)&pMediaEvent))){ MessageBox(0,"メディアイベントの取得に失敗しました",NULL,MB_OK); return 0; } //ウインドウメッセージの受け取り準備 if(FAILED(pBuilder->QueryInterface(IID_IMediaEventEx,(void **)&pMediaEventEx))){ MessageBox(0,"メディアイベントの作成に失敗しました",NULL,MB_OK); return E_FAIL; } if(FAILED(pMediaEventEx->SetNotifyWindow((OAHWND)hwnd,WM_GRAPHNOTIFY,0))){ MessageBox(0,"メッセージの設定に失敗しました",NULL,MB_OK); return E_FAIL; } <コールバック関数にて> long ecode,param1,param2; //DirectShow用 switch(iMsg) { case WM_DESTROY: PostQuitMessage(0); return 0; case WM_KEYDOWN: switch((CHAR)wParam) { case VK_ESCAPE: PostQuitMessage(0); return 0; } // DirectShow用 case WM_GRAPHNOTIFY: while(SUCCEEDED(pMediaEventEx->GetEvent(&ecode,&param1,&param2,0))){ switch(ecode){ case EC_COMPLETE: case EC_END_OF_SEGMENT: case EC_WINDOW_DESTROYED: if(FAILED(pMediaControl->Stop())){ MessageBox(0,"停止に失敗しました",NULL,MB_OK); return 0; } GameStartFlag=true; } } break; } return DefWindowProc (hWnd, iMsg, wParam, lParam) ;

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

 すんません。フラグの照会でSW_RESTOREを無視していました。  此方へ修正した方が良いかもしれません。 //追加 //フラグ照会用のタグ typedef struct __flag_t { WORD fwSizeType;//WM_SIZE側のフラグ int iCmdType;//DirectShowに渡す int iOAFlag;//DirectShowに渡す } flag_t; //修正 //フラグの照会 static const flag_t _S_convert_flag(WORD fwSizeType) { const flag_t aflags[] = { {SIZE_MAXHIDE, SW_HIDE, OAFALSE}, {SIZE_MAXIMIZED, SW_MAXIMIZE, OATRUE}, {SIZE_MINIMIZED, SW_MINIMIZE, OATRUE}, {SIZE_RESTORED, SW_RESTORE, OATRUE}, {SIZE_MAXSHOW, SW_SHOW, OATRUE} }; for(int i = 0; i < 5; ++i) { if(aflags[i].fwSizeType == fwSizeType) return aflags[i]; } return aflags[0]; } プロシージャの中 +----------------------------------------------------------------------- case WM_SIZE://修正 { if(!pVideoWindow)break; //パラメータの分解 const WORD fwSizeType = wParam; const int nWidth = LOWORD(lParam); const int nHeight = HIWORD(lParam); const flag_t flag = ::_S_convert_flag(fwSizeType);//修正 //ビデオウィンドウのサイズ pVideoWindow->SetWindowPosition(0, 0, nWidth, nHeight); //ビデオウィンドウの表示ステートを外側のウィンドウの表示ステートと照会する pVideoWindow->put_WindowState(flag.iCmdType); //ビデオウィンドウを表示 pVideoWindow->put_Visible(flag.iOAFlag); break; } -----------------------------------------------------------------------+

cyacya2000
質問者

お礼

非常に丁寧なご回答ありがとうございます。 おかげさまで上手く行きそうです。 本当にありがとうございました。

その他の回答 (1)

回答No.1

 こんにちは。  確認出来ました。確かに表示がおかしくなります。  リサイズされた時の為に、WM_SIZEを処理して、pVideoWindow->put_Visible(OATRUE)を呼び出して対応すれば良いようです。  欠けた領域に関しては、DirectShowのビデオウィンドウにInvalidateRect()APIを使用して強引に解決出来るようです。  一通り出来ましたので、以下参考程度に。 #include<windows.h> #include<dshow.h> #pragma comment(lib, "strmbasd.lib") static IGraphBuilder* pBuilder; static IVideoWindow* pVideoWindow; static IMediaControl* pMediaControl; static IMediaEvent *pMediaEvent; static IMediaEventEx *pMediaEventEx; bool GameStartFlag = false; const UINT WM_GRAPHNOTIFY = 0x00008001; //関数プロトタイプ LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //DirectShowの初期化 static HRESULT _S_init(HWND hwnd) { RECT rc; long w,h; //COMライブラリの初期化 CoInitialize(NULL); //GraphBuilder オブジェクトの作成 if(FAILED(CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,IID_IGraphBuilder,(void **)&pBuilder))){ MessageBox(NULL, "GraphBuilder オブジェクトの作成に失敗しました", NULL, MB_OK); return E_FAIL; } //フィルタ・グラフの作成 if(FAILED(pBuilder->RenderFile(L"sample.mpg",NULL))){ MessageBox(NULL, "フィルタ・グラフの作成に失敗しました", NULL, MB_OK); return E_FAIL; } // AVI描画用ウインドウを作成し... if(FAILED(pBuilder->QueryInterface(IID_IVideoWindow,(void **)&pVideoWindow))){ MessageBox(0,"AVI描画用ウインドウの作成に失敗しました",NULL,MB_OK); return E_FAIL; } // メインウインドウの子ウインドウに設定する // ウインドウハンドルの設定 if(FAILED(pVideoWindow->put_Owner((OAHWND)hwnd))){ MessageBox(0,"AVI描画用ウインドウを子ウインドウにすることに失敗しました",NULL,MB_OK); return E_FAIL; } // ウインドウスタイルの設定 if(FAILED(pVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS ))){ MessageBox(0,"AVI描画用ウインドウを子ウインドウにすることに失敗しました",NULL,MB_OK); return E_FAIL; } // ウインドウサイズの設定(メインウインドウに合わせる) GetClientRect(hwnd,&rc); w=rc.right; h=rc.bottom; if(FAILED(pVideoWindow->SetWindowPosition(0,0,w,h))){ MessageBox(0,"ウインドサイズの変更に失敗しました",NULL,MB_OK); return E_FAIL; } // メディアコントロールの取得 if(FAILED(pBuilder->QueryInterface(IID_IMediaControl,(void **)&pMediaControl))){ MessageBox(0,"メディアコントロールの取得に失敗しました",NULL,MB_OK); return 0; } // メディアイベントの取得 if(FAILED(pBuilder->QueryInterface(IID_IMediaEvent,(void **)&pMediaEvent))){ MessageBox(0,"メディアイベントの取得に失敗しました",NULL,MB_OK); return 0; } //ウインドウメッセージの受け取り準備 if(FAILED(pBuilder->QueryInterface(IID_IMediaEventEx,(void **)&pMediaEventEx))){ MessageBox(0,"メディアイベントの作成に失敗しました",NULL,MB_OK); return E_FAIL; } if(FAILED(pMediaEventEx->SetNotifyWindow((OAHWND)hwnd,WM_GRAPHNOTIFY,0))){ MessageBox(0,"メッセージの設定に失敗しました",NULL,MB_OK); return E_FAIL; } return 0; } //フラグの照会 static int _S_convert_flag(WORD fwSizeType) { switch(fwSizeType) { case SIZE_MAXHIDE : return SW_HIDE; case SIZE_MAXIMIZED : return SW_MAXIMIZE; case SIZE_MINIMIZED : return SW_MINIMIZE; case SIZE_RESTORED : case SIZE_MAXSHOW : return SW_SHOW; } return SW_SHOW; } //ウィンドウの作成 static HWND _S_create() { WNDCLASSEX w = {sizeof(w)}; const char* pszClass = "DirectShowTest"; w.lpfnWndProc = (WNDPROC)WndProc; w.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); w.lpszClassName = pszClass; RegisterClassEx(&w); HWND h = CreateWindow(pszClass,pszClass,WS_OVERLAPPEDWINDOW, 0,0,640,480,NULL,NULL,NULL,NULL); return h; } //見ての通り LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { long ecode,param1,param2; //DirectShow用 switch(iMsg) { case WM_DESTROY: PostQuitMessage(0); return 0; case WM_KEYDOWN: switch((CHAR)wParam) { case VK_ESCAPE: PostQuitMessage(0); return 0; } //此処を処理する case WM_SIZE: { if(!pVideoWindow)break; //パラメータの分解 const WORD fwSizeType = wParam; const int nWidth = LOWORD(lParam); const int nHeight = HIWORD(lParam); //ビデオウィンドウのサイズ pVideoWindow->SetWindowPosition(0, 0, nWidth, nHeight); //ビデオウィンドウの表示ステートを外側のウィンドウの表示ステートと照会する pVideoWindow->put_WindowState(::_S_convert_flag(fwSizeType)); //ビデオウィンドウを表示 pVideoWindow->put_Visible(OATRUE); break; } //再描画 case WM_PAINT : //DirectShowのビデオウィンドウを再描画させる ::InvalidateRect(::GetWindow(hWnd, GW_CHILD), NULL, TRUE); break; // DirectShow用 case WM_GRAPHNOTIFY: while(SUCCEEDED(pMediaEventEx->GetEvent(&ecode,&param1,&param2,0))) { //此れを呼ばないといけない pMediaEventEx->FreeEventParams(ecode, param1, param2); switch(ecode) { case EC_COMPLETE: case EC_END_OF_SEGMENT: case EC_WINDOW_DESTROYED: if(FAILED(pMediaControl->Stop())) { MessageBox(0,"停止に失敗しました",NULL,MB_OK); return 0; } GameStartFlag=true; } } break; } return DefWindowProc (hWnd, iMsg, wParam, lParam); } //見ての通り int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int) { MSG msg; //ウィンドウの作成 HWND hWnd = ::_S_create(); //DirectShowの初期化 ::_S_init(hWnd); //再生 pMediaControl->Run(); //ビデオを表示する pVideoWindow->put_Visible(OATRUE); //ウィンドウを表示する ::ShowWindow(hWnd, SW_SHOW); while(::GetMessage(&msg, NULL, 0, 0)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } return msg.wParam; }

cyacya2000
質問者

お礼

ありがとうございました。 助かりました。

関連するQ&A

  • directshowでAVIファイルが再生が出来ません…

    Directshowを用いて動画を再生しようと試みています。 Direct sdkとplarformの両方を入れて、インクルードパスとライブラリパスを通しました。 ビルドしてもエラーは無いので某所のシンプルなソースでデバッグ無しで開始をクリック。 すると、再生が終わらないようにメッセージBlock Executionが表示されるものの肝心の動画が映りません。 プログラムはしっかりと動いているはずですが、、 動画aviはMSMPEG4V2です。Directshowのコーデックで動くとのことです。何がおかしいのか、さっぱりです。 環境はwindowsXP visual studio2005 DirectxSDK2008 microsoft platform(しっかりDirectshowフォルダは存在します) ここまで来たなら設定ミスは無いとは思いますが、(設定ミスがあれば、開けない等エラーが出ると思いますので) どうかお願い致します。 サンプルソース ↓ #include <stdio.h> #include <dshow.h> #define FILENAME L"C:\\Documents and Settings\\057104\\My Documents\\homerun2.avi" int main() { IGraphBuilder *pGraphBuilder; IMediaControl *pMediaControl; // COMを初期化 CoInitialize(NULL); // FilterGraphを生成 CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (LPVOID *)&pGraphBuilder); // MediaControlインターフェース取得 pGraphBuilder->QueryInterface(IID_IMediaControl, (LPVOID *)&pMediaControl); // Graphを生成 pMediaControl->RenderFile(FILENAME); // 再生開始 pMediaControl->Run(); // 再生中にプログラムが終わってしまわないように MessageBox(NULL, "Block Execution", "Block", MB_OK); // 資源を解放 pMediaControl->Release(); pGraphBuilder->Release(); // COM終了 CoUninitialize(); return 0; }

  • 今DirectSoundの初期化でわからないことがあります。カレントデ

    今DirectSoundの初期化でわからないことがあります。カレントディレクトリにもsoundファイルにもwavファイルがあるのにうまく読み込まれません。また、mmioRead関数でなぜか失敗時の処理が出てしまいます。下に一部省略したソースを書きます。 if(FAILED(hr = OpenWaveFile(aWaveFileName, aSound))) { TCHAR strWavFile[MAX_PATH]; TCHAR kSoundsPath[6]={'s','o','u','n','d','/'}; int kSoundsPathLength=6; lstrcpyn(strWavFile, kSoundsPath, MAX_PATH); lstrcpyn(strWavFile + kSoundsPathLength, aWaveFileName, MAX_PATH - kSoundsPathLength); if(FAILED(hr = OpenWaveFile((LPSTR)strWavFile, aSound))) { sprintf(tmpString, "wavファイル『%s』が見つかりませんでした", strWavFile); goto FAIL_RETURN; } HRESULT Sound::OpenWaveFile(LPSTR aWaveFileName, theSounds *aSound) { mmioOpen→mmioDescend →aChunkInfo.ckid = mmioFOURCC('f', 'm', 't', ' '); if(MMSYSERR_NOERROR != mmioDescend(aSound->sndHmmio, &aChunkInfo, &(aSound->sndChunkRiff), MMIO_FINDCHUNK)) { MessageBox(NULL, "FAIL:mmioDescend2","エラー", MB_OK | MB_ICONHAND); CloseWaveFile(aSound); return(E_FAIL); } →if(mmioRead(aSound->sndHmmio, (HPSTR) &aPCMWaveFormat, sizeof(aPCMWaveFormat)) != sizeof(aPCMWaveFormat)) { MessageBox(NULL, "FAIL:mmioRead","エラー", MB_OK | MB_ICONHAND); CloseWaveFile(aSound); return (E_FAIL); } } ソースは以上です。誰か原因に心当たりがある方がいましたら回答お願いします。

  • DirectXでのエラー処理について

    現在、Visual Studio .NET 2003でWindowsフォームを使って C++、DirectXのプログラムを作っています。 そこでXファイルを読み込むために以下のようにしているのですが、 Xファイルが存在しない場合 「アプリケーションのコンポーネントで、ハンドルされていない例外が発生しました。」 というメッセージが繰り返し出てきてreturnまで処理が進みません。 returnまで進まない原因、もしくはXファイルが存在しない場合の よい処理方法があれば教えていただけないでしょうか。 初心者なので説明足らずなところがあると思いますが よろしくお願いします。 if(FAILED(D3DXLoadMeshFromX("**.x",D3DXMESH_SYSTEMMEM,**,NULL,&**,NULL,&**,&**))){ MessageBox(NULL,"",NULL,MB_OK); return E_FAIL; } (**は全て独自、同じではありません)

  • midiの再生が思うようにできません

    ファイルの文字列を1行ずつ読み込み、文字列の数字の範囲によって再生する音楽を変えるプログラムを作成していますが、読み込んだ文字列とは無関係に、ループの初めの範囲で指定してある音楽しか再生されません。読み込んだ文字列ごとに再生音楽を変えるにはどうすればいいのでしょうか?分かる方ご教授願います。 環境:WindowsXP, Visual C++ 2008 Express Edition 以下がプログラムのソースの一部です。 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { FILE *fp; errno_t err; TCHAR buf[30]; TCHAR *temp; int m=0, n=0; switch(msg) { case WM_CREATE: CreateWindow(TEXT("BUTTON"), TEXT("Play"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,120, 100, 70, 70, hWnd, NULL, hInst, NULL); break; case WM_COMMAND: err = _tfopen_s(&fp, TEXT("C:\\Documents and Settings\\m22015\\My Documents\\Visual Studio 2008\\Projects\\process\\process\\Corner.txt"), TEXT("r+")); if(err != 0) break; temp = (TCHAR*)malloc(_tcsclen(buf)+1); if(temp == NULL){ MessageBox(hWnd, TEXT("Can't secure of memory"), TEXT("Error"), MB_OK); break; } for(int i=0; i<2; i++){ _fgetts(buf, 10, fp); _tcstok(buf, TEXT("\n")); } while(_fgetts(buf, 30, fp) != NULL){ _tcstok(buf, TEXT("\n")); _tcscpy(temp, buf); while(_stprintf(buf, _T("- { x:%d, y:%d }"), m, n)!=EOF){ if((m>=0 && m<110)&&(n>=0 && n<200)){ if(mciSendString(_T("play C+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play C+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=110 && m<220)&&(n>=0 && n<200)){ if(mciSendString(_T("play D+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play D+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=220 && m<330)&&(n>=0 && n<200)){ if(mciSendString(_T("play E+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play E+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=330 && m<440)&&(n>=0 && n<200)){ if(mciSendString(_T("play F+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play F+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=440 && m<550)&&(n>=0 && n<200)){ if(mciSendString(_T("play G+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play G+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=550 && m<660)&&(n>=0 && n<200)){ if(mciSendString(_T("play A+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play A+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=660 && m<770)&&(n>=0 && n<200)){ if(mciSendString(_T("play B+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play B+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if(mciSendString(_T("play C.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play C.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=110 && m<220)&&(n>=200 && n<400)){ if(mciSendString(_T("play D.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play D.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; 以下省略 . . . }else{ break; } } } free(temp); fclose(fp); break; case WM_CLOSE: DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wParam, lParam)); } return 0; }

  • BHO-2

    http://eternalwindows.jp/browser/mshtml/mshtml01.html の関数を、 http://msdn.microsoft.com/ja-jp/library/bb250489(v=vs.85).aspx のなかに組み込みたいと思っています。 BOOL CHelloWorldBHO::GetDocumentFromIE(IHTMLDocument3 **pp) { HWND hwnd; UINT uMsg; LRESULT lResult; HRESULT hr; EnumChildWindows(FindWindow(TEXT("IEFrame"), NULL), EnumChildProc, (LPARAM)&hwnd); if (hwnd == NULL){ return FALSE; } uMsg = RegisterWindowMessage(TEXT("WM_HTML_GETOBJECT")); if (!SendMessageTimeout(hwnd, uMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, (LPDWORD)&lResult)){ MessageBox(NULL, L"WM_HTML_GETOBJECT", L"BHO", MB_OK); return FALSE; } hr = ObjectFromLresult(lResult, IID_IHTMLDocument3, 0, (void **)pp); if (FAILED(hr)) return FALSE; MessageBox(NULL, L"Hello World! ie-end", L"BHO", MB_OK); return TRUE; } で、 uMsg = RegisterWindowMessage(TEXT("WM_HTML_GETOBJECT")); if (!SendMessageTimeout(hwnd, uMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, (LPDWORD)&lResult)){ MessageBox(NULL, L"WM_HTML_GETOBJECT", L"BHO", MB_OK); return FALSE; } の部分で失敗します。 原因はなんでしょうか・ VS2005 と Win7 を使っています。 MessageBox(NULL, L"WM_HTML_GETOBJECT", L"BHO", MB_OK); はバグの確認のため入れてあります。 アドバイスよろしくお願いします。

  • DirectXによる通信ができなくて困っています。

    DirectX9のDirectPlayで通信をしようとしているのですが、セッションへの接続が出来なくて困っています。 言語はC++で開発環境はVisualC++6.0です。プログラムは自分で組んだもので、ピアツーピア型。ホストとピア両方が出来るようにプログラムを組んで、同じプログラムを二つ起動して同一のマシンで実行しています。 接続が出来ない原因を調べたところ以下のセッションへの接続部分でプログラムが1~2分ほど固まり、その後接続に失敗していました。 hr = lpDirectPlay8Peer->Connect(&dpnAppDesc2, prgHostAddr,prgDeviceInfo2, NULL, NULL, NULL, 0, NULL, NULL, NULL,DPNCONNECT_OKTOQUERYFORADDRESSING | DPNCONNECT_SYNC); 接続に失敗した後、このエラー処理で接続に失敗した事は分かるのですが原因が分かりません。又、アドレスの設定やホストが確立しているかも同様の方法でエラーの判断をしています。 if (FAILED(hr)) //エラー処理 {MessageBox("セッションの接続に失敗", "PeerVoice", MB_OK | MB_ICONWARNING);} else {MessageBox("セッションの接続に成功", "PeerVoice", MB_OK | MB_ICONWARNING);} MSDNのIDirectPlay8Peer::Connectメソッドの項を見るとエラー時の戻り値でエラー原因が分かるようなので以下の様なコードを書きました。 switch (hr){ case S_OK: MessageBox("成功1", "PeerVoice", MB_OK |MB_ICONWARNING); break; case DPNSUCCESS_PENDING:("成功2", "PeerVoice", MB_OK |MB_ICONWARNING);break; case DPNERR_HOSTREJECTEDCONNECTION: MessageBox("失敗1", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDAPPLICATION : MessageBox("失敗2", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDDEVICEADDRESS : MessageBox("失敗3", "PeerVoice", MB_OK | MB_ICONWARNING); break; case DPNERR_INVALIDFLAGS: MessageBox("失敗4", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDHOSTADDRESS: MessageBox("失敗5", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDINSTANCE: MessageBox("失敗6", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDINTERFACE: MessageBox("失敗7", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDPASSWORD: MessageBox("失敗8", "PeerVoice", MB_OK | MB_ICONWARNING); break; case DPNERR_NOCONNECTION: MessageBox("失敗9","PeerVoice", MB_OK| MB_ICONWARNING);break; case DPNERR_NOTHOST: MessageBox("失敗10", "PeerVoice", MB_OK|MB_ICONWARNING);break; case DPNERR_SESSIONFULL: MessageBox("失敗11", "PeerVoice",MB_OK| MB_ICONWARNING);break; default: MessageBox("失敗0", "PeerVoice",B_OK|MB_ICONWARNING);break; } しかし、これでもdefaultの失敗0のメッセージボックスが出てきてしまいます。何かの設定ミスやホストがいないのなら上記のエラー処理で原因が特定できると思ったのですが、全くわけが分かりません。どうか理由が分かる方回答をお願いいたします。

  • WM_CREATE について

    Windows API の勉強を始めた者です。 CreateWindow関数を使ったときに発行されるWM_CREATEについて質問させていただきます。 以下のようなプログラムを作りました。このプログラムはウインドウを作るプログラムなのですが、はじめにウインドウを作るかどうかをWindowProcの中で聞いています。 このプログラムでウインドウを作らないという選択肢をとった時が分かりません。 WindowProcでは return -1 をするのでウインドウは作られず、従ってhWndにはNULLが入ります。そして次の文で、  if (hWnd == NULL) {   MessageBox(NULL,TEXT("CreateWindow failed"),NULL,MB_OK);   return 0;  } メッセージボックスが表示されてからプログラムが終了すると思ったのですが、実際にはメッセージボックスは表示されませんでした。 なぜでしょうか。return -1 をした時点で、ウインドウが作られないのでWM_DESTROYがウインドウプロシージャにSendされるのかと考えたのですが、そうなのでしょうか。 よろしくお願いします。 /* 作ったプログラム */ #include <windows.h> LRESULT CALLBACK WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {  int YESNO;  switch(uMsg) {  case WM_DESTROY:   PostQuitMessage(0);  return 0;  case WM_CREATE:  YESNO = MessageBox(NULL, TEXT("Create a new window?"),        ((LPCREATESTRUCT)lParam)->lpszName, MB_YESNO);  if (YESNO == IDYES)   return 0;  if (YESNO == IDNO)   return -1;  }  return DefWindowProc(hWnd, uMsg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance,           HINSTANCE hPrevInstance,           PSTR lpCmdLine,            int nCmdShow) {  WNDCLASS wc;  ATOM atom;  MSG msg;  HWND hWnd;  wc.style = CS_HREDRAW| CS_VREDRAW;  wc.lpfnWndProc = WindowProc;  wc.cbClsExtra = 0;  wc.cbWndExtra = 0;  wc.hInstance = hInstance;  wc.hIcon = NULL;  wc.hCursor = NULL;  wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND + 1;  wc.lpszMenuName = NULL;  wc.lpszClassName = TEXT("sample_window");  if ((atom = RegisterClass(&wc)) == 0) {   MessageBox(NULL,TEXT("RegisterClass failed"),NULL,MB_OK);   return 0;  }  hWnd = CreateWindow((LPCTSTR)atom, TEXT("Sampe window"),              WS_OVERLAPPEDWINDOW | WS_VISIBLE,              100, 100, 400, 300,              NULL, NULL, hInstance, NULL);                if (hWnd == NULL) {   MessageBox(NULL,TEXT("CreateWindow failed"),NULL,MB_OK);   return 0;  }  while (GetMessage(&msg, NULL, 0, 0) > 0) {   DispatchMessage(&msg);  }  return msg.wParam; }

  • 自作関数で元の値を変更したい

    ポインタとかが分からないので教えてください。 元のプロセスで  case WM_KEYDOWN:   MyFunc(hWnd);   if(!hWnd)MessageBox(NULL, "成功", "", MB_OK);   else MessageBox(NULL, "エラー", "", MB_OK);  break; 元のプロセスの自作関数で void MyFunc(HWND wnd){  SetWindowText(wnd, "てすと");//これはちゃんとできた。  wnd = NULL;//ここが失敗で、この関数を抜けるまでしか効果がない。 } これで MessageBox(NULL, "エラー", "", MB_OK); が実行されてしまいました。

  • 文字化けを直したい

    visual stadio C++ で、テキストファイルを読み込み、それをウインドウに表示するというプログラムを作っているのですが、表示すると文字化けしてしまいます。 原因がわかりません。 教えてください。 VC++ 2010です。 サイトを見て設定でマルチバイトに変えてあります case IDB_SELECT:{ HDC hDC; errno_t error; static LPCTSTR TEST_STR ;//= _T("左ボタンが押されました"); // ファイルを開くコモンダイアログを作成 if( !GetOpenFileName( &ofn ) ){ MessageBox( hWnd, _T("エラー"), _T("エラー"), MB_OK ); SendMessage( hWnd, WM_CLOSE, 0, 0 ); return 0; } // 選択されたファイル名を表示 MessageBox( hWnd, filename_full, _T("OK"), MB_OK ); int k=0; fp = fopen( "test.txt", "r" ); if( fp == NULL ) /* 関数が失敗していないか */ { MessageBox( hWnd,"読み込み失敗", _T("bad"), MB_OK ); return 1; /* 異常終了は0以外を返す */ } MessageBox( hWnd,"読み込み成功", _T("good"), MB_OK ); hDC = GetDC( hWnd ); while (fgets(file, 80, fp) != NULL){ TEST_STR = &file[k]; TextOut( hDC, 50, k*15+50, TEST_STR, (int)_tcslen(TEST_STR) ); k++; } fclose(fp); } return 0L; } InvalidateRect(hWnd, NULL, TRUE); // 再描画命令発 return 0L;

  • IDLファイルからソースファイルの実装方法について

    MessageDll.idlファイルで以下のようにコードを書いて、コンパイルしてできた MessageDll_h.hをインクルードして、 MessageComponent.cppに以下のように記述しました。 実装方法を教えてください。 また、間違っている所は指摘して頂きたいです。 DllRegisterServerとか足りない所はありますが、class内部だけでもお願いします。 お願いします。 //MessageDll.idl import "oaidl.idl"; import "ocidl.idl"; [uuid(7BBCC3A6-033D-4306-BC3D-EA358549F30F),version(1.0)] library ComputerLibrary { importlib("stdole2.tlb"); [uuid(9CAEC929-7E14-4af3-80EE-3D4EFECB3DCC), object] interface IMessage : IUnknown { HRESULT Message(); }; [uuid(0689B073-989C-483c-9757-0770F90A8C86)] coclass MessageClass { [default] interface IMessage; }; }; //MessageComponent.cpp #include"MessageDll_h.h" class MessageClass : public IMessage { public: HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { // 指定されたIID(Interface ID)に応じて、そのインターフェースポインタを // *ppvObjectに渡してやります。 if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IMessage)) { *ppvObject = static_cast<IMessage *>(this); } else { *ppvObject = NULL; return E_NOINTERFACE; } return S_OK; } ULONG STDMETHODCALLTYPE AddRef() { // 今は何もしません。 return 0; } ULONG STDMETHODCALLTYPE Release() { // Release関数は、その名の通りコンポーネントの開放を行います。 delete this; return 0; } HRESULT STDMETHODCALLTYPE Message() { MessageBox(NULL,"Hello World","",MB_OK); return 0; } };