NO

Author Topic: Reset NumLock etc.  (Read 7257 times)

czerny

  • Guest
Reset NumLock etc.
« on: January 16, 2015, 04:23:02 PM »
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?

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Reset NumLock etc.
« Reply #1 on: January 16, 2015, 07:23:27 PM »
Code: [Select]
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

  • Guest
Re: Reset NumLock etc.
« Reply #2 on: January 17, 2015, 01:10:34 AM »
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.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Reset NumLock etc.
« Reply #3 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.
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

  • Guest
Re: Reset NumLock etc.
« Reply #4 on: January 17, 2015, 09:32:08 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?

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Reset NumLock etc.
« Reply #5 on: January 17, 2015, 10:43:47 PM »
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:
Quote
An 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).
« Last Edit: January 17, 2015, 10:50:01 PM by frankie »
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

czerny

  • Guest
Re: Reset NumLock etc.
« Reply #6 on: January 18, 2015, 02:49:17 PM »
There is something wrong with SetState himself:
Code: [Select]
#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.

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: Reset NumLock etc.
« Reply #7 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):

  .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.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Reset NumLock etc.
« Reply #8 on: January 18, 2015, 04:04:15 PM »
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.
Code: [Select]
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);
}
}
« Last Edit: January 18, 2015, 04:08:59 PM by frankie »
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

aardvajk

  • Guest
Re: Reset NumLock etc.
« Reply #9 on: January 18, 2015, 04:59:46 PM »
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.

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.

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: Reset NumLock etc.
« Reply #10 on: January 18, 2015, 05:10:30 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

  • Guest
Re: Reset NumLock etc.
« Reply #11 on: January 18, 2015, 09:13:14 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.