March 29, 2024, 05:44:59 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


DIK_LWIN eaten

Started by sapero, October 18, 2007, 01:57:40 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

sapero

I'm writing a mini player as property page. In full screen mode I needed also to detect mouse wheel and keystokes.
So I have used the DirectInput interfaces, because DirectShow does not support WM_MOUSEWHEEL forwarding.
The routine for keyboard has implemented autorepeat functionality.
When i switch to another (logged on) user with the LWIN+L hotkey, and return back, after switching the video to full screen mode the dinput device reports that LWIN key is still pressed, until I press it again.

Here is my routineCDInput::OnTimer()
{
if (this->keyboard)
{
HRESULT hr = this->keyboard->GetDeviceState(256, &this->keystate); // byte keystate[256]
if (hr == DIERR_INPUTLOST)
{
hr = this->keyboard->Acquire(); // never here
if (!hr)
hr = this->keyboard->GetDeviceState(256, &this->keystate);
}
if (!hr)
{
UCHAR *pCounter = this->counters; // byte counters[256]

for (int a=1; a<256; a++)
{
if (!(this->keystate[a] & 0x80))
{
*pCounter = 255; // idle
}
else
{
if (*pCounter == 255)
{
*pCounter = repeat1; // just pressed
SendMessage(m_hwnd, WM_DI_CHAR, a, 0);
}
*pCounter--;
if (!*pCounter)
{
*pCounter  = repeat2; // autorepeat
SendMessage(m_hwnd, WM_DI_CHAR, a, 0);
}
}
pCounter++;
}
}
}
}

keyboard->GetDeviceState always return success.
I'm sure the LWIN+L hotkey is first posted to the winlogon process, winlogon switches the desktop, but the release-key event is posted to winlogon desktop.
But why after returning to user desktop, the direct input driver reports this key still pressed?

Here's example code for XP users with Fast User Switching service running, it shows how this bug works:sub main()
{
CDirectInput di;
CWindow w;
di.Init(w);
print("press left WIN key, press L, release both, and return to this desktop");

di.WaitKey(DIK_LWIN);
print("DIK_LWIN ok");
di.WaitKey(DIK_L);
print("DIK_L ok");

print("press escape to quit");

while (!di.KeyDown(DIK_ESCAPE))
{
if (di.KeyDown(DIK_LWIN))
print("DIK_LWIN is down\x0D",)
else
print("DIK_LWIN is up  \x0D",);

import int Sleep(int t);
Sleep(20);
}
return 0;
}

When you return to your desktop, the console will display "DIK_LWIN is down". Sometimes DIK_L is down too.
I think, I need to call GetAsyncKeyState before accepting directinput data as trusted.

BTW the WaitKey method could use SetEventNotification + WaitForSingleObject to reduce power consumption.