• ベストアンサー

DirectInputが上手く動きません;

DirectInputを使って操作は正しく取得できるようになったのですが、 つぎはぎで最低限動く所にこぎつけただけで 色々問題が有ります・・orz 1.フォーカスを別アプリに移して戻すと、一切操作を受付けなくなる。 2.Unacquire(); を入れなければならないらしいけれど、入れるべき場所が解らない 3.動かしてみる度に、マウス座標の受け取りが劣悪な程遅くなってくる。。 コードは大よそ以下のようになっています。 どこか怪しい部分がわかる方が推察できる方がいらっしゃいましたら ご指摘願います、その部分のコード全体を書き出そうと思います。 よろしくお願い致します。 orz --------------------------------- //●Inputクラス 初期化用関数内 DirectInput8Create(); //オブジェクト作成 lpDI lpDI->CreateDevice(); //マウス用作成 lpDIDeviceM lpDIDeviceM->SetDataFormat(); lpDIDeviceM->SetCooperativeLevel() lpDIDeviceM->Acquire(); lpDI->CreateDevice(); //キーボード用作成 lpDIDeviceK lpDIDeviceK->SetDataFormat(); lpDIDeviceK->SetCooperativeLevel() lpDIDeviceK->Acquire(); //●Inputクラス マウス用状態取得関数内(キーボードも同じ構造です) DIMOUSESTATE dims; HRESULT hr2; hr2 = lpDIDeviceM->GetDeviceState( sizeof(DIMOUSESTATE), &dims ); if (hr2==DIERR_INPUTLOST) { g_lpDIDeviceM->Acquire(); } else if (SUCCEEDED(hr2)) {  // 受け取り処理 } //●Inputクラス デストラクタ処理 //Unacquire();をすべき場所はここなのでしょうか SAFE_RELEASE( lpDIDeviceK ); SAFE_RELEASE( lpDIDeviceM ); SAFE_RELEASE( lpDI ); ---------------------------------

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

  • ベストアンサー
  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

デバイスロストしたときはGetDeviceState( )の前にAcquire( )しないとだめなようです 自分はデバイス獲得済みであろうがとりあえずAcquireしてます hr2 = lpDIDeviceM->Acquire(); if (hr2 == DI_OK || hr2 == S_FALSE) { hr2 = lpDIDeviceM->GetDeviceState( sizeof(DIMOUSESTATE), &dims ); if (hr2 == DI_OK) { // 受け取り処理

zaxs5968
質問者

お礼

ありがとうございます・・! こういう方法で上手くいくのですね。 >>1.フォーカスを別アプリに移して戻すと、一切操作を受付けなくなる。 の問題を無事解決できました。 感謝っ!

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

回答No.2

 こんばんは。  WM_ACTIVATEを適切に処理して、入力デバイスの所有権を切り替えないといけない筈です。 case WM_ACTIVATE: { const BOOL fActive = LOWORD(wParam); const BOOL fMinimized = (BOOL) HIWORD(wParam); HWND hwndPrevious = (HWND)lParam; //ウィンドウが非アクティブに成った時 if(fActive == WA_INACTIVE) { g_lpDIDeviceM->Unacquire(); g_lpDIDeviceK->Unacquire(); } else { g_lpDIDeviceM->Acquire(); g_lpDIDeviceK->Acquire(); } }

zaxs5968
質問者

お礼

ありがとうございます。 このままだと強制終了エラーが出るので、今は取り込む事ができませんでしたが、 ウィンドウのメッセージでの制御の方法もあるのですね。 別の問題が発生した時にこちらの方法を色々調べて行きたいと思います。 ありがとうございましたっ

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • DirectInputについて

    C++でDirectinputの事なのですが。 デバッグには成功するのに、起動した後すぐ強制終了してしまいます。 VOID KeyCheck() { BYTE KeyState[256]; HRESULT hr; hr = g_lpDIDevice->GetDeviceState(256,KeyState); if (SUCCEEDED(hr)) { if (KeyState[DIK_LEFT]&0x80) muki=0; } else hr = g_lpDIDevice->Acquire(); } directxの勉強に簡単なものを書いてみようと思ったのですが、どの辺りがいけないのでしょうか?

  • DirectInput

    VisualStudio2008で、 http://spiralray.rakusei.info/help/directx_practice.zip このソースコードをビルドすると、以下のようなエラーが出ます 1>------ ビルド開始: プロジェクト: CreateDevice, 構成: Release Win32 ------ 1>コンパイルしています... 1>main.cpp 1>D:\Program Files\Microsoft DirectX SDK (March 2008)\Include\dinput.h: DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800 1>リンクしています... 1>main.obj : error LNK2001: 外部シンボル "_c_dfDIKeyboard" は未解決です。 1>main.obj : error LNK2001: 外部シンボル "_c_dfDIJoystick2" は未解決です。 1>main.obj : error LNK2019: 未解決の外部シンボル _DirectInput8Create@20 が関数 "long __cdecl InitDirectInput(struct HWND__ *,struct HINSTANCE__ *)" (?InitDirectInput@@YAJPAUHWND__@@PAUHINSTANCE__@@@Z) で参照されました。 1>Release/CreateDevice.exe : fatal error LNK1120: 外部参照 3 が未解決です。 1>ビルドログは "file://d:\Documents\Visual Studio 2008\Projects\DirectX_Practice\Release\BuildLog.htm" に保存されました。 1>CreateDevice - エラー 4、警告 0 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== DirectInputを導入しようとした矢先にコレで、何が何だかわからないのですが、どうすればいいのでしょうか? どなたかお願いします。

  • DirectInput でのエラー

    LPDIRECTINPUT8 m_pDI; LPDIRECTINPUTDEVICE8 m_pJoystick; 省略 // ゲームコントローラーの列挙 if(FAILED(hr = m_pDI->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCalback, NULL, DIEDFL_ATTACHEDONLY))) return hr; //********************************************************/ BOOL CALLBACK InputDevice::EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, VOID* pContext ) { HRESULT hr; hr = m_pDI->CreateDevice(pdidInstance->guidInstance, &m_pJoystick, NULL); if(FAILED(hr)){ return DIENUM_CONTINUE; }else{ return DIENUM_STOP; } } ゲームコントローラーの列挙をするためのコードを msdn や DirectXSDK のサンプルを 参考に書きました。でもどうしても以下のようなエラーがでます。 キャストなど試してみましたが解決にはいたりませんでした。 どうかご教授おねがいします。 d:\○○△△.cpp(30) : error C2664: 'IDirectInput8A::EnumDevices' : 2 番目の引数を 'BOOL (const DIDEVICEINSTANCE *,void *)' から 'LPDIENUMDEVICESCALLBACKA' に変換できません。

  • DirectInputでの現在のマウス座標は・・?

    DirectInputでマウス座標を取得したいのですが、 lX lY による移動量の取得方法しかわからず、 初回起動時に下のコードで現在座標を取得して扱っているのですが、 ----------------------------------- GetCursorPos(&point); ScreenToClient(hWnd, &point); input_mpos[0] = float(point.x); input_mpos[1] = float(point.y); ----------------------------------- 問題点 1.クライアント領域を抜け、モニターの隅までマウスカーソルが行っても移動量が加算され続け狂ってしまう 2.タイトルバーをダブルクリックして擬似フルスクリーンにすると移動量そのものが通用しない 3.フォーカスが飛んだり、ダイアログボックスが出ると現在座標が狂ってしまう に悩まされています。 常に確実にクライアント内の座標を捕らえ続けられる計算式というか、 定番の手順というものが有ったりするのでしょうか? それとも、マウス座標はDirectXで取得しようとする事そのものが間違いだったりするのでしょうか? 経験者様いらっしゃいましたら、ヒント程度でも構いませんので教えて頂けると幸いです。 orz

  • 十字ボタンのデータについて

    連続して質問して申し訳ありませんがどうか質問させてください。 早速ですがDirectInputのモジュールを作っているんですが、 ジョイスティックからのデータの受け取りで、 各ボタンは問題ないのですが、十字ボタンからのデータを、 うまく認識してくれません。 ●Input.h --省略-- class Input{ public: BOOL JoyData(int ButtonNo); BOOL UP() {return JoyData(0);} BOOL DOWN() {return JoyData(1);} }; ●Input.cpp BOOL Input::JoyData(int No) { DIJOYSTATE2 js; m_pJoystick->Acquire(); m_pJoystick->GetDeviceState(sizeof(DIJOYSTATE2), &js); switch(ButtonNo){ case 0: if(js.lY < 0) return TRUE; // Up break; case 1: if(js.lY > 0) return TRUE; // DOWN break; } } ●Main.cpp HRESULT hr; if( FAILED( hr = CMyD3DApplication::FrameMove(fElapsedTime))) return hr; D3DXMATRIX matWorld; D3DXMATRIX matRotY; D3DXMATRIX matRotX; m_DInput.JoyUpdate(); if(m_DInput.UP()) m_fWorldRotX += m_fElapsedTime * 0.5f; //UP if(m_DInput.DOWN()) m_fWorldRotX -= m_fElapsedTime * 0.5f; //DOWN D3DXMatrixRotationX( &matRotX, m_fWorldRotX ); ポリゴン一つ表示させているのですが、十字ボタンを押していないのに勝手に 下側に動き出してしまうのです。 十字ボタンはどの様な値でゲームパッドからデータを受け取っているのでしょうか この十字ボタンがうまく動かない現象どうかご教授おねがいします。

  • C++のクラスポインタの初期化?

    C言語しか経験がないものです。最近Irrlichtでゲームをつくりはじめました。いきなりチュートリアルがわからないので質問させていただきます。 IrrlichtDevice *device = createDevice( video::EDT_SOFTWARE, dimension2d<u32>(640, 480), 16,     false, false, false, 0); if (!device) return 1; という部分で、 (1) *devide = createDevice( ...);  なぜクラスポインタが関数で初期化できるのですか。  アドレスを入れないのはなぜなのでしょうか。 (2) if(!device)  これだとアドレス値の式を判別しているように思いますが、どういうことですか。 初歩的な質問で申し訳ございません。

  • DirectXを用いたActiveXを用いてVistaで情報が取れない

    ActiveXからDirectXを叩いてOSやCPUなどの情報を 取得しようとしています。 XPでは問題なく情報が取れますが、Vistaでは 情報が取れる項目と取れない項目があります。 この現象について、教えてください。 APIは正常に終了しています。 OS(szOSExLongEnglish) → 正常取得 ベンダー(szSystemManufacturerEnglish) → n/a 型番(szSystemModelEnglish) → n/a CPU(szProcessorEnglish) → (空白) 物理メモリ(szPhysicalMemoryEnglish)  → 正常取得 IEのデフォルトの設定では上記のような状態ですが、 設定を変えて保護モードを外すと正常動作し、 すべての情報が取得できます。 しかし、保護モードが有効の状態で、 情報取得したいです。 以下にコードを書きます。 ※このコードはあるサンプルソースをほとんどそのまま使っています。 //////////////////////////////////////////////////////////////////////////////// // 初期化 //////////////////////////////////////////////////////////////////////////////// bool CDxDiagLib::Init(void) { HRESULT hr; DXDIAG_INIT_PARAMS dxDiagInitParam; m_pDxDiagProvider = NULL; m_pDxDiagRoot = NULL; g_DxDiagInfo = NULL; g_DxSoundInfo = NULL; // COMライブラリを使用できるように初期化 hr = CoInitialize(NULL); if (FAILED(hr)) { return false; } hr = CoCreateInstance( CLSID_DxDiagProvider, NULL, CLSCTX_INPROC_SERVER, IID_IDxDiagProvider, (LPVOID*) &m_pDxDiagProvider); if( FAILED(hr) || m_pDxDiagProvider == NULL) { return false; } // DXDIAG_INIT_PARAMSを初期化 ZeroMemory( &dxDiagInitParam, sizeof(DXDIAG_INIT_PARAMS) ); dxDiagInitParam.dwSize = sizeof(DXDIAG_INIT_PARAMS); dxDiagInitParam.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION; // WHQLを確認するかどうか // ネットを経由するので基本的にはfalseにしておく dxDiagInitParam.bAllowWHQLChecks = AllowWHQLChecks; dxDiagInitParam.pReserved = NULL; hr = m_pDxDiagProvider->Initialize( &dxDiagInitParam ); if( FAILED(hr) ) { return false; } hr = m_pDxDiagProvider->GetRootContainer( &m_pDxDiagRoot ); if( FAILED(hr) ) { return false; } return true; } //////////////////////////////////////////////////////////////////////////////// // DxDiag でSystem情報を取得 //////////////////////////////////////////////////////////////////////////////// bool CDxDiagLib::GetSyatemInfo( void ) { HRESULT hr; IDxDiagContainer* pObject = NULL; DWORD nInstanceCount = 0; DWORD nItem = 0; DWORD nCurCount = 0; // "DxDiag_SystemInfo" を取得 if( FAILED( hr = m_pDxDiagRoot->GetChildContainer( L"DxDiag_SystemInfo", &pObject ) ) ) { return false; } // 情報保存領域の確保 ZeroMemory(&g_DxDiagSysInfo, sizeof(g_DxDiagSysInfo)); if( FAILED( hr = GetStringValue( pObject, L"szOSExLongEnglish", g_DxDiagSysInfo.cOS , sizeof(g_DxDiagSysInfo.cOS) ) ) ) { SAFE_RELEASE( pObject ); return false; } if( FAILED( hr = GetStringValue( pObject, L"szSystemManufacturerEnglish", g_DxDiagSysInfo.cManufacturer , sizeof(g_DxDiagSysInfo.cManufacturer) ) ) ) { SAFE_RELEASE( pObject ); return false; } if( FAILED( hr = GetStringValue( pObject, L"szSystemModelEnglish", g_DxDiagSysInfo.cModel , sizeof(g_DxDiagSysInfo.cModel) ) ) ) { SAFE_RELEASE( pObject ); return false; } if( FAILED( hr = GetStringValue( pObject, L"szProcessorEnglish", g_DxDiagSysInfo.cProcessor , sizeof(g_DxDiagSysInfo.cProcessor) ) ) ) { SAFE_RELEASE( pObject ); return false; } if( FAILED( hr = GetStringValue( pObject, L"szPhysicalMemoryEnglish", g_DxDiagSysInfo.cMemory , sizeof(g_DxDiagSysInfo.cMemory) ) ) ) { SAFE_RELEASE( pObject ); return false; } SAFE_RELEASE( pObject ); return true; } よろしくお願いいたします。

  • C++ でWindowsAPIを使用する際

    WindowsAPIを使用しようとしているのですが、エラーが出てうまくいきません。 もし原因が分かる方がいらっしゃれば、教えていただけると幸いです。 エラーコード: error C2787:: IFileOperation :このオブジェクトに関連付けられたGUIDがありません。 問題箇所: HRESULT CopyItem(__in PCWSTR pszSrcItem, __in PCWSTR pszDest, PCWSTR pszNewName) { // // Initialize COM as STA. // HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (SUCCEEDED(hr)) { IFileOperation *pfo; // // Create the IFileOperation interface // hr = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pfo));  //※ここでエラー発生  if (SUCCEEDED(hr)) { // // Set the operation flags. Turn off all UI from being shown to the // user during the operation. This includes error, confirmation, // and progress dialogs. // hr = pfo->SetOperationFlags(FOF_NO_UI); if (SUCCEEDED(hr)) { // // Create an IShellItem from the supplied source path. // IShellItem *psiFrom = NULL; hr = SHCreateItemFromParsingName(pszSrcItem, NULL, IID_PPV_ARGS(&psiFrom)); if (SUCCEEDED(hr)) { IShellItem *psiTo = NULL; if (NULL != pszDest) { // // Create an IShellItem from the supplied // destination path. // hr = SHCreateItemFromParsingName(pszDest, NULL, IID_PPV_ARGS(&psiTo)); } if (SUCCEEDED(hr)) { // // Add the operation // hr = pfo->CopyItem(psiFrom, psiTo, pszNewName, NULL); if (NULL != psiTo) { psiTo->Release(); } } psiFrom->Release(); } if (SUCCEEDED(hr)) { // // Perform the operation to copy the file. // hr = pfo->PerformOperations(); } } // // Release the IFileOperation interface. // pfo->Release(); } CoUninitialize(); } return hr; よろしくお願いします。

  • コールバック関数とクラスとの間のトラブル

    // クラスの定義 class CInputDevice{ private: LPDIRECTINPUT8 m_pDInput; LPDIRECTINPUTDEVICE8 m_pJoystick; public: HRESULT CreateInput(HWND hWnd); // コールバック関数 static BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext); }; // メンバ関数 HRESULT CInputDevice::CreateInput(HWND hWnd) { 省 略 // ゲームコントローラーの列挙:コールバック関数呼出 if(FAILED(hr = m_pDInput->EnumDevices(DI8DEVCLASS_GAMECTRL,EnumJoysticksCallback, NULL, DIEDFL_ATTACHEDONLY))) return hr; 省 略 return S_OK; } // コールバック関数 BOOL CALLBACK CInputDevice::EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, VOID* pContext) { HRESULT hr; CInputDevice* pDevice = (CInputDevice*) pContext; // ▼アヤシイ部分 hr = pDevice->m_pDInput->CreateDevice(pdidInstance->guidInstance, &pDevice->m_pJoystick,NULL); if(FAILED(hr)){ return DIENUM_CONTINUE; }else{ return DIENUM_STOP; } } これは下のURLで質問した時のアドバイスを元に修正したものです。 http://oshiete1.goo.ne.jp/kotaeru.php3?q=2305038 おかげでコンパイル時はエラーは出なくなりましたが。。。 実行時メモリに関する警告メッセージが出るようになりました。 そしてデバッガで調べたところ、コールバック関数内で、 どうやらメンバ関数からの値が完全に行き渡っていないようです。 そういえば、 >要は暗黙に使われている this ポインタが邪魔なのですよ と一言書いてあったのですが、これが解決の鍵を持っているのではないかと 思います。試してみましたが返ってエラーが多発するだけで現在STOP状態です。 どうか、ご教授ください。おねがいします!

  • BHO-3

    いつもお世話になっています。 STDMETHODIMP CHelloWorldBHO::SetSite(IUnknown* pUnkSite) { HRESULT hr = S_OK; if (m_pSite != NULL){ m_pSite->Release(); m_pSite = NULL; } if (pUnkSite != NULL) { IHTMLDocument3 *pDocument3; HRESULT hr2 = pUnkSite->QueryInterface(IID_IHTMLDocument3, (void **)&pDocument3); if (SUCCEEDED(hr2)){ PutEventHandler(pDocument3); } ////////////////////////////// // IWebBrowser2 へのポインタをキャッシュします。 HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void **)&m_spWebBrowser); if (SUCCEEDED(hr)) { // DWebBrowserEvents2 からのイベントをシンクに登録します。 hr = DispEventAdvise(m_spWebBrowser); if (SUCCEEDED(hr)) { m_fAdvised = TRUE; } } 上のコードの IHTMLDocument3 *pDocument3; HRESULT hr2 = pUnkSite->QueryInterface(IID_IHTMLDocument3, (void **)&pDocument3); if (SUCCEEDED(hr2)){ PutEventHandler(pDocument3); } ですが、 HRESULT hr2 = pUnkSite->QueryInterface(IID_IHTMLDocument3, (void **)&pDocument3); の部分で失敗します。 HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void **)&m_spWebBrowser); if (SUCCEEDED(hr)) { // DWebBrowserEvents2 からのイベントをシンクに登録します。 hr = DispEventAdvise(m_spWebBrowser); if (SUCCEEDED(hr)) { m_fAdvised = TRUE; } } が、上手く動くのでまねをしたのですが上手く行きません。 すみませんが、アドバイスお願いします。