C++ vkCode/ScanCode to country-specific and case-sensitive character - c++

I searched in a lot of different places and didn't find any conclusive answer, so I'm asking here.
I have to make a basic Windows keylogger as a school project.
I managed to set it up, and it works quite well. It logs characters and dead keys.
My problem is handling case-sensitive and country-specific input. I can get the SHIFT key state just fine to convert keys into their upper/lowercase equivalent, but I can't actually know what upper/lowercase equivalent it corresponds to.
Example : I'm using a French AZERTY keyboard. Numbers can be written via SHIFT + &, SHIFT + é, etc.
Here are the results my keylogger displays when trying to log numbers 1 to 5, first via SHIFT + Number and then by using CAPS LOCK.
If I switch to an English QWERTY keyboard, it will probably work fine, displaying the numbers (but then I'll not be able to access other characters like parentheses).
Is there any way to get a list of all possible keys for a given ScanCode/vkCode, depending on the type of keyboard ?
Here's a part of my code for the Callback function, and the translation of keys to strings.
It's the first time I use Windows' C++ API, so I don't really know much about it.

Related

(C++) Can the color of text change as it is typed?

I have a list of instructions in my program and they are activated by entering a string. There are a large number of possible instructions. You could call them commands if you like.
I already have a program that can successfully execute the instructions I've added so far.
For example, adding a person to the database would require the user to enter add "John" "Doe".
This would output to the screen Added John Doe to the database, ID#1234. The IDs are random.
I know how to add colors; in this output text, "John Doe" would be colored green.
What I'm wondering is, can I make it so that color changes as one types? Because I learned how to use some kind of keyboard mode change so that when I type a password, all characters are displayed as * of any color I desire, or even nothing displayed at all, through "display" of \0, and I know how to do that. I was wondering if the color could change before the complete string (extracted with std::getline(std::cin, str);) is typed.
The first reason I want the colors to change is because when there are so many commands, and I already have more complex commands than that, I want to provide a way for the user to be able to correct syntax mistakes before they press enter. Something like Windows PowerShell, perhaps, which was written in C#. I know that C# is a very different language than C++, but if C# can achieve something like that, I want to see if C++ can as well. My hope is that it doesn't require thousands of lines of application-specific code, especially considering that PowerShell is an actual application and not a simple terminal-run executable. And while PowerShell appears to be open-source, I don't understand C#. See the bottom for the second reason.
I have no idea if this is possible, but because similar manipulation of entered text is possible (as I said, I know how to add colors and also mask text as some other single character like *), I want to know if this is also possible.
Simple examples:
Firstly, the user should know when they have not entered a valid command, and when they have. I want the text to be in red until the letters entered so far consist of an actual keyword, like add. So, the text would be red until the second d is added, when it reverts to white, and if another letter is entered, it becomes red again.
Example 1: add "John Elias" "Doe"
After the space, the text after "add" should be red no matter what, unless the character after the space is a quotation mark. In order to tell the user that they have not terminated the string, the text beyond the (orange?) quotation mark should be orange. When the final quotation mark is entered, the entire content of the quotation marks (including the quotation marks) should be some other color (probably green?) to tell the user that they have successfully entered an argument. The same applies to any instances of quotation-mark arguments. Note that a space is allowed in a quotation argument.
Example 2: list-info 1234
In this command, it gets more complex. list is a separate command, so the text should be red until t is entered, and it turns white. But then it turns red again after that, until o is entered, and it turns white again. The numerical argument following it should be red if the entered character isn't a digit. If it is, it's still red, because the only valid IDs are 3- or 4-digit numbers. It should turn green(?) once a third digit is entered, and still stay green when another digit is entered. But if a fifth digit is entered (or another character for that matter), the number turns red again. Although this would better be implemented as returning an error if the entered number is invalid, I would still like to know if this can be done as well.
Example 3: add "John" "Elias" "Doe" "fourth-string"
Since there is an overloaded function that enables an explicit first-middle-last name to be stored as well, it should be ok if there is a third string. But if there is a fourth string added, then it should be in red no matter what because add cannot take more than 3 arguments.
My question is, are any of these things possible? And yes, I am aware that it is almost certainly better to just implement an error system, but my intention is to expand my coding ability, and that is the second reason, and coding an error system will not do that because I have already done that for every command.
For reference, I'm operating in Linux Ubuntu 18.04, I compile with g++, my code conforms to C++17, I use ANSI escape sequences for color, bold, etc., and for masking characters with something like * I use a pointer to a char array (passed by address as char**) and a C-style FILE* to reference the input stream stdin (because I haven't bothered to conform it to a typical C++ implementation yet, learning ways to advance my current skills is my priority at this point in time).

Using multi key sequenced inputs to result in a function

Straight to the point. I've been using visual studio to run a game I've been making. So far while coding in C++ I've been using inputs like VK_BACK or 0x52 for single key inputs. But I currently need to be able to type a word while the game is running to trigger a function. Basically, I'm asking how you would go about making the program recognize an inputted word. Like pressing the keys in a sequence to trigger a function.
Thanks, Jack
You've left a lot up to us to guess:
What are you using to read keyboard input?
I assume you're polling rather than streaming?
I'm also assuming non-blocking input?
With so many unknowns it's difficult to give a useful answer to the question. But here are a handful of options that may be helpful to you:
Require a terminating character for all keyboard input. This is characteristic of blocking input. The input is only read when the terminating character is placed.
Require the holding of a mode key while inputting a string. For example if I press an 'a' the key's command is executed immediately, but if I'm currently holding down the left Ctrl key and I press an 'a', it is treated as being within a string until the Ctrl key is released.
Use delimiters. If the '\'' is pressed it denoted the beginning of a string input consisting of all characters till the next '\'' key is pressed.
Make string entry keys separate from instantaneous input keys. This may be the most convenient solution because it allows instantaneous input in the middle of string input. But it may also be frustrating to the user if the allowable string commands are not clearly defined.

hyphen character and apostrophe character - the same ASCII code in different languages?

I need to specify a regex for validation of user input that allows the user to enter a hyphen character or apostrophe character on Windows Desktop operating systems or Mac OS/X desktop operating systems.
The user may have configured for the following languages:
English
French
Spanish
Portuguese
Hawaiian
I wan't to understand if I use a standard ASCII regex for hyphen and apostophe (e.g. ['-]) whether that will catch the hyphen or apostrophe keys typed by the user in most cases. I appreciate my definition is quite loose as there are many different keyboard layouts, OS versions, and language definitions (e.g. fr_FR, ca_FR).
I have checked the following resources and generally searched on google, but could not find anything in particular about saying that the ASCII code generated by a hyphen key or apostrophe key will always be ASCII code 45 and ASCII code 39 respectively.
http://en.wikipedia.org/wiki/Keyboard_layout
http://en.wikipedia.org/wiki/Hyphen
http://en.wikipedia.org/wiki/Apostrophe
NOTE: If you feel this question is badly worded, please add a comment to help me improve it.
You're mixing up a couple of things:
keyboard layout is what determines what value get assigned to a scancode.
localization settings determine in what language you should address the user, and wether the user expects a decimal point or comma.
character encoding is how a glyph is encoded into the bits memory and, in reverse, how to decode bits into glyphs
If you're validating user input, you shouldn't be interested in scancodes. A DVORAK layout user on a QWERTY keyboard will be pressing the Q key to input an '. And you shouldn't mess with that. So you have no business dealing with keyboard layouts.
The existence of this keyboard, should remind you, that what keys do is not your head-ache, but up to the user.
The localization settings will matter to you, but not for your regex. They will, however, tell you in what language you should put your error message, in case the user input is invalid. A good coding practice is to use a library like gettext to manage this.
What matters most, when you are validating input. Is just those 2 things: what is valid and what is the input.
You (or your domain expert) decide what is valid. Wether a hyphen-minus is just as acceptable as a hyphen or n-dash.
The input will be in encoded; computers work with bits, not strings of glyphs. It could be ASCII, but I'd steer towards unicode if I could help it.
As for your real concern, if I may rephrase it: "Can all users easily enter ' and -?". I guess they probably can. Many important programming languages use those glyphs to resp. denote strings and as a subtraction operator. And if your application needs to (dis)allow certain glyphs you can put unicode code points or categories in your regex.

Can all keys be represented as a single char in c++?

I've searched around and I can't seem to find a way to represent arrow keys or the escape key as single char in c++. Is this even possible? I would expect that it would be similar to \t or \n for tab and new line respectively. Whenever I search for escaped characters, there's only ever a list of five or six well known characters.
The short answer is no.
The long answer is that there are a number of control characters in the standard ANSI character set (from decimal 1 to decimal 31, inclusive), among which are the control codes for linefeed, carriage return, end-of-file, and so on. A few are commonly interpreted as arrows and the escape key, but only for compatibility with terminals.
Standard PC keyboards send a 2- or 3-byte control code that represents the key that was pressed, what state it's in, which control/alt/shift key is pressed, and a few other things. You'll want to look up "key codes" to see how to handle them. Handling them differs between operating systems and the base libraries you use, and their meaning differs based on the operating system's configured keyboard layout (which may include characters not found in the ANSI character set).
Not possible; keyboards built for some languages have characters that can't be represented in a char, and anyway, how do you represent control-option-command-shift-F11 in a char?
Keyboards send scancodes, which are either some kind of event in a GUI system or a short string of bytes that represent the key. What codes depends on your system, but on most terminal-like systems, ncurses knows how to deal with them.
char variables usually represent elements in the ASCII table.
http://www.asciitable.com/
there is also man ascii on unix. If you want arrow keys you'll need a more direct way to access keyboard input. the arrow keys get translated into sequences of characters before hitting stdio. If oyu want direct keyboard access consider a GUI library, sdl, direct input to name a few.
There aren't any escape characters for the arrow keys. They are represented as Keycodes, afaik. I suggest using a higher level input library to detect key presses. If you want to do it from scratch, the approach taken might vary with the specific platform you are programming for.
In any case, back in the days of TURBO C, I used -
//Wait for keypress
//store input in ch
//see if the ASCII code matches the code for one of the arrow keys

Restrict users to enter numbers valid only till 2 decimal places C/C++

I am making an currency change program where I would be providing exact change to the input amount, for example a value of 23 would be one 20 dollars and 3 one dollar bills
I want to restrict the user to input the value only till 2 decimal places. For example: the valid inputs are
20, 20.4, 23.44 but an invalid input would be 20.523 or 20.000.
How can I do this is C/C++.
I read about one function that is setprecision but that is not what I want, setprecision allows to display the value till that decimal point, it still doesn't stop the user from entering any value.
Is there any way to do this?
Read the amount from the user as a string, either character by character or the entire line, and then check its format, and then convert it.
It's generally easier to let the user type whatever they want followed by the program rejecting the input if it isn't valid rather than restricting what they can type on a keystroke basis.
For keystroke analysis you would need a state machine with 4 states, which we can call Number, Numberdot, Numberdotone, and Numberdottwo. Your code would have to make the proper transitions for all keystrokes, including the arrow keys to move the cursor to some arbitrary place and the Backspace key. That's a lot of work.
With input validation, all you have to do is check the input using a regular expression, e.g. ^(([0-9]+) | ([0-9]+.[0-9]) | ([0-9]+.[0-9][0-9])$. This assumes that "20." is not valid. Then if it's invalid you tell the user and make them do it again.
I do not believe that there is any way to set the library to do this for you. Because of that you're going to have to do the work yourself.
There are may ways you can do this, but the only true way to handle restricting the input is to control reading it in yourself.
In this case you would loop on keyboard input, for ever keystroke you would have to decided if it can be accepted in the context of the past input, then display it. That is, if there is a decimal point you would only accept to more numbers. This also allows you to limit input to numbers and decimal places as well, not to mention input length.
The down side is you will have to handle all the editing commands. Even bare bones you would need to support delete and enter.
This is rather a task for the GUI you are using, than for core C/C++. Depending on your GUI/Web Toolkit you can give more or less detailed rules how data can or can not be entered.
If you are writing a normal GUI application you can control and modify the entered keys (in C or C++).
In a WEB application you can do similar things using javascript.
The best solution would be when all illegal input is impossible.