2017-05-12 17 views
2

나는 IDirectInputDevice8 인터페이스를 사용하여 직접 입력 장치에 폴링전화을 차단하는 차단 및 비 할 필요가있다.Microsoft의 IDirectInputDevice8을 사용하여 C++에서 조이스틱 코드를 ​​구현하는 방법은 무엇입니까?

차단 할 수있는 리눅스에서

, 우리는 사용 선택 예 : 내가 설정하더라도 https://msdn.microsoft.com/en-us/library/windows/desktop/ee417816(v=vs.85).aspx

: 나는 idirectinputdevice8인터페이스를 사용하여 같은 일을 할 수있는 방법

while(::select(_jdev+1, &set, NULL, NULL, &tv) > 0) 
{ 
    if(::read(_jdev, &js, sizeof(js_event)) != sizeof(js_event)) 
    { 
     perror("Joystick : read error"); 
     return; 
    } 

    _handleEvent(js); 
} 

IDirectInputDevice8 :: SetEventNotification(), 새로운 데이터를 가져 오기 위해 매번 poll()을 호출해야하는데 이것은 w가 아닙니다. orkable 솔루션은 cpu가 회전 할 것이기 때문입니다.

어떻게하면됩니까?

*** 지금은 조이스틱 장치에서 데이터를 찾고, 반복하고, 연결하고 가져올 수 있습니다. 차단 호출이 구현되지 않았습니다.

가 ... 여기 내 실험/테스트 코드입니다 ... 구문 오류

#include <windows.h> 
#include <dinput.h> 
#include <stdio.h> 
#include <iostream> 
#include <sstream> 
#include "joystick.h" 


LPDIRECTINPUT8 di; 
HRESULT hr; 
LPDIRECTINPUTDEVICE8 joystick; 
DIDEVCAPS capabilities; 

BOOL CALLBACK 
enumCallback(const DIDEVICEINSTANCE* instance, VOID* context) 
{ 
    HRESULT hr; 
    hr = di->CreateDevice(instance->guidInstance, &joystick, NULL); 
    if (FAILED(hr)) { 
     return DIENUM_CONTINUE; 
    } 
    return DIENUM_STOP; 
} 

int JoyStickProp() 
{ 
    if (FAILED(hr = joystick->SetDataFormat(&c_dfDIJoystick2))) { 
     return hr; 
    } 
    if (FAILED(hr = joystick->SetCooperativeLevel(NULL, DISCL_EXCLUSIVE | 
     DISCL_FOREGROUND))) { 
     return hr; 
    } 
    capabilities.dwSize = sizeof(DIDEVCAPS); 
    if (FAILED(hr = joystick->GetCapabilities(&capabilities))) { 
     return hr; 
    } 
} 

HRESULT JoyStickPoll(DIJOYSTATE2 *js) 
{ 
    HRESULT  hr; 

    if (joystick == NULL) { 
     return S_OK; 
    } 

    // Poll the device to read the current state 
    hr = joystick->Poll(); 
    if (FAILED(hr)) { 
     hr = joystick->Acquire(); 
     while (hr == DIERR_INPUTLOST) { 
      hr = joystick->Acquire(); 
     } 

     if ((hr == DIERR_INVALIDPARAM) || (hr == DIERR_NOTINITIALIZED)) { 
      return E_FAIL; 
     } 

     // If another application has control of this device, return successfully. 
     // We'll just have to wait our turn to use the joystick. 
     if (hr == DIERR_OTHERAPPHASPRIO) { 
      return S_OK; 
     } 
    } 

    // Get the input's device state 
    if (FAILED(hr = joystick->GetDeviceState(sizeof(DIJOYSTATE2), js))) { 
     return hr; // The device should have been acquired during the Poll() 
    } 

    return S_OK; 
} 

int main() 
{ 


    // Create a DirectInput device 
    if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, 
     IID_IDirectInput8, (VOID**)&di, NULL))) { 
     return hr; 
    } 

    // Look for the first simple joystick we can find. 
    if (FAILED(hr = di->EnumDevices(DI8DEVCLASS_GAMECTRL, enumCallback, 
     NULL, DIEDFL_ATTACHEDONLY))) { 
     return hr; 
    } 
    // Make sure we got a joystick 
    if (joystick == NULL) { 
     printf("Joystick not found.\n"); 
     return E_FAIL; 
    } 

    JoyStickProp(); 
    DIJOYSTATE2 diState; 

    HANDLE ghWriteEvent; 
    // Create joystick event stuff here 
    ghWriteEvent = CreateEvent(
     NULL,    // default security attributes 
     FALSE,    // manual-reset event 
     FALSE,    // initial state is nonsignaled 
     TEXT("WriteEvent") // object name 
     ); 

    //makesure we can read fromt the joystick before waiting for an event 
    JoyStickPoll(&diState); 
    printf("x axis %d", diState.lX); 
    printf("y axis %d", diState.lY); 
    JoyStickPoll(&diState); 
    printf("x axis %d", diState.lX); 
    printf("y axis %d", diState.lY); 
    JoyStickPoll(&diState); 
    printf("x axis %d", diState.lX); 
    printf("y axis %d", diState.lY); 
    JoyStickPoll(&diState); 
    printf("x axis %d", diState.lX); 
    printf("y axis %d", diState.lY); 
    JoyStickPoll(&diState); 
    printf("x axis %d", diState.lX); 
    printf("y axis %d", diState.lY); 
    JoyStickPoll(&diState); 
    printf("x axis %d", diState.lX); 
    printf("y axis %d", diState.lY); 
joystick->SetEventNotification(ghWriteEvent); 
    while (TRUE) { 

     DWORD dwResult = WaitForSingleObject(
      ghWriteEvent, // event handle 
      INFINITE); 

     switch (dwResult) { 
     case WAIT_OBJECT_0: 
      // Event 1 has been set. If the event was created as 
      // autoreset, it has also been reset. 
      int x = 0; 
      //ProcessInputEvent1(); 
      break; 
     } 
    } 
} 
+0

[밑줄을보세요.] (http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-ac-identifier) ​​있다면 정말 짜증이납니다. 컴파일러의 표준 라이브러리 구현에 정의 된'_handleEvent' 또는'_jdev'가 코드와 교차됩니다. – user4581301

+0

그건 내가 리눅스에서 코드를 내가 Windows에서 성취하고자하는 것에 대한 예제로 ... 그것은 Windows 코드 또는 현재 문제와 관련이 없습니다. –

+0

부적절합니다. 밑줄은 C++에서 C++ 표준에 의해 정의 된 특별한 의미를 지니고 있습니다. 규칙이 Linux 또는 Windows 용인지 여부에 관계없이 규칙은 동일합니다. 결과 만 다릅니다.어떻게 사용하는지주의하십시오. – user4581301

답변

1

IDirectInputDevice8::SetEventNotification()에 대한 MSDN 문서는 당신에게 관련 코드 조각을 제공 무시하십시오.

CreateEvent()으로 전화하여 SetEventNotification()에 대한 인수로 HANDLE을 제공해야합니다. 상태 변경이 발생할 때 이벤트가 신호로 보내집니다. 이벤트가 발생할 때까지 기다렸다가 알림을 받으면 IDirectInputDevice8::GetDeviceState()을 사용하여 새 상태 데이터를 얻습니다.

모든 표준 Wait Functions은 이벤트가 신호를받을 때까지 대기 할 수 있습니다. IDirectInputDevice8::Poll() 방법은 이벤트 알림을 생성하지 않는 장치에 사용되는

while (TRUE) { 

    dwResult = MsgWaitForMultipleObjects(2, ah, FALSE, INFINITE, QS_ALLINPUT); 
    switch (dwResult) { 
     case WAIT_OBJECT_0: 
      // Event 1 has been set. If the event was created as 
      // autoreset, it has also been reset. 
      ProcessInputEvent1(); 
      break; 

: 다음 코드는 당신에게 MsgWaitForMultipleObjects()를 사용하는 한 가지 방법을 보여줍니다. 자신이 원하는 방식으로 운영 할 수 없기 때문에 투표를해야합니다.

일부 조이스틱 및 기타 게임 장치 또는 그 위의 특정 개체는 do not generate hardware interrupts and do not return any data or signal any events until you call the IDirectInputDevice8::Poll method입니다.

장치에 대한 알림이 작동하지 않을 때만 폴링합니다. 위의 링크는 폴링이 필요한지 여부를 식별하는 방법을 설명합니다.

+0

내가 잘못했으면 폴링을 호출 할 때까지 이벤트가 호출되지 않습니다. 내가하고 싶은 것은/무엇이 일어날 것인가는 상태 변경 이벤트를 기다리고 나서 투표를 호출 할 수 있다는 것입니다. –

+0

방금 ​​이벤트와 별도의 스레드가 생성되어 실행된다는 것을 깨달았습니다. 아마도 어쩌면 그 일을 버릴 수 있습니다. 시도해보고 다시 보겠습니다. –

+2

@lukesignh : CreateEvent()로 생성 된 이벤트가 아닙니다. 특정 스레드에 연결됩니다. 하나 이상의 스레드가 다른 스레드가 신호를 보내는 동안 이벤트를 대기 할 수 있습니다. 그래서 그것은 당신의 문제가 아닙니다. 질문을 편집하여 실제 작동하지 않는 코드를 표시하십시오. –