Basically, when one types, a keydown event happens. If the key is held for more than a certain time (~1 sec) then the key is repeatedly pressed until keyup hapens. I would like to change the time it takes for the key to be automatically repressed in my c++ application. How can this be done?
Thanks
The speed at which a keypress becomes automatically recurring is controlled by Windows.
If you want to manipulate automatic recurrences of key-presses, it might be more advantageous to poll for the state of the key rather than waiting for the keydown event. It depends on how responsive you need your application to be.
This article may help you in figuring out how to query for key states: link
You can use the SystemParametersInfo function to change the keyboard delay and refresh rate, as described in this newsgroup thread.
A simple way to handle this is to establish a buffer of time around the OnKeyDown event. Setup a timer that determines whether control passes to a secondary event handler. If the timer has expired, then it is OK to pass control. If the timer hasn't expired, then you should return and leave the event unhandled. Start the timer right before passing control to your secondary event handler.
void KeyDownHandler(...)
{
// ...
if (TimeLeft() <= 0)
{
StartTimer();
handleKeyDown();
}
}
A timer is better than counting duplicate events because you can't assume that a given system will have the same repeat rate set as yours.
I agree with Stuart that polling for the state of the key might work better. It depends upon what you are trying to accomplish.
Also note that this type of behavior might be highly annoying to your user - why do you need to ignore duplicates?
You might be able to tap into a Windows API but this might be controlled by the OS. Not sure...
You might need to manually draw a command such as to simulate a key press multiple times after a set number of seconds after the key has been pressed.
Use SetKeySpeed api (Kernel)
Related
I bought a really nice keyboard (logitech G915) that for whatever inane reason doesn't have a numlock indicator. Thus, I'm using Logitech's lighting SDK to make the functionality myself using the key's rgb backlight.
I have an extremely simple console proof of concept that works:
while (true)
{
if (GetKeyState(VK_NUMLOCK) & 0x1)
LogiLedSetLightingForKeyWithKeyName(LogiLed::KeyName::NUM_LOCK, 0, 100, 100);
else
LogiLedSetLightingForKeyWithKeyName(LogiLed::KeyName::NUM_LOCK, 0, 0, 0);
}
But I don't think it's good to eat up cpu cycles with a perpetual while loop for such a tiny feature. Should I just have it sleep for time (length suggested?) or is there a way to sleep until the system gets a numlock state change or am I simply going about this wrong?
Additionally, I haven't looked into it yet, but I want to make this a background process or a tray application (doesn't matter, just hidden away) so I guess answers should have that limitation in mind if it is one.
Thanks!
At app startup, use GetAsyncKeyState() instead of GetKeyState() to get the key's current state and update the light accordingly.
Then, use SetWindowsHookEx() to install a global WH_KEYBOARD_LL hook to detect whenever the key is pressed afterwards. On each callback event, use the state information provided by the hook, or start an asynchronous task to get the current key state immediately after your hook callback exits (as GetAsyncKeyState() has not been updated yet when the callback is called), and then update the light accordingly.
Alternatively, use the Raw Input API to monitor the keyboard and receive WM_INPUT window messages on each key press. And then get the key's current state and update the light accordingly.
The scenario is the following:
When my active Widget is a QSpinBox, I can change the value by clicking or holding a click on an arrow of the box or by pressing or holding Page Up/Page Down/ ▲ / ▼ .
The problem is, that i have some hardware communications on valueChanged() which needs some milliseconds.
While i permascroll (mouse) or hold the click on a boxes arrow, this isn't a problem, because the scroll seems to be slower here (acceleration off), but when i use my keyboard (acceleration also off), the scrollspeed is much faster which causes the timing problem. The application slows down, then freezes for some seconds until the event queue is finished.
I need to allow using the keyboard input (including holding the keyboard key), so I'd like to know if there is a way to slow down key repeat rate of arrow/page up/down.
Actually I'm triggering a 200 msec oneshot timer on value changed, which passes the spinbox value on timeout. The timer will only be triggered if it's not running. That means when i change the value it will always have a 200 msec delay and the update frequency can only be 5 updates/sec or slower. It actually works, but I'd really like to improve this by reducing the key repeat rate somehow.
Ok no I see problem. Here problem is keyboard repaying character on button hold.
To overcome this without direct interaction with keyboard, I would try use event filter, observe key press events and reject some of them if then are arriving to fast.
Your device communication subsystem has two states: busy and available. When it's busy, you should schedule an update of a particular variable in your target, but don't execute it just yet. When the previous communications are done, and the subsystem is available, it should pick up any outstanding changes and propagate them.
I need to determine if the user is idle in this particular way.
For complicated reasons i cant use functions like GetCursorPos or any mouse related thing. Also i cant use LowLevelKeyboardProc with all the hooking and the GetMessage / TranslateMessage / DispachMessage loop running in the main function. These two options are off my choices, not for my decision.
GetLastInputInfo seemed perfect, but it cant filter only keyboard events, by default it detects both mouse and keyboard events.
Is there a simliar funcion that i can use for detecting only keyboard events?
i dont need and i dont want to know which keys are pressed, all i need to know is if the user pressed any of the keys. I will then loop and check that every half second until it returns false, then its done.
A better way would be to have in return the last time a keyboard event occurred. like GetLastInputInfo does. :(
This is hard to explain, and those are not excuses, i must avoid using hooks, and just detect if a keyboard event occurred.
Thanks for any help.
Is there a way to notice the release of a hot-key button registered with RegisterHotKey?
I get a WM_HOTKEY message every time I press the hot-key but I need to know when the key was released
There is no specific notification for that specific action. You will have to write a DLL that implements a global keyboard hook via SetWindowsHookEx(), then you will receive individual keypress up/down notifications and can match them up to your WM_HOTKEY notifications as needed.
Use RegisterHotkey to detect the key going down, then use polling with GetAsyncKeyState until the key is no longer down. This avoids the complexity of SetWindowsHookEx and the polling is generally acceptable since it is only done while the hotkey is being held down.
I have a transparent window (WS_EX_TRANSPARENT) floating topmost.
Whenever there is a mouse move (anywhere on the screen) or keyboard stroke, it needs to display the related info (e.g. mouse position).
Is it possible to capture mouse/keyboard activities without using a global hook? Anti-virus software almost always triggers false alarms for the use of global
hooks.
Any idea greatly appreciated.
I guess, GetAsyncKeyState and GetCursorPos might help. You probably can have a thread calling these functions every 300-500 msec, and posting a message to your main thread.
You could register for receiving raw input messages via RegisterRawInputDevices. Have a look over here, there are some links in the accepted answer of RRUZ, one points to a C# implementation. This works with window messages, no hooks involved.
(With this method you also get information about the specific device the input came from, so you could distinguish between multiple keyboards. That's where most questions having "use RegisterRawInputDevices" as answer are heading. But you can also use it to just capture the input, not caring about the source.)
You can get notified of keyboard/mouse activity (GetLastInputInfo), and I am fairly certain you can get the cursor position (GetMouseMovePointsEx). If you do not need the actual keyboard strokes, then that should do it. If you do, I do not think it can be done...
LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
UInt32 lastInputTick = lastInputInfo.dwTime;
return Environment.TickCount - (Int32)lastInputInfo.dwTime
This code (C#) return the inactivity time (keyboard and mouse both). So you can have the time since the user is inactive.