DirectInput Tips by Wild Tangent

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:

Keyboard Hooks

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;
  }
}

The Game Programming MegaSite
The Entire Site ©1996,1997,1998 Matt Reiferson.
Any Questions/Comments, Feel Free To E-Mail Me.