Jump to content

  • Log In with Google      Sign In   
  • Create Account


DirectInput stops reading keys after backgrounded


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
12 replies to this topic

#1 Erlex   Members   -  Reputation: 111

Like
0Likes
Like

Posted 12 June 2012 - 02:59 PM

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!

Sponsor:

#2 Khatharr   Crossbones+   -  Reputation: 2972

Like
1Likes
Like

Posted 13 June 2012 - 04:33 PM

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! Posted Image

Edited by Khatharr, 13 June 2012 - 04:35 PM.

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.

#3 Erlex   Members   -  Reputation: 111

Like
0Likes
Like

Posted 13 June 2012 - 05:22 PM

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, 13 June 2012 - 05:23 PM.


#4 Washu   Senior Moderators   -  Reputation: 5046

Like
1Likes
Like

Posted 13 June 2012 - 05:27 PM

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.

Edited by Washu, 13 June 2012 - 05:29 PM.

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.
ScapeCode - Blog | SlimDX


#5 Khatharr   Crossbones+   -  Reputation: 2972

Like
0Likes
Like

Posted 13 June 2012 - 09:11 PM

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.

#6 Tom KQT   Members   -  Reputation: 1569

Like
1Likes
Like

Posted 14 June 2012 - 12:48 AM

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.

That doesn't sound like Microsoft not recommending to use DirectInput at all, does it?

Edited by Tom KQT, 14 June 2012 - 12:49 AM.


#7 Erlex   Members   -  Reputation: 111

Like
0Likes
Like

Posted 14 June 2012 - 12:07 PM

Thanks for everyone's help.

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

#8 Endurion   Crossbones+   -  Reputation: 3485

Like
0Likes
Like

Posted 14 June 2012 - 10:42 PM

Erlex, can you show your WindProc?
Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

#9 Erlex   Members   -  Reputation: 111

Like
0Likes
Like

Posted 15 June 2012 - 01:08 PM

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]

#10 Endurion   Crossbones+   -  Reputation: 3485

Like
1Likes
Like

Posted 15 June 2012 - 11:26 PM

About the missing min/max/close buttons, change WS_OVERLAPPED to WS_OVERLAPPEDWINDOW.
Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

#11 Erlex   Members   -  Reputation: 111

Like
0Likes
Like

Posted 16 June 2012 - 04:43 PM

That worked Endurion, thanks a lot. :)

#12 Khatharr   Crossbones+   -  Reputation: 2972

Like
0Likes
Like

Posted 19 June 2012 - 08:12 PM

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

#13 mhagain   Crossbones+   -  Reputation: 7866

Like
0Likes
Like

Posted 20 June 2012 - 03:27 AM

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.

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS