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 }