DirectInput stops reading keys after backgrounded

Started by
11 comments, last by 21st Century Moose 11 years, 10 months ago
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!
Advertisement
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! smile.png
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.
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]

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

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 raw input, not DirectInput. DirectInput is both deprecated and not recommended for use by Microsoft.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

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.
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.
I've never used DirectInput for keyboard, but when working with joysticks (maybe it's similar to keyboard), you can use this line:
pJoystick->SetCooperativeLevel(m_hWnd, DISCL_EXCLUSIVE | DISCL_BACKGROUND);
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.


Unless you're working with joysticks (and even then), you should be using raw input, not DirectInput. DirectInput is both deprecated and not recommended for use by Microsoft.

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...


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.


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:

By supporting XInput only, your game will not work with legacy DirectInput devices. XInput will not recognize these devices.
If you want your game to support legacy DirectInput 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?
Thanks for everyone's help.

Khatharr, I tried both zeroing the struct, and messing around with the brush types, unfortunately to no avail.
Erlex, can you show your WindProc?

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

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]
About the missing min/max/close buttons, change W[size="2"]S_OVERLAPPED to [size="2"]WS_OVERLAPPEDWINDOW.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

This topic is closed to new replies.

Advertisement