-1

Using DirectX 9, I am unable to acquire the keyboard device if another program has focus while my program is trying to acquire it. This is a problem if the user clicks another window while my program is initializing.

I call Windows's SetFocus and SetCapture functions, but it doesn't seem to have an effect.

#define FAILED(hr) (((HRESULT)(hr)) < 0) //in WinError.h

...

class CantCreate {}; //My exception class

Keyboard::Keyboard(LPDIRECTINPUT8 pDI, HWND hwnd)

{

LPDIRECTINPUTDEVICE8 m_pDIDev;

if (FAILED(pDI->CreateDevice(GUID_SysKeyboard, &m_pDIDev, NULL)))

throw CantCreate();

if (FAILED(m_pDIDev->SetDataFormat(&c_dfDIKeyboard)))

throw CantCreate();

if(FAILED(m_pDIDev->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))

throw CantCreate();

SetFocus (hwnd); SetCapture (hwnd);

if (FAILED(m_pDIDev->Acquire())) throw CantCreate(); //<-- throws an exception here
}

I've also tried replacing that last line with

while (FAILED(m_pDIDev->Acquire())) { SetFocus (hwnd); SetCapture (hwnd); }

...but it never does seize focus.

What's the best way either to seize focus, or to acquire the keyboard without needing focus?

Based on discussion from the answer below, I tried this so that it could wait for focus:

while (true)
{
    while (GetFocus () != hwnd) Sleep (100);
    if (! FAILED(m_pDIDev->Acquire())) break;
} 

Sometimes it works beautifully. Sometimes the application freezes.

Topological Sort
  • 2,733
  • 2
  • 27
  • 54

1 Answers1

2

That is a security feature, not a weakness.

If programs could seize the keyboard, think what a pain it would be to exit malware you did not want to run.

Sleep awhile between attempts. Once the focus is changed to your app, then you are allowed to do what you need.

wallyk
  • 56,922
  • 16
  • 83
  • 148