keytune

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

main.c (3622B)


      1 //  
      2 // Copyright (c) 2017 Konjahin A.A. <koniahin.ant@yandex.ru>
      3 // Licensed under the MIT License. See LICENSE file in the project root for full license information.  
      4 //
      5 
      6 #include <windows.h>
      7 #include "keyboard.h"
      8 
      9 
     10 typedef struct {
     11   char *title;
     12   WORD keyCode;
     13 } Key;
     14 
     15 typedef struct {
     16   int padding;
     17   int width;
     18   int height;
     19   int rows;
     20   int columns;
     21   HBRUSH background;
     22   Key *keys;
     23 } Layout;
     24 
     25 
     26 static Key* currentKeys = NULL;
     27 
     28 WORD getActionForKey(int keyHandler) {
     29   return currentKeys[keyHandler].keyCode;
     30 }
     31 
     32 
     33 LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
     34   switch(msg) {
     35 
     36   case WM_CLOSE:
     37     DestroyWindow(hwnd);
     38     break;
     39     
     40   case WM_DESTROY:
     41     PostQuitMessage(0);
     42     break;
     43     
     44   case WM_COMMAND:
     45     // processed only button's clicks
     46     if (HIWORD(wParam) != BN_CLICKED) {
     47       break;
     48     }
     49     
     50     INPUT input = {0};
     51     press(&input, getActionForKey(LOWORD(wParam)));
     52     break;
     53     
     54   case WM_NCHITTEST:
     55     // move window by user drag
     56     LRESULT hit = DefWindowProc(hwnd, msg, wParam, lParam);
     57     if (hit == HTCLIENT) hit = HTCAPTION;
     58     return hit;
     59     
     60   case WM_WINDOWPOSCHANGING:
     61     // forbid window maximization
     62     ((WINDOWPOS*) lParam)->flags |= SWP_NOSIZE;
     63     return 1;
     64     
     65   default:
     66     return DefWindowProc(hwnd, msg, wParam, lParam);
     67   }
     68   
     69   return 0;
     70 }
     71 
     72 
     73 HWND createMainWindow(Layout *layout, HINSTANCE hInstance, int nCmdShow) {
     74   const char className[] = "keyTuneWindowClass";
     75   WNDCLASSEX wc = {0};
     76 
     77   int width = (layout->width + layout->padding) * layout->columns + layout->padding;
     78   int height = (layout->height + layout->padding) * layout->rows + layout->padding;
     79   
     80   wc.cbSize        = sizeof(WNDCLASSEX);
     81   wc.lpfnWndProc   = WndProc;
     82   wc.hInstance     = hInstance;
     83   wc.hbrBackground = layout->background;
     84   wc.lpszClassName = className;
     85   wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
     86   
     87   RegisterClassEx(&wc);
     88   
     89   HWND hwnd = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_TOPMOST | WS_EX_NOACTIVATE | WS_THICKFRAME,
     90 			     className, "Keytune", WS_POPUP | WS_VISIBLE | WS_SYSMENU, CW_USEDEFAULT,
     91 			     CW_USEDEFAULT, width, height, NULL, NULL, hInstance, NULL);
     92   ShowWindow(hwnd, nCmdShow);
     93   UpdateWindow(hwnd);
     94 
     95   return hwnd;
     96 }
     97 
     98 
     99 HWND createButton(Layout *layout, HWND window, int x, int y) {
    100   int index = x + y * layout->columns;
    101   Key key = layout->keys[index];
    102 
    103   if (key.keyCode == NULL) {
    104     return NULL;
    105   }
    106   
    107   int positionX = layout->padding + (layout->padding + layout->width) * x;
    108   int positionY = layout->padding + (layout->padding + layout->height) * y;
    109   return CreateWindow("BUTTON", key.title, WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 
    110 		      positionX, positionY, layout->width, layout->height, window, (HMENU) index,
    111 		      (HINSTANCE)GetWindowLong(window, GWL_HINSTANCE), NULL);
    112 }
    113 
    114 
    115 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    116 
    117   Key keys[] = {
    118     {.title = "<", .keyCode = VK_LEFT},
    119     {.title = "Esc", .keyCode = VK_ESCAPE},
    120     {.title = ">", .keyCode = VK_RIGHT},
    121     {0}
    122   };
    123   
    124   Layout layout = {
    125     .padding = 10,
    126     .width = 60,
    127     .height = 40,
    128     .rows = 1,
    129     .columns = 4,
    130     .background = (HBRUSH) 0,
    131     .keys = keys
    132   };
    133 
    134   currentKeys = layout.keys;
    135 
    136   HWND hwnd = createMainWindow(&layout, hInstance, nCmdShow);
    137 
    138   for (int x = 0; x < layout.columns; x++) {
    139     for (int y = 0; y < layout.rows; y++) {
    140       createButton(&layout, hwnd, x, y);
    141     }
    142   }
    143 
    144   MSG Msg;
    145   while(GetMessage(&Msg, NULL, 0, 0) > 0) {
    146     TranslateMessage(&Msg);
    147     DispatchMessage(&Msg);
    148   }
    149   
    150   return Msg.wParam;
    151 }