keytune

Simple virtual like keyboard for Windows
git clone git://git.konyahin.xyz/keytune
Log | Files | Refs | README | LICENSE

commit 4927fea93fc99cb3eba1bca3a5cd931a8e0a83a7
Author: Konjahin Anton <koniahin.ant@yandex.ru>
Date:   Sat, 17 Jun 2017 21:43:11 +0300

Initial commit

Diffstat:
ALICENSE | 22++++++++++++++++++++++
AMakefile | 12++++++++++++
AREADME.md | 14++++++++++++++
Akeyboard.c | 43+++++++++++++++++++++++++++++++++++++++++++
Akeyboard.h | 42++++++++++++++++++++++++++++++++++++++++++
Amain.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 227 insertions(+), 0 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Konjahin A.A. <koniahin.ant@yandex.ru> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +\ No newline at end of file diff --git a/Makefile b/Makefile @@ -0,0 +1,11 @@ +SOURCES = \ + main.c \ + keyboard.c + +TARGET = keytune.exe + +$(TARGET): $(SOURCES) + cl $(SOURCES) /link user32.lib Gdi32.lib /out:$(TARGET) + +clear: + del *.obj $(TARGET) +\ No newline at end of file diff --git a/README.md b/README.md @@ -0,0 +1,13 @@ +### Keytune + +Keytune - virtual-keyboard like application for Windows written in C. + +Use nmake for build. + +Licensed under the MIT License. + +TODO +- [ ] Tune keyboard layout with config file +- [ ] Support for multiply layouts +- [ ] Graphical tuning for layouts +- [ ] Can be used as system virtual keyboard +\ No newline at end of file diff --git a/keyboard.c b/keyboard.c @@ -0,0 +1,42 @@ +// +// Copyright (c) 2017 Konjahin A.A. <koniahin.ant@yandex.ru> +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +#include "keyboard.h" + +void setUpInput(INPUT *ip) { + ip->type = INPUT_KEYBOARD; + ip->ki.wScan = 0; + ip->ki.time = 0; + ip->ki.dwExtraInfo = 0; +} + +void hold(INPUT *ip, WORD keyCode) { + setUpInput(ip); + ip->ki.wVk = keyCode; + ip->ki.dwFlags = 0; + SendInput(1, ip, sizeof(INPUT)); +} + +void release(INPUT *ip, WORD keyCode) { + setUpInput(ip); + ip->ki.wVk = keyCode; + ip->ki.dwFlags = KEYEVENTF_KEYUP; + SendInput(1, ip, sizeof(INPUT)); +} + +void press(INPUT *ip, WORD keyCode) { + hold(ip, keyCode); + release(ip, keyCode); +} + +void getCharForKey(WORD keyCode, wchar_t* buffer, size_t bufferLength) { + HKL keyboardLayout = GetKeyboardLayout(0); + UINT scanCode = MapVirtualKeyEx(keyCode, MAPVK_VK_TO_VSC, keyboardLayout); + + BYTE keyState[256] = {0}; + GetKeyboardState(keyState); + + ToUnicodeEx(keyCode, scanCode, keyState, buffer, bufferLength, 0, keyboardLayout); +} +\ No newline at end of file diff --git a/keyboard.h b/keyboard.h @@ -0,0 +1,41 @@ +// +// Copyright (c) 2017 Konjahin A.A. <koniahin.ant@yandex.ru> +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +#include <windows.h> +#include <winuser.h> + +/** + * Send press event for key with virtual-key codes + * Arguments: + * ip - INPUT structure from winuser.h + * keyCode - WORD with virtual key-code from https://msdn.microsoft.com/en-us/library/dd375731(v=vs.85).aspx +*/ +void hold(INPUT *ip, WORD keyCode); + +/** + * Send release event for key with virtual-key codes + * Arguments: + * ip - INPUT structure from winuser.h + * keyCode - WORD with virtual key-code from https://msdn.microsoft.com/en-us/library/dd375731(v=vs.85).aspx +*/ +void release(INPUT *ip, WORD keyCode); + +/** + * Send press and release event for key with virtual-key codes + * Arguments: + * ip - INPUT structure from winuser.h + * keyCode - WORD with virtual key-code from https://msdn.microsoft.com/en-us/library/dd375731(v=vs.85).aspx +*/ +void press(INPUT *ip, WORD keyCode); + +/** + * Put in buffer with wide chars text representation of keyboard's key + * with virtual-key codes in current keyboard layout. + * Arguments: + * keyCode - WORD with virtual key-code from https://msdn.microsoft.com/en-us/library/dd375731(v=vs.85).aspx + * buffer - wxhar_t* wide chars buffer for output + * bufferLength size_t size of buffer +*/ +void getCharForKey(WORD keyCode, wchar_t* buffer, size_t bufferLength); +\ No newline at end of file diff --git a/main.c b/main.c @@ -0,0 +1,93 @@ +// +// Copyright (c) 2017 Konjahin A.A. <koniahin.ant@yandex.ru> +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +#include <windows.h> +#include "keyboard.h" + + +#define BUTTON_LEFT 1 +#define BUTTON_RIGHT 2 +#define BUTTON_ESCAPE 3 + + +LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + switch(msg) { + case WM_CREATE: + HWND hwndButton = CreateWindow("BUTTON", "<", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, + 10, 10, 40, 40, hwnd, (HMENU) BUTTON_LEFT, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL); + hwndButton = CreateWindow("BUTTON", "Esc", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, + 60, 10, 40, 40, hwnd, (HMENU) BUTTON_ESCAPE, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL); + hwndButton = CreateWindow("BUTTON", ">", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, + 110, 10, 40, 40, hwnd, (HMENU) BUTTON_RIGHT, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL); + break; + + case WM_CLOSE: + DestroyWindow(hwnd); + break; + + case WM_DESTROY: + PostQuitMessage(0); + break; + + case WM_COMMAND: + // processed only button's clicks + if (HIWORD(wParam) != BN_CLICKED) { + break; + } + + INPUT input; + switch(LOWORD(wParam)) { + case BUTTON_LEFT: + press(&input, VK_LEFT); + break; + case BUTTON_RIGHT: + press(&input, VK_RIGHT); + break; + case BUTTON_ESCAPE: + press(&input, VK_ESCAPE); + break; + } + break; + + // move window by user drag + case WM_NCHITTEST: + LRESULT hit = DefWindowProc(hwnd, msg, wParam, lParam); + if (hit == HTCLIENT) hit = HTCAPTION; + return hit; + + default: + return DefWindowProc(hwnd, msg, wParam, lParam); + } + return 0; +} + + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { + const char className[] = "keyTuneWindowClass"; + WNDCLASSEX wc = {0}; + + wc.cbSize = sizeof(WNDCLASSEX); + wc.lpfnWndProc = WndProc; + wc.hInstance = hInstance; + wc.hbrBackground = 0; + wc.lpszClassName = className; + wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); + + RegisterClassEx(&wc); + + HWND hwnd = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_TOPMOST | WS_EX_NOACTIVATE, className, + "Keytune", WS_POPUP | WS_VISIBLE | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 160, + 60, NULL, NULL, hInstance, NULL); + ShowWindow(hwnd, nCmdShow); + UpdateWindow(hwnd); + + MSG Msg; + while(GetMessage(&Msg, NULL, 0, 0) > 0) { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } + + return Msg.wParam; +} +\ No newline at end of file