how would i read keystrokes using the win32 api? i would also like to see them from international keyboards like german umlauts.
thanks
There's a difference between keyboard presses and the characters they generate.
At the lowest level, you can poll the keyboard state with GetKeyboardState. That's often how keylogging malware does it, since it requires the least privileges and sees everything regardless of where the focus is. The problem with this approach (besides requiring constant polling) is that you have to piece together the keyboard state into keystrokes and then keystrokes into a character stream. You have to know how the keyboard is mapped, you have keep state of shift keys, control keys, alt keys, etc. You have to know about auto-repeat, dead keys, and possibly other complications.
If you have privileges you can install a keyboard hook, as Jens mentioned in his answer.
If you have focus, and you're a console app, you use one of the functions to read from standard input. On Windows, it's hard to get true Unicode input. You generally get so-called ANSI characters, which correspond to the current code page for the console window. If you know the code page, you can use MultiByteToWideChar to convert the single- or multi-byte input into UTF-16 (which Windows documentation calls Unicode). From there you can convert it to UTF-8 (with WideCharToMultiByte) or whatever other Unicode encoding you want.
If you have focus, and you're a GUI app, you can see keystrokes with WM_KEYDOWN (and friends). You can can also get fully resolved UTF-16 characters with WM_CHAR (or UTF-32 from WM_UNICHAR). If you need UTF-8 from those, you'll have to do a conversion.
To get keyboard input regardless of focus, you'll probably need to hook the keyboard.
Take a look at SetWindowsHookEx with WH_KEYBOARD or WH_KEYBOARD_LL. Add a W to the call for the Unicode variant.
Related
Whenever I type some characters into the windows console and hit enter, it automatically scrolls to the next line. Is there any way to disable this behavior in C++ (using the Windows API), and if so; how?
If you call scanf or getline or similar then the underlying C runtime (CRT) handles Enter, Backspace, Delete, arrow keys, Tab, and such, and of course all printable keys.
If you want to handle Enter differently from CRT then you will have to handle every other key as well, using _getch (nonstandard function different from getchar). You will have to write some code. As far as I know there is no way to use scanf or getline, without Enter going to the next line.
I need to get scan codes of keyboard buttons (or any other codes) in layout-independent way. More specific, let's say I have QEditText and catching keystrokes from it. Now I'm starting to press a single button, and when the layout is English it has keycode=X, then I'm switching layout to Russian (German, French, whatever) and keycode becomes Y - but the physical button is the same. So I need to know code of that physical button, how to do this?
I am not sure if you will be able to do this only from code itself by some qt/x11 methods, but there is a tool that helps in similar situations: xbindkeys. You can read more here:
https://unix.stackexchange.com/questions/91355/shortcut-keys-that-are-independent-to-keyboard-layout
If you can't use xbindkeys, you can still check its code and see how the author achieved this.
I'm trying to write a Keyboard class that can read in the keyboard buttons. I have looked at this link - http://www.daniweb.com/software-development/cpp/code/216732/reading-scan-codes-from-the-keyboard But as stated on there, it is not very accurate for all computers (I don't know if this is even true). Therefore, my question is whats the best method in implementing my keyboard class? This will be used for Windows
Many thanks
There are three ways to read keyboard input:
By reading input from a console window as described in your link. It's true that it's hard to get this to work correctly, for starters because it's reading ANSI characters and not Unicode characters, but there are other issues. Console input/output is kind of obscure, as is the documentation for it
By handling UI events associated with a normal window. In this case you would handle the WM_KEYDOWN message in a window procedure
By going deep into the Win32 API with functions like SetWindowsHookEx. In this case you don't even need a window (normal or console), and you can read keystrokes pressed in any application or in the desktop
It's hard to suggest which one to use without knowing how you intend to use this Keyboard class.
On a windows pc, I have 2 USB keyboards attached.
When a key is pressed on either keyboard it is sent to Windows, And then windows sends notifies applications that a key has been pressed.
What I want is to capture input from one of these two keyboards BEFORE it is sent to other applications, and stop it, do whatever I want with it. The other keyboard has to work normally.
I managed to differentiate keyboard inputs after they are sent to applications via Raw Input, but how do I do this before they are sent to the applications?
What I want to do is have two keyboard, one keyboard that functions normally, and another keyboard that is exclusively used for hotkeys/custom macros.
Is this even possible in Windows? And if yes, how can I accomplish this?
I have a problem with unicode filenames appearing as question marks in my edit boxes.
When I paste unicode characters in an edit box, for example Arabic or Thai, they show correctly, but after I run this code, they become question marks. How come?
WCHAR buf[100];
GetWindowTextW(hWndEditBox, buf, 100);
SetWindowTextW(hWndEditBox, buf);
Another thing - the project is ANSI (we have code that can't be ported so the entire project stays ANSI), i.e. _UNICODE macro is undefined, but I explicitly use the Unicode versions of the filenames.
The GetWindowText function actually sends a WM_GETTEXT message to the window (hWndEditBox). Since you're using the *A functions rather than the *W function (specifically CreateWindowExA in this case, I think) your message loop will be converting from wide characters to multi-byte characters using some locale.
Your only solution here seems to be changing the entire window setup - if your code that requires ANSI is not related to UI this should be possible. Alternatively, you may be able to replace the edit box with rich edit boxes, that provide extra messages (such as streaming, for example).
You may want to check whether it is the GetWindowTextW call or the SetWindowTextW call that is doing the bad conversion - if GetWindowTextW works correctly you may be able to convert to multibyte using the correct locale before you set it.
Finally, you can try adjusting the thread's code page before reading the text, though this may cause all sorts of other issues. The usual advice is to use Unicode.
Sources: GetWindowText and this comment from Raymond Chen on his blog.
A useful answer to address SetWindowTextW()is given in https://stackoverflow.com/a/11515400/1190077 :
intercept the resulting WM_SETTEXT message and re-route it to DefWindowProcW() instead of DefWindowProc().