Sign in to follow this  
Erlex

DirectInput stops reading keys after backgrounded

Recommended Posts

Erlex    111
Hello,

I am fairly new to game programming, especially with DirectX. I am an experienced programmer, but not with DirectX or Windows. Like so many, I am going through Beginning Game Programming 3rd, and I have run into a few recurring problems. But before just posting a giant block of code, I thought I would at least ask if anyone has encountered similar problems.

1. I am unable to get my program to read key presses after the program window is back grounded. Everything works until I bring one window up to the front, and bring my program back. Perhaps there is something wrong with my WinProc function?

2. Not a serious problem, but a rather annoying one; the minimize, maximize, and exit buttons that are supposed to be at the top right of the window are not showing up. My WinMain is consistent with the book's. I haven't a clue on this one.

Any help would be very much appreciated. Thank you in advance!

Share this post


Link to post
Share on other sites
Khatharr    8812
If you're not using exclusive access to the device then you'll need to re-acquire it before reading from it any time another process has taken control of it.

Re-acquiring when you already have the device acquired produces no negative results, so it's best to simply re-acquire the device every time before reading its state.

DInput bypasses the winproc. It reads the device state from the hardware rather than from windows messaging, so no worries there.

As for part 2, we'd need to see your window creation routine.

Hope that helps! [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img] Edited by Khatharr

Share this post


Link to post
Share on other sites
Erlex    111
Reaquiring the keyboard at the beginning of the game loop did the trick! Thanks Khatharr.

And here is my WinMain. Keep in mind that this is the same code from the book, and that I have only a surface knowledge of windows. Thanks again for the help.
[source lang="cpp"]int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
//set the new window's properties
WNDCLASSEX wc; //create window class structure

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra= 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = APPTITLE.c_str();
wc.hIconSm = NULL;

RegisterClassEx(&wc);

//create new window
HWND window = CreateWindow(
APPTITLE.c_str(),
APPTITLE.c_str(),
WS_OVERLAPPED,
CW_USEDEFAULT,
CW_USEDEFAULT,
SCREENW,
SCREENH,
NULL,
NULL,
hInstance,
NULL);

//check if window could be created
if(!window){
MessageBox(window, "Cannot create window", "Error", MB_OK);
return 0;
}

//display the window
ShowWindow(window,nCmdShow);
UpdateWindow(window);

//initialize the game
if(!gameInit(window)){
MessageBox(window, "Cannot initialize game", "Error", MB_OK);
return 0;
}

//main message loop
MSG message;
while(!gameover){
if(PeekMessage(&message, NULL, 0, 0, PM_REMOVE)){
TranslateMessage(&message);
DispatchMessage(&message);
}
gameRun(window);
}
gameEnd();

return message.wParam;
}[/source] Edited by Erlex

Share this post


Link to post
Share on other sites
Washu    7829
[quote name='Khatharr' timestamp='1339626780' post='4948955']
DInput bypasses the winproc. It reads the device state from the hardware rather than from windows messaging, so no worries there.
[/quote]
No, actually DInput just runs a message loop for keyboard and mouse input in a separate thread.

Unless you're working with joysticks (and even then), you should be using [url="http://msdn.microsoft.com/en-us/library/windows/desktop/ms645536(v=vs.85).aspx"]raw input[/url], not DirectInput. DirectInput is both deprecated and not recommended for use by [url="http://msdn.microsoft.com/en-us/library/windows/desktop/ee417014(v=vs.85).aspx"]Microsoft[/url]. Edited by Washu

Share this post


Link to post
Share on other sites
Khatharr    8812
The only significant difference I see between your window setup and my own is that I ZeroMemory() the struct before setting its values and I don't set a brush. I'm too lazy right now to look the struct up, but I reckon those two changes would probably fix it either way.

As for using XInput instead of DirectInput, a lot of the affordable books out there still refer to DirectInput. Frankly my experience so far has been that anything Microsoft puts out is deprecated 3 days prior to its release. Maybe that's just me. Either way, DirectInput still works. Once you're on your feet you can pick up XInput later.

Share this post


Link to post
Share on other sites
Tom KQT    1704
I've never used DirectInput for keyboard, but when working with joysticks (maybe it's similar to keyboard), you can use this line:
[CODE]pJoystick->SetCooperativeLevel(m_hWnd, DISCL_EXCLUSIVE | DISCL_BACKGROUND);[/CODE]
and you'll be getting input even when your application is without focus.

BUT - please note that this may not be the same behaviour as you want. As I said, this will mean that your application will be getting the input all the time, when focused and when on the background. In my cases this was exactly what I needed, because my application had to be working always, even when minimised and not visible.

[quote name='Washu' timestamp='1339630036' post='4948978']
Unless you're working with joysticks (and even then), you should be using [url="http://msdn.microsoft.com/en-us/library/windows/desktop/ms645536(v=vs.85).aspx"]raw input[/url], not DirectInput. DirectInput is both deprecated and not recommended for use by [url="http://msdn.microsoft.com/en-us/library/windows/desktop/ee417014(v=vs.85).aspx"]Microsoft[/url].
[/quote]
DirectInput is completely fine for joysticks and other game controllers. It is not recommended by Microsoft for mouse and keyboard. And Microsoft also recommends XInput instead of DirectInput, BUT read my next paragraph below...

[quote name='Khatharr' timestamp='1339643491' post='4949025']
As for using XInput instead of DirectInput, a lot of the affordable books out there still refer to DirectInput. Frankly my experience so far has been that anything Microsoft puts out is deprecated 3 days prior to its release. Maybe that's just me. Either way, DirectInput still works. Once you're on your feet you can pick up XInput later.
[/quote]

You make it sound like if XInput was a replacement of DirectInput. XInput works ONLY with XInput compatible devices - Xbox 360 compatible controllers. There already are some gamepads compatible with this new standard from other manufacturers (I personaly have one from Logitech).
But you still NEED DirectInput to work with other/older devices like joysticks etc.

DirectInput works with everything, including XInput compatible devices. There are just some limitations (for example the two triggers on the Xbox 360 gamepad work as a single axis in DirectInput and thus there will be no difference between both triggers released and both fully pressed).
On the other hand, XInput works ONLY with Xbox 360 devices.

And quoting from the msdn page linked by Washu in his post:
[quote]
By supporting XInput only, your game will not work with legacy [url="http://msdn.microsoft.com/en-us/library/windows/desktop/ee416842%28v=vs.85%29.aspx"]DirectInput[/url] devices. XInput will not recognize these devices.
If you want your game to support legacy [url="http://msdn.microsoft.com/en-us/library/windows/desktop/ee416842%28v=vs.85%29.aspx"]DirectInput[/url] devices, you may use DirectInput and XInput side by side. When enumerating your DirectInput devices, all DirectInput devices will enumerate correctly. All XInput devices will show up as both XInput and DirectInput devices, but they should not be handled through DirectInput. You will need to determine which of your DirectInput devices are legacy devices, and which are XInput devices, and remove them from the enumeration of DirectInput devices.
[/quote]
That doesn't sound like Microsoft not recommending to use DirectInput at all, does it? Edited by Tom KQT

Share this post


Link to post
Share on other sites
Erlex    111
Thanks for everyone's help.

Khatharr, I tried both zeroing the struct, and messing around with the brush types, unfortunately to no avail.

Share this post


Link to post
Share on other sites
Erlex    111
Sure thing.
[source lang="java"]LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){

switch(msg){
case WM_DESTROY:
gameover = true;
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}[/source]

Share this post


Link to post
Share on other sites
Khatharr    8812
OMG, I failed, lol. Good catch, Endurion. I saw "overlapped" and didn't even finish reading the thing all the way.

@Tom KQT - Sorry, I just assumed that they had upgraded XI to replace DI since it's been quite a while since I downloaded the SDK. You say they don't recommend it for mouse and KB? What do they recommend then? Or was I reading that incorrectly?

Share this post


Link to post
Share on other sites
mhagain    13430
DirectInput is still useful in that it bypasses mouse acceleration (which may be highly desirable if you're doing an FPS), automatically clips to the window's client rect, and automatically hides/shows the cursor for you. It's also extremely well-documented, which is a LOT more than can be said for Raw Input. MS may consider it deprecated, but they have yet to produce anything that fully replaces it's functionality.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this