Special key input not working (Enter, backspace, tab etc) - c++

My keypress code works for all keyboard letters but not for keys like Enter or Tab.
glfwSetCharCallback(window, character_callback);
void character_callback(GLFWwindow* window, unsigned int codepoint)
{
char c = codepoint;
printf("%c", c);
}
The function isn't even run when I press Tab or Enter but it does work for the Space bar, how would I go about receiving all key presses?

You should use glfwSetKeyCallback, not glfwSetCharCallback, since you're interested in keys instead of characters. See the Keyboard Input docs and the list of keyboard key macros.
I'm not sure though why Tab and Enter don't produce characters: they would normally produce respectively 0x09 and 0x0d in other toolkits (e.g. freeglut and Qt). But apparently, it's the way GLFW wants it to be, see their issue Backspace not reported to character callbacks:
elmindreda commented on Apr 12, 2017 •
Use the key callback for keys like Enter and Backspace. It provides press, repeat and release events.

Related

"type" emojis using C++ [duplicate]

This question already has an answer here:
Using SendInput to send unicode characters beyond U+FFFF
(1 answer)
Closed 7 years ago.
I don't really know what I should type in the title, but anyway, here is what I need :
I make small programs that do stuff like, "typing" the given input. Here is a small example to type "test" (as example).
#include <windows.h>
void Press(int Touch);
int main()
{
Sleep(5000);//Sleep a bit, so that you can select where to type
Press(VkKeyScan('t'));
Press(VkKeyScan('e'));
Press(VkKeyScan('s'));
Press(VkKeyScan('t'));
return 0;
}
void Press(int Touch)
{
keybd_event(Touch, 0x9d, 0, 0);
keybd_event(Touch, 0x9d, KEYEVENTF_KEYUP, 0);
}
So what I need is barely this, but with emojis. I need to be able to "type" any emoji like this one : "😂", from my program. Any ideas please ?
There's two ways you can approach this.
The first is using "alt codes":
Hold the ALT key
Press + on the number pad
Type the Unicode code point in hex
Release the ALT key
However, this method requires having EnableHexNumpad set in the Windows registry.
The second would be using the Windows clipboard.
Save the contents of the Windows clipboard
Set the clipboard contents to the Unicode character you wish to insert
Send CTRL + V to paste the character
Revert the clipboard to its previous content
keybd_event is deprecated, as mentioned on its MSDN page. Usually when you look up a Windows function and it is deprecated, you really should consider using the newer one.
Use SendInput, which among other things supports unicode keyboard input emulation.
You can send non-16-bit clean unicode characters by packing two different INPUT structures in a row.

Linux send unicode character to active application

Ok, so I'm trying to develop an app using C++ and Qt4 for Linux that will map certain key sequences to special Unicode characters. Also, I'm trying to make it bilingual, so the special Unicode character sent depends on the selected language. Example: AltGr+s will send ß or ș, depending whether German or Romanian is selected. On Windows, I have achieved this using AutoHotKey. However, I couldn't get IronAHK to work on Linux so I have written myself a nice Qt Application for it, using Qxt to register "global" shortcuts. I have tried this snippet:
void mainWnd::sendKeypress( unsigned int keycode )
{
Display *display = QX11Info::display();
Window curr_focus;
int revert_to;
XGetInputFocus( display, &curr_focus, &revert_to );
XTestFakeKeyEvent( display, keycode, true, 0 );
XTestFakeKeyEvent( display, keycode, false, 1 );
XFlush( display );
}
copied from another application(where it works), but here it seems to do nothing. Also, there might be a problem with the fact that the characters I'm trying to send aren't found on a US 101 Keyboard, that I currently use on my laptop(and as the layout in the OS).
So my question is: how do I make the app send a Unicode character to whichever app has focus, inserting a special character(sort of like KCharMap)? Remember, these are special characters which are not found on a normal US Keyboard. Thanks in advance.

Creating Alt Codes on a Laptop Without Them

My laptop has a number pad, but it does not have a NumLock key, and the numpad is actually just a copy of the row of numbers above the letters. This is confirmed by the virtual key codes sent when I press these keys.
I'm trying to develop a small program to mimic alt codes when the alt key and regular numbers are pressed. I use a low-level keyboard hook (I have a similar format working in another program), and first check to see if either alt key is down. If either is, I loop through the VK codes 0x30-0x39 (0-9 keys). If one of those is pressed down at that moment, I discard the actual keystroke by returning a value of 1, and instead send a numpad version of that key instead (alt is still pressed down at this time).
I can confirm that the hook is being reached, and that the alt key being down is being recognized successfully. However, when I check for matches on 0-9, either only a couple are printed before nothing matches after that, or I have to lift up and press down the alt key every time I press a number. Additionally, one number may be printed 16 times after releasing alt having pressed a number, and then holding down alt and pressing another (this one is 16x).
Also, I can confirm the SendInput sequence works via copying the part from the hook, putting it into the main function and replacing i with 0x30. Upon running, a 0 will be typed onto the text document.
When holding down ALT(down)+6+5+ALT(up) in a text document, "65" is what shows. If I add another ALT(down)+6, 16 sixes appear.
Hook Procedure:
LRESULT CALLBACK proc (int code, WPARAM wParam, LPARAM event) //hook proc
{
if (code < HC_ACTION) //don't process if not meant to
return CallNextHookEx (0, code, wParam, event);
if (GetAsyncKeyState (VK_MENU) & 0x8000) //if either alt is down
{
for (int i = 0x30; i <= 0x39; ++i) //loop 0-9
{
if (GetAsyncKeyState (i) & 0x8000) //if index is down
{
cout << "MATCH\n"; //debug
input.ki.wVk = i + 0x30; //set VK code to numpad version of index
input.ki.dwFlags = 0; //key is being pressed
SendInput (1, &input, sizeof (INPUT)); //send keystroke down
input.ki.dwFlags = KEYEVENTF_KEYUP; //key is being released
SendInput (1, &input, sizeof (INPUT)); //send keystroke up
while (GetAsyncKeyState (i) & 0x8000) //wait for normal key to be released
Sleep (10); //don't hog CPU
return 1; //discard normal key
} //end if match
} //end for
} //end if alt
return CallNextHookEx (0, code, wParam, event); //if any key not handled, pass on
} //end function
Well, I finally came back to this and after some more testing I discovered that programmatically sending [ALT ] [num6] [num5] [ALT ] does nothing whatsoever. I find this odd because I am able to simulate the volume control keys on the Mac keyboards despite not having those keys.
Since the computer simply can't send alt codes, I declare this helpful tool royally screwed unless I map thousands of characters.
EDIT:
Here's what you need to do to get the number pad working on the G74SX-XA1:
Download the BIOS 203 (I don't know if 202 works or not, I went from 201 to 203).
Put the file on a FAT32-formatted flash drive.
Restart the computer and either press F4 to go right into EasyFlash, or navigate to it through the BIOS. The Winflash program that comes with it doesn't work.
Select the updated BIOS file on the flash drive.
Now the numlock light will always be on and the number pad will have the virtual key codes of a number pad, not the numbers above the letters. This naturally includes ALT codes working.

Handling keyboard input in win32, WM_CHAR or WM_KEYDOWN/WM_KEYUP?

So in the text editor program that i've been working on, I've used WM_CHAR to process input from the keyboard. However, I found that some of the character mesages are not recorded. For example, if I use [shift]+ number key to type a symbol such as % or &, some re recorded while others such as [shift]+9 (which results in ')'), are not recorded. So, I'm wondering if I should use WM_KEYDOWN/WMKEYUP pair to handle keyboard input. I once wrote a keylogger in assembly(actually it was just a tutorial that i was trying out) and had used WM_KEYDOWN/WM_KEYUP pairs and that worked out quite good. So, should I move on to this, or is it something unusual that is happening with my program?
Thanks,
Devjeet
This is really a long reply to your comment above, but putting it in an answer because it's too long for a comment :)
The core issue to understand here is that keys and characters are not quite the same thing. Some (but not all) keys generate characters; some keys generate different characters depending on shift or other keyboard state. And to implement an editor, you need to handle both textual input and also non-textual keyboard input like arrow keys. Now the long-winded version, picking off from what seems to be an incorrect assumption:
Apparently, windows works in really strange ways. [...] It seems that when you press [shift]+9, windows sends a VK_LEFT in the wParam of message WM_CHAR
Sounds like you might be mixing two things up here. The thing with WM_CHAR is that it gives you character codes for textual characters: so if someone presses the 9 key, you'll get '9'. If someone presses SHIFT+9, Windows will take the shift state into account - and you get '(' (if using US keyboard). But you won't ever get a WM_CHAR for arrow keys, HOME, END, and so on, since they are not textual characters. WM_KEYDOWN, on the other hand, does not deal in characters, but in VK_ codes; so pressing 9 gives you VK_9 regardless of shift state; and left arrow gives you VK_LEFT - again regardles of shift state.
The things is that WM_CHAR and WM_KEYDOWN both give you two parts to the overall input picture - but you really have to handle both to get the full picture. And have to be aware that the wParam is a very different thing in both cases. It's a character code for WM_CHAR, but a VK_ code for WM_KEYDOWN. Don't mix the two.
And to make things more confusing, VK_ values share the same values as valid characters. Open up WinUser.h (it's in the include dir under the compiler installation dir), and look for VK_LEFT:
#define VK_LEFT 0x25
Turns out that 0x25 is also the code for the '%' character (see any ascii/unicode table for details). So if WM_CHAR gets 0x25, it means shift-5 was pressed (assuming US keyboard) to create a '%'; but if WM_KEYDOWN gets 0x25, it means left arrow (VK_LEFT) was pressed. And to add a bit more confusion, the Virtual Key codes for the A-Z keys and 0-9 keys happen to be the same as the 'A'-'Z' and '0'-'9' characters - which makes it seem like chars and VK_'s are interchangable. But they're not: the code for lower case 'a', 0x61, is VK_NUMPAD1! (So getting 0x61 in WM_CHAR does mean 'a', getting it in WM_KEYDOWN means NUMPAD1. And if a user does hit the 'A' key in unshifted state, what you actually get is first a VK_A (same value as 'A') in WM_KEYDOWN, which gets translated to WM_CHAR of 'a'.)
So tying all this together, the typical way to handle keyboard is to use all of the following:
Use WM_CHAR to handle textual input: actual text keys. wParam is the character that you want to append to your string, or do whatever else with. This does all the shift- processing for you.
Use WM_KEYDOWN to handle 'meta' keys - like arrow keys, home, end, page up, and so on. Pass all the A-Z/0-9 values through, the default handling will turn them into WM_CHARs that you can handle in your WM_CHAR handler. (You can also handle numpad keys here if you want to use them for special functionality; otherwise they 'fall through' to end up as numeric WM_CHARs, depending on numlock state. Windows takes care of this, just as it handles shift state for the alphabetic keys.)
If you want to handle ALT- combos explicitly (rather than using an accelerator table), you'll get those via WM_SYSKEYDOWN.
I think there are some keys that might show up in both - Enter might show up as both a WM_KEYDOWN of VK_RETURN and as either \r or \n WM_CHAR - but my preference would be to handle it in WM_KEYDOWN, to keep editing key handling separate from text keys.
Spy++ will show you the messages being sent to a window, so you can experiment and see what messages are appropriate for your application.
If you have Visual Studio installed, it should be in your Start menu, under Programs -> Microsoft Visual Studio -> Visual Studio Tools -> Spy++.
WM_CHAR
WM_KEYDOWN
The helpful message above inspired me to create this snippet, which gives you a human-readable indication of what key was pressed from any WM_KEYDOWN/WM_KEYUP/WM_SYSKEYDOWN/WM_SYSKEYUP independent of the state of the modifier keys.
// get the keyboard state
BYTE keyState[256];
GetKeyboardState(keyState);
// clear all of the modifier keys so ToUnicode will ignore them
keyState[VK_CONTROL] = keyState[VK_SHIFT] = keyState[VK_MENU] = 0;
keyState[VK_LCONTROL] = keyState[VK_LSHIFT] = keyState[VK_LMENU] = 0;
keyState[VK_RCONTROL] = keyState[VK_RSHIFT] = keyState[VK_RMENU] = 0;
// convert the WM_KEYDOWN/WM_KEYUP/WM_SYSKEYDOWN/WM_SYSKEYUP to characters
UINT scanCode = (inLParam >> 16) & 0xFF;
int i = ToUnicode(inWParam, scanCode, keyState, outBuf, inOutBufLenCharacters, 0);
outBuf[i] = 0;
By modifying the keyState array so that all the modifier keys are clear, ToUnicode will always output the unshifted key you pressed. (So, on the English keyboard you'll never get '%' but always '5') as long as it's a human readable key. You still have to do the VK_XXX checking to sense the arrow and other non-human readable keys however.
(I was trying to rig up a user editable "hot key" system in my app, and the distinction between WM_KEYXXX and WM_CHAR was making me nuts. The code above solved that problem.)

Getting input without a linebreak

I'm writing a program which will be doing manipulation of matrices. I want the user to be able to enter data into a matrix by typing it in one row at a time. So it will first ask for the value in row: 1, column: 1. The user will type in the appropriate value, and then press enter, after which he will type in the value for row: 1, column: 2.
This is the trick: I want the console to not enter a new line when the user presses enter. Instead, I want it to simply insert a tab character. Is this possible?
Thanks so much.
Yes, it's possible. You'll need to use a console/terminal library, though. Ncurses for *nix, wincon (part of the Windows API; you can just #include windows.h to use it)... There are a lot of choices out there.
The actual algorithm will simply be checking the characters that are sent as key events/using the getkey() equivalents of the various libraries, outputting the inputted characters to the console if the key pressed is not ENTER but would still cause a character to be echoed to the screen (i.e. function keys, caps lock, shift, etc. wouldn't cause any echoing to the console or terminal window) and then outputting \t if the key pressed is indeed ENTER.
Set the cursor position back up to the previous line. In Windows, you can use SetConsoleCursorPosition().
It's not exactly what you wanted, but you could get the same effect by using getline to obtain the row input all on one line, and then use std::stringstream to parse out the values.
std::string row;
getline(cin,row);
std::stringstream ss(row);
int j=0,i=currentrow; //put this in a loop over your rows
int input; //or float, double, whatever
while(ss >> input)
{
mat[i][j] = input;
j++;
}