Jump to content
  • Advertisement
Sign in to follow this  
kendoran

DirectInput mouse grab/release

This topic is 5055 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having a major headache with DirectInput 8 mouse capture. What i'm trying to do is move about a 3d world in the same way UnrealEd does. Hold down the right mouse button to grab the mouse cursor, and move the mouse about to change the camera view. In my program it works fine. Right mouse button down captures the mouse, and right mouse button release releases it, and I can interact with other programs without problems while mine is running. The insanity here is that the problem occurs on every other mouse button apart from the left ( DIMOFS_BUTTON0 ) Here's the problem: I hold down the right mouse ( or anything other than the left ) button for more than a few seconds ( 3 ) then release, then do anything, or nothing, then quit the program. I then bring up any window from the taskbar, and it comes into focus fine, then if I click on the menubar of the focused window, it loses focus. If I click on a non-focused menubar of a window, it doesn't gain focus. If I ALT+TAB to any window, the focus problems disappear until I next run my program. The problem doesn't occur until I close my program. I haven't been able to reliably trigger it, but sometimes, I can't even click the taskbar to bring up a window. ( it doesn't react ) The ALT+TAB always corrects the problem. -- The kicker is that the problem doesn't occur when I change the line mouseData.dwOfs == DIMOFS_BUTTON1 to mouseData.dwOfs == DIMOFS_BUTTON0 the error doesn't occur. It's only when BUTTON > 0 that the problem comes up. I can only guess that the problem is within the grabMouseCursor call, but I can't figure out why the problem comes up only when button > 0 Can anybody help here? Matthew. --
When reading buffered data:
    MOUSE_BUFFER_SIZE = 32


    assert(g_Mouse);
    DIDEVICEOBJECTDATA mouseData[MOUSE_BUFFER_SIZE];
    elements = MOUSE_BUFFER_SIZE;
    hr = g_Mouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA),
                                 mouseData, &elements, 0 );
    
    if ( hr != DI_OK ) {
        hr = g_Mouse->Acquire();
        while ( hr == DIERR_INPUTLOST )
            hr = g_Mouse->Acquire();
        
        return;
    }


    if ( mouseData.dwOfs == DIMOFS_BUTTON0 ) {
                static bool grab = true;
        
                common.sys->grabMouseCursor(grab);   
                grab = !grab; 
    }

--

void blSys::grabMouseCursor( bool grabIt ) {
    HRESULT hr = DI_OK;
    DWORD coopFlags;
      
    if ( grabIt )   coopFlags = DISCL_EXCLUSIVE | DISCL_FOREGROUND;
    else            coopFlags = DISCL_NONEXCLUSIVE | DISCL_FOREGROUND;
    
    assert(g_Mouse);
    g_Mouse->Unacquire();
    hr = g_Mouse->SetCooperativeLevel( _window.hwnd, coopFlags );
    assert( hr == DI_OK );
    g_Mouse->Acquire();
}

-- My setup code is:
    hr = g_DI->CreateDevice( GUID_SysMouse, &g_Mouse, NULL );
    assert( hr == DI_OK );
    
    // c_dfDIMouse2 allows support for more than 4 mouse buttons
    hr = g_Mouse->SetDataFormat( &c_dfDIMouse2 );
    assert( hr == DI_OK );
    
    dipdw.dwData           = MOUSE_BUFFER_SIZE;
    hr = g_Mouse->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph );
    assert( hr == DI_OK );
      
    grabMouseCursor(false);
       
    SetTimer(_window.hwnd, 0, 1000/60, NULL );

-- The timer event updates calls the reading buffered data method above -- And my shutdown code:
    if ( g_Mouse ) {
        g_Mouse->Unacquire();
        g_Mouse->Release();
        g_Mouse = 0;
    }

--

Share this post


Link to post
Share on other sites
Advertisement
Sheesh! Replying to my own post. A thread consisting of just me! Awww.

Well, it doesn't look like anybody is going to reply, but I've solved the problem, and my grab/release code works like a charm.

I'm not sure why it was a problem, but it seems the trouble was something to do with the SetCooperativeLevel. If someone could enlighten me, that would be great.

So, when initalising, I SetCooperativeLevel only once using the non-exclusive, and foreground flags. I then grabMouseCursor(false), and I then can grab, and relase in any situation without troubles.

There is also some trivial code in the WinProc function to Unacquire/reaquire the device when the window loses/gains focus respectively.

I modified my grabMouseCursor function, and here it is:

void blSys::grabMouseCursor( bool grabIt ) {
assert(g_Mouse);

if ( grabIt) {
g_Mouse->Acquire();
while ( ShowCursor( false ) >= 0 );
GetCursorPos( &g_MouseOldPos );
}
else {
g_Mouse->Unacquire();
SetCursor(LoadCursor(NULL, IDC_ARROW));
while( ShowCursor( true ) <= 0 );
g_Mouse->Acquire();
if ( g_MouseIsGrabbed ) SetCursorPos( g_MouseOldPos.x, g_MouseOldPos.y );
}

g_MouseIsGrabbed = grabIt;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!