- ベストアンサー
DirectInputについて再
前に回答してくださった方すみません。 directinputで、デバックに成功して実行してみるとすぐに強制終了してしまう問題なのですが。 VOID KeyCheck() { BYTE KeyState[256]; HRESULT hr; hr = g_lpDIDevice->GetDeviceState(256,KeyState); if (SUCCEEDED(hr)) { if (KeyState[DIK_LEFT]&0x80) muki=0; } } 強制終了が出なくなったのはこの処理が実行されていなかっただけらしく、まだおかしいみたいなんです。 hr = g_lpDIDevice->GetDeviceState(256,KeyState); この文辺りが怪しいと思って256をsizeof(KeyState)にしたりなどいろいろなサイトで違った方法を試したりなどしたのですが、解決しませんでした。 OSはVistaの32bitなのですが、どのようにすれば治るでしょうか?
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
こんばんは。前回回答した者です。えぇと、拝見させて頂きました。グローバル変数がパラメータの名前になっていたりと、大分怪しい所だらけなのですが、「g_pKeyboard->SetCooperativeLevel」で強調レベルを設定した後の「g_pKeyboard->SetProperty」が抜けています。其の外にも「WM_ACTIVATE」を処理していない為、制御権の獲得が出来て居ない状態です。この状態での動作は絶望的かと。 以下修正品です。どの様にするのかを参考程度に見て下さい。 LPDIRECTINPUT8 g_pDI; LPDIRECTINPUTDEVICE8 g_pKeyboard; int muki; //此れは要らないのでは? HRESULT InitD3D(HWND hWnd) { return DI_OK; } //ジオメトリ? HRESULT InitGeometry() { return DI_OK; } //レンダリングして下さい void Render() { } //----------------------------------------------------------------------------- BOOL DI_Init(HWND hWnd, HINSTANCE hInst) { HRESULT hr = DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&g_pDI, NULL); if(FAILED(hr)) return FALSE; hr = g_pDI->CreateDevice(GUID_SysKeyboard, &g_pKeyboard, NULL); if(FAILED(hr)) return FALSE; hr = g_pKeyboard->SetDataFormat(&c_dfDIKeyboard); if(FAILED(hr)) return FALSE; hr = g_pKeyboard->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); if(FAILED(hr)) return FALSE; //キーボードの設定 //↓此れを設定しないといけません DIPROPDWORD dipdw; dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = 8; hr = g_pKeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph); //↑此処まで return SUCCEEDED(hr); } //----------------------------------------------------------------------------- VOID KeyCheck() { if(!g_pKeyboard) return; BYTE KeyState[256]; HRESULT hr = g_pKeyboard->GetDeviceState(256,KeyState); if(FAILED(hr)) { return; } if(KeyState[DIK_RIGHT]&0x80) { muki++; ::MessageBox(0, L"右ボタンが押された", L"入力テスト", MB_OK); } } LRESULT CALLBACK MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_CREATE: { return TRUE; } case WM_CLOSE : { ::DestroyWindow(hWnd); return FALSE; } case WM_DESTROY : { ::PostQuitMessage(0); return FALSE; } case WM_ACTIVATE: { if(!g_pKeyboard) break; //制御権の切り替え if(wParam == WA_INACTIVE) { g_pKeyboard->Unacquire(); } else { g_pKeyboard->Acquire(); } return FALSE; } } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT ) { MSG msg; WNDCLASSEX wc = {sizeof(WNDCLASSEX)}; wc.lpszClassName = L"D3D Tutorial"; wc.lpfnWndProc = MsgProc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.hInstance = hInst; wc.hIcon = LoadIcon(hInst,L"IDI_APPICON"); wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.cbClsExtra = 0; wc.cbWndExtra = 0; if(!RegisterClassEx(&wc)) return FALSE; HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 06: Meshes", WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,NULL, NULL, wc.hInstance, NULL ); ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd); if(FAILED(InitD3D(hWnd))) return 0; if(FAILED(InitGeometry())) return 0; if(FAILED(DI_Init(hWnd, hInst))) return 0; //此処で権利を獲得する g_pKeyboard->Acquire(); while(TRUE) { if(::PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE)) { if(!::GetMessage(&msg, NULL, 0, 0)) break; ::TranslateMessage(&msg); ::DispatchMessage(&msg); } else //アイドリング { KeyCheck(); Render(); } } UnregisterClass( L"D3D Tutorial", wc.hInstance ); return 0; }
その他の回答 (3)
- php504
- ベストアンサー率42% (926/2160)
g_hInstとg_hWndはグローバルで宣言されているのですよね DI_Init() の hr = DirectInput8Create(g_hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&g_pDI, NULL); でg_hInstが初期化状態のままだと思われます。 FALSE(0)で返しているのをSUCCEEDED(>=0)で判定しているのでチェックできていません。 INT WINAPI wWinMain( HINSTANCE g_hInst, HINSTANCE, LPWSTR, INT ) を INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT ) にして g_hInst = hInst; をwWinMain( )内に追加しましょう。 それとグローバルで宣言しているなら HWND g_hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 06: Meshes", のHWNDを削除しましょう。
お礼
ありがとうございます、うまくいきました~
- php504
- ベストアンサー率42% (926/2160)
昔自分が作ったプログラムのソースを見てみたら以下のような処理をしていました hr = g_lpDIDevice->Acquire(); if (hr == DI_OK || hr == S_FALSE) { hr = g_lpDIDevice->GetDeviceState( 256, KeyState); if (SUCCEEDED(hr)) { if (KeyState[DIK_LEFT]&0x80) muki=0; } } 情報取得前にAcquireしてみたらどうでしょう
補足
g_pKeyboard->Acquire();は初期化の際に行っておりますが、試しに書いてみてもダメでした
- SAYKA
- ベストアンサー率34% (944/2776)
その部分だけ出されてもどうにもならないんだけど? 落ちてる部分やそれが関連するソース、ないし以前の質問とやらの番号を提示するべきじゃないかな。 このソースだけだと普通にしかみえない。
補足
以前の質問はこれですね http://okwave.jp/qa4310890.html?ans_count_asc=20 INT WINAPI wWinMain( HINSTANCE g_hInst, HINSTANCE, LPWSTR, INT ) { WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, L"D3D Tutorial", NULL }; RegisterClassEx( &wc ); HWND g_hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 06: Meshes", WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, wc.hInstance, NULL ); if( SUCCEEDED( InitD3D( g_hWnd ) ) ) { if( SUCCEEDED( InitGeometry() ) ) { if( SUCCEEDED( DI_Init() ) ) { ShowWindow( g_hWnd, SW_SHOWDEFAULT ); UpdateWindow( g_hWnd ); MSG msg; ZeroMemory( &msg, sizeof(msg) ); while( msg.message!=WM_QUIT ) { if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else { KeyCheck(); Render(); } } } } } UnregisterClass( L"D3D Tutorial", wc.hInstance ); return 0; } //----------------------------------------------------------------------------- BOOL DI_Init() { HRESULT hr; hr = DirectInput8Create(g_hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&g_pDI, NULL); if FAILED(hr) return FALSE; hr = g_pDI->CreateDevice(GUID_SysKeyboard, &g_pKeyboard, NULL); if FAILED(hr) return FALSE; hr = g_pKeyboard->SetDataFormat(&c_dfDIKeyboard); if FAILED(hr) return FALSE; hr = g_pKeyboard->SetCooperativeLevel(g_hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); if FAILED(hr) return FALSE; hr = g_pKeyboard->Acquire(); if FAILED(hr) return FALSE; return TRUE; } //----------------------------------------------------------------------------- VOID KeyCheck() { BYTE KeyState[256]; HRESULT hr; hr = g_pKeyboard->GetDeviceState(256,KeyState); { if (KeyState[DIK_RIGHT]&0x80) muki++; } } wWinMainのKeyCheck();を消すと普通に動作しました。
お礼
ありがとうございます。 今度はきっちり成功しました~