GetKeyState doesn't register if holding ctrl - winapi

Given this statement:
if (GetKeyState(VK_CAPITAL) & 0x8000)
{
cout << "caps lock" << endl;
}
It works fine if I press caps lock alone, or along with any key except ctrl. I was thinking it's because ctrl is a modifier, but this works fine when holding shift. Is there something I'm missing?

GetKeyState() provides the synchronized state of the keyboard. The state of all the keys when the key was pressed. It can take a while before your program sees it, Windows provides type-ahead, so it is important that the state of all keys is known to reliably detect whether Shift, Alt, Ctrl were down at the time.
The synchronized state gets updated when you call GetMessage(). Done in the boilerplate message loop of a Windows program.
But since you use cout, you probably wrote a console mode program and don't use a message loop at all. So it doesn't update. And you'll have to use GetAsyncKeyState(). No buffering at all, so you have to call it often. Do note that the console also has a way to retrieve keystrokes with buffering supported. Probably what you really want/should do when you write code like this. Watch out for input redirection.

Related

GetAsyncKeyState from windows.h

I will use the following code to explain my question:
#include <Windows.h>
#include <iostream>
int main()
{
bool toggle = 0;
while (1)
{
if (GetAsyncKeyState('C') & 0x8000)
{
toggle = !toggle;
if (toggle) std::cout << "Pressed\n";
else std::cout << "Not pressed\n";
}
}
}
Testing, I see that
(GetAsyncKeyState('C') & 0x8000) // 0x8000 to see if the most significant bit is 1
has the same behavior as
(GetAsyncKeyState('C'))
However, to achieve the behavior I want, which is the way any text input out there works (it waits like 1 second, and if you are still pressing the button, it starts spamming in a certain rate), I need to write
(GetAsyncKeyState('C') & 1)
The documentation says
The behavior of the least significant bit of the return value is retained strictly for compatibility with 16-bit Windows applications (which are non-preemptive) and should not be relied upon.
Can someone clarify this please?
MSDN tells you why on the same page you linked to!
Although the least significant bit of the return value indicates whether the key has been pressed since the last query, due to the pre-emptive multitasking nature of Windows, another application can call GetAsyncKeyState and receive the "recently pressed" bit instead of your application. The behavior of the least significant bit of the return value is retained strictly for compatibility with 16-bit Windows applications (which are non-preemptive) and should not be relied upon.
GetAsyncKeyState gives you "the interrupt-level state associated with the hardware" and is probably shared by all processes in the window station/session.
The low bit might be connected to the keyboard key repeat delay you can set in Control Panel, but it does not really matter because MSDN tells you to not look at that bit.
GetAsyncKeyState is usually not the correct way to process keyboard input. Console applications should read stdin, or use the console API. GUI applications should use the WM_CHAR/WM_KEYDOWN/WM_KEYUP window messages.

Can both esc key and escape sequences be separtely detected on Unix systems?

I have a Linux distribution, and I'd like to be able to detects a wide range of keys, but I can't figure out how to distinguish the press of the Escape key, versus a key detected as keypress.
If I use this:
require 'io/console'
puts STDIN.raw { STDIN.getc }
and press, say, Arrow up, the interpreter will return immediately \e, then on subsequent getc calls, without pressing any key, it will return the remaining chars of the escape sequence ([ and A).
The problem is that, after the first getc call, I don't know if the user has actually pressed Esc, or another key which generates an escape sequence.
Is it possible to make the distinction between the two cases, without multiple getc invocations?
I don't think so, because the character input is done at a higher level than the physical keyboard. That is, by design, an ESC character read by getc is an ESC character, no matter how on the keyboard it was input (or not input on the keyboard at all, for example, by redirection).
I don't think Ruby out of the box has a way to detect hardware events such as keyboard presses. There is IOCTL for lower level device access, but I don't know how to use it for your purpose. But even if you could, how would you handle alternate keyboard layouts? What you expect to be an ESC key might be mapped to a different character.
There is a read_nonblock method on $stdin that you might use to see if there is an additional character in the buffer immediately after reading the ESC key. If so, it's likely that a special character other than ESC was pressed. If not, it's likely the ESC key was pressed.

getch() in TASM

So, i'm writing a program in Borland C with TASM in DOS. The program should switch s.c. "tasks" (or processes) until completion, and switching fuction should be operated via key click (getch), and this getch should be written in TASM, inserted in C++ . So, is there any getch() analog in TASM?
It depends on what environment that the program is supposed to be running in.
If it is intended to run in DOS, you can use interrupt 16h to retrieve pressed keys from the keyboard event handler. I have never used it myself, so I don't know more about it than that.
You can also install your program as the handler for hardware-interrupts from the keyboard. This is done using subfunction 25h (specified in AH register) of interrupt 21h. AL specifies the interrupt to install a handler for (keyboard interrupts is 9h), and DS:DX (segment:offset) specifies address to the handler.
As for Windows I am not as sure, but perhaps this will answer your question: https://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress%28v=vs.110%29.aspx

Swap alt keys functionality

I need to swap Alt keys functionality in Windows 7. A big company needs that for old people that were writing on typewriters, which had diacritic characters key on the left side, but Win7 which they are working on now has right Alt for this purpose.
Two days of research brought me to a driver solution. I need source code for original Windows 7 drivers (two .sys files seem to be the keyboard drivers), and possibily to modify them in Windows DDK. Or I need to make an additional driver that would work with the default ones. As I can see, the solution would be in C or C++. But what way do I have to go to accomplish this? What steps should I take?
The limits are:
One system restart only for driver installation.
A simple way to swap Alt keys while working in Win7 (swap Alt keys by pressing them both).
No Win7 keyboard remapping which needs a restart.
Added later: I have everything I need, but not the code that will handle the swapping. For example, I've made a switch for right Shift and Enter, because there is only one scancode sent. But left Alt sends one and right Alt sends two scancodes:
VOID
KbFilter_ServiceCallback(
IN PDEVICE_OBJECT DeviceObject,
IN PKEYBOARD_INPUT_DATA InputDataStart,
IN PKEYBOARD_INPUT_DATA InputDataEnd,
IN OUT PULONG InputDataConsumed
)
/*++
Routine Description:
Called when there are keyboard packets to report to the Win32 subsystem.
You can do anything you like to the packets. For instance:
o Drop a packet altogether
o Mutate the contents of a packet
o Insert packets into the stream
Arguments:
DeviceObject - Context passed during the connect IOCTL
InputDataStart - First packet to be reported
InputDataEnd - One past the last packet to be reported. Total number of
packets is equal to InputDataEnd - InputDataStart
InputDataConsumed - Set to the total number of packets consumed by the RIT
(via the function pointer we replaced in the connect
IOCTL)
Return Value:
Status is returned.
--*/
{
PDEVICE_EXTENSION devExt;
WDFDEVICE hDevice;
hDevice = WdfWdmDeviceGetWdfDeviceHandle(DeviceObject);
devExt = FilterGetData(hDevice);
if (InputDataStart->MakeCode==0x1c)
InputDataStart->MakeCode=0x36;
else if (InputDataStart->MakeCode==0x36)
InputDataStart->MakeCode=0x1c;
else if (InputDataStart->MakeCode==0x9c)
InputDataStart->MakeCode=0xb6;
else if (InputDataStart->MakeCode==0xb6)
InputDataStart->MakeCode=0x9c;
(*(PSERVICE_CALLBACK_ROUTINE)(ULONG_PTR) devExt->UpperConnectData.ClassService)(
devExt->UpperConnectData.ClassDeviceObject,
InputDataStart,
InputDataEnd,
InputDataConsumed);
}
So I simply swap the scancodes of pressing and releasing both keys individually. Right Alt is sending two scancodes and I'm not sure if it does that by two calls of this function or makes two scancodes in the InputDataStart structure. I'll try to beep every Alt scancode but your help would be appreciated.
Solution:
if (InputDataStart->MakeCode==0x38 || InputDataStart->MakeCode==0xb8)
InputDataStart->Flags^=KEY_E0;
which swaps right-left Alt keys functionality.
Now I need to make the swapping configurable. For the best - by pressing both Alts.

How does echo actually work in Unix

When I type any key, normally, it is immediately echoed back to the std output i.e.my screen.
If I have to enter a password, that says that it will not echo back, I cannot see the keys that I type.
How does this work.
Does each key press go to the kernel immediately(without me pressing ENTER), and then the kernel decides to echo them or not?
Like , I press 'A', it goes to the kernel; kernel echoes it; I get it on my screen. Now I hit 'B'...same sequence again...; Now I have 'AB' on my screen (my command) and hit ENTER; My command goes to the kernel and is finally executed.
Is there any other explanation? What happens in the background during the key presses?
The terminal driver in the kernel can be put in several modes (there are actually many more flags than this, and these days "cbreak" is actually the opposite of a different flag, so this is simplified).
The "cbreak" mode means that the process that is attempting to read from the terminal will receive keyboard input as soon as it is available. When cbreak mode is off, the data is stored by the kernel in a buffer until enter is pressed, and certain keys like backspace are handled by the kernel (when you press backspace, it removes the character from the buffer and - if echo mode is on - writes "backspace-space-backspace" to the terminal to overwrite the character with a blank space).
Echo mode means that whenever the user presses a key, the kernel will immediately echo it back to the screen. When it is off, nothing will be echoed to the screen, and the program will need to write it to the terminal if it wants you to see it.
There are several typical situations:
In programs that do advanced input handling (like most shells, or something like a full screen program), cbreak is on and echo is off; the program will write the character to the terminal itself if it is not part of a special key escape sequence.
In most situations [the default with a simple program that reads stdin and writes stdout], echo is on and cbreak is off. When you type, it behaves as I described above, all of this is handled by the kernel until you hit enter and it sends it to the application. Input editing is limited to backspace [and ctrl-u, ctrl-w], trying to use the arrow keys will just put escape sequences like ^[[D in the input line.
When reading a password, echo is off and cbreak is off. Input works just like the default case, except the kernel does not copy input to the screen.
The program that is running tells the kernel what mode to have it in with the termios functions. You can use the stty command to do the same in a shell environment, but be aware that this may interfere with the shell's own input handling or with what programs you run expect the default state to be.
Your keyboard generates electrical signals that are eventually interpreted as keycodes that correspond to letters - 'A', 'B', function keys F1, F2 etc. This all happen in the keyboard driver that is handled by the kernel. That keyboard driver has a buffer to receive all the keypresses from the keyboard and sends that to the kernel that in turn direct them to processes that is currently having the focus. What to do with the sequence of keys are totally decided by the individual application, such as whether to display the keys or not.
echo program is part of coreutils. You can download its sources here. Look at src/echo.c it's quite small. You can see that echo uses fputc or putchar calls. Those calls deal with standard stream called stdout. The architecture of standard streams is quite complicated and it's beyond of this post. You can found it using for example google.

Resources