News:

Download Pelles C here: http://www.smorgasbordet.com/pellesc/

Main Menu

Reset NumLock etc.

Started by czerny, January 16, 2015, 04:23:02 PM

Previous topic - Next topic

czerny

Hallo!

It seems as if I have another silly question.

I want to show a busy period by switching the three keyboard leds sequential on and off.

To restore the state of the three keys, I first save it.

But the restauration doesn't work. What I am doing wrong here?

frankie


static void Main_OnPaint(HWND hwnd)
{
PAINTSTRUCT ps;
RECT rc;

BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rc);
DrawText(ps.hdc, _T(" Start"), -1, &rc, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
BusyStart(hwnd, 100);
Sleep(10000);
BusyStop(hwnd);
DrawText(ps.hdc, _T("Stop "), -1, &rc, DT_SINGLELINE | DT_RIGHT | DT_VCENTER);
EndPaint(hwnd, &ps);
}

:o The message loop stocked for 10 seconds?  :o
Check the attachment.
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

czerny

I know that the message loop was blocked. That's why I don't want to use the SetTimer api. The MMTimer do not depend on the message loop.

frankie

Yes, but the keyboard status is not updated in the messages queue so you read again the last state and the final setting is wrong.
Allowing the message loop to run the sample works.
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

czerny

Quote from: frankie on January 17, 2015, 03:40:22 PM
Yes, but the keyboard status is not updated in the messages queue so you read again the last state and the final setting is wrong.
How does GetKeyboardState depend on the message queue? And why is it working ok all the time while rotating the leds?

frankie

#5
To be honest I've not investigated so much because I've no much time, but anyway from MSDN description of GetKeyboardState in remark section:
QuoteAn application can call this function to retrieve the current status of all the virtual keys. The status changes as a thread removes keyboard messages from its message queue. The status does not change as keyboard messages are posted to the thread's message queue, nor does it change as keyboard messages are posted to or retrieved from message queues of other threads.
.
Maybe you simply blindly toggle the status and it seems to work (if the case they should change at half the frequency of timer).
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

czerny

There is something wrong with SetState himself:
#include <windows.h>
#include <stdio.h>

void SetState(BYTE bVk, BYTE bScan, BOOL bState)
{
BYTE keyState[256];

GetKeyboardState((LPBYTE)&keyState);
if ((bState && !(keyState[bVk] & 1)) || (!bState && (keyState[bVk] & 1)))
{
keybd_event(bVk, bScan, KEYEVENTF_EXTENDEDKEY | 0, 0);
keybd_event(bVk, bScan, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
}
}
int main(int argc, char **argv)
{
SetState(VK_SCROLL, 0x46, TRUE);
Sleep(2000);
SetState(VK_SCROLL, 0x46, FALSE);

return 0;
}

led is on.

jj2007

In my editor, I have disabled the NumLock key by handling the keydown message as follows (pseudocode):

  .if uMsg==WM_KEYDOWN && wParam==VK_NUMLOCK
      invoke GetKeyState, ebx
      test al, 1
      .if Zero?
         invoke keybd_event, ebx, 0, KEYEVENTF_KEYUP, 0     ; first, release the key
         invoke Sleep, 1
         invoke keybd_event, ebx, 0, 0, 0            ; second, trigger a second keypress to toggle
      .endif

The logic is as follows:
- numlock is being pressed by user
- we catch the keydown message
- we insert a keyup message for the same key
- then we insert a keydown message
- and Windows completes the whole cycle by handling the keyup message.

This cheats the message queue by inserting keyup and keydown:
keydown  ; windows
keyup  ; handler
keydown  ; handler
keyup  ; windows

Result: the key can't be activated.

frankie

#8
The problem is again the missing message loop, the static array returned by GetKeyboardState is updated during messages processing when a key event message is retreived!
Try using the asynchronus version of state as in the emended example below.
It works for your simple sample, but I've not tested it deeply.

void SetState(BYTE bVk, BYTE bScan, BOOL bState)
{
//BYTE keyState[256];

//GetKeyboardState((LPBYTE)&keyState);
SHORT State = GetAsyncKeyState(bVk);
//if ((bState && !(keyState[bVk] & 1)) || (!bState && (keyState[bVk] & 1)))
if ((bState && !(State & 1)) || (!bState && (State & 1)))
{
keybd_event(bVk, bScan, KEYEVENTF_EXTENDEDKEY | 0, 0);
keybd_event(bVk, bScan, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
}
}
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

aardvajk

Quote
I want to show a busy period by switching the three keyboard leds sequential on and off.
Use a progress bar and/or the hourglass cursor, it's what they're there for. They also don't interfere with doing other things (i.e. typing in other programs) while your program's busy.

Quote from: jj2007 on January 18, 2015, 03:10:42 PM
In my editor, I have disabled the NumLock key by handling the keydown message as follows (pseudocode):
Result: the key can't be activated.
Your editor would be better served if you implemented Page Down, Page Up, Home and End rather than just stopping me and I'm sure plenty of other laptop users for whom NumLock disables and/or changes the location of those keys, from being able to use them.

jj2007

Quote from: aardvajk on January 18, 2015, 04:59:46 PM
Quote from: jj2007 on January 18, 2015, 03:10:42 PM
In my editor, I have disabled the NumLock key by handling the keydown message as follows (pseudocode):
Result: the key can't be activated.
Your editor would be better served if you implemented Page Down, Page Up, Home and End rather than just stopping me and I'm sure plenty of other laptop users for whom NumLock disables and/or changes the location of those keys, from being able to use them.

My notebook does have Page Down, Page Up, Home and End right above the numpad. It's a major nuisance that some very frequently used keys, namely Backspace, Delete and Home, are placed in the direct neighbourhood of NumLock. You want to type "9" and find yourself one page down in the middle of nowhere, just because before you hit by accident that bloody NumLock key. Equally annoying are Insert and CapsLock - keys that are extremely rarely used but if hit by accident (a dozen times a day at least) will cause you to write nonsense. But of course, I could make that feature optional. Actually, thanks for your critique, I just realised that there is no numpad on the other notebook ;-)

czerny

Quote from: aardvajk on January 18, 2015, 04:59:46 PM
Use a progress bar and/or the hourglass cursor, it's what they're there for.
I have learned, that only going new -- maybe strange -- ways gives new knowledge.