DirectInputSample.zip 155,307 bytes.
di is a really simple MFC app that demonstrates the use of buffered keyboard input. MFC was used as the whole thing was coded, designed, etc. in less than an hour. AppWizard again. :)
It is not an example of how to code in MFC. Just be aware of that.
The zip file contains a VC4.2 project and requires DX3 to build. The release build is included.
The 'clumps' that the output refers to is based on the fact that each pass through on the polling loop, as many events are grabbed as are in the queue.
I was trying to figure out a way to parse when the pause key was hit; the byte stream is similiar to hooking INT 9, but missing the E1 flag byte; ie:
Pressing the Pause Key in DOS and with DI:
| DirectInput | DOS |
| 1d 80 | e1 |
| 45 80 | 1d |
| 1d 00 | 45 |
| 45 00 | e1 |
| 9d | |
| c5 |
All numbers in hex
The DirectInput system is not returning the e1 to let you know that a multi-byte sequence is on the way.
And, you don't always get all four events in one clump all of the time!
This made it useless for what I was doing with Hexen95; which brings me to the next topic:
This is what I've ended up using again (as in Doom95) in Hexen95.
Here is a code snippet of the basics of hooking. There is more to be done. I can't give away id's code, of course; but this will give you the basics of getting started:
LRESULT CALLBACK
KeyboardProc( int code, WPARAM wParam, LPARAM lParam )
{
WORD wInfo = (WORD) (lParam >> 16);
BOOL fDown = !(wInfo & KF_UP);
BOOL fRepeat = wInfo & KF_REPEAT;
// check for ctrl-alt-del
if (wParam == VK_DELETE && (wInfo & KF_ALTDOWN) &&
(GetAsyncKeyState(VK_CONTROL) & 0x80000000))
return CallNextHookEx( hh, code, wParam, lParam );
// check for ctrl-esc
if (wParam == VK_ESCAPE && (GetAsyncKeyState(VK_CONTROL) & 0x80000000))
return CallNextHookEx( hh, code, wParam, lParam );
// check for alt-tab
if (wParam == VK_TAB && (wInfo & KF_ALTDOWN))
return CallNextHookEx( hh, code, wParam, lParam );
// feed the keystroke to your game loop here
// ie. post to to an internal event queue, whatever
// eat alt and f10 so our system menu doesn't pop down
// thus pausing our game!
if (wParam == 121 || wParam == 18)
return 1;
return CallNextHookEx( hh, code, wParam, lParam );
}
void
GrabKeys(BOOL f)
{
if (f)
{
hh = SetWindowsHookEx(WH_KEYBOARD,
(HOOKPROC) KeyboardProc,
hInstApp,
GetCurrentThreadId());
if (hh == NULL)
{
Message("hook set failed! %x", GetLastError());
}
}
else
{
if (UnhookWindowsHookEx( hh ) == FALSE)
{
Message("unhook set failed! %x", GetLastError());
}
}
}
LRESULT CALLBACK
WindowProc(HWND hwnd, unsigned uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_ACTIVATEAPP:
if (wParam)
{
Message("WM_ACTIVATEAPP: activation");
// activate
GrabKeys( TRUE );
}
else
{
// deactivate
Message("WM_ACTIVATEAPP: de-activation");
GrabKeys(FALSE);
}
return 0;
}
}