I found an old VT100 Terminal editor written in C++ that I wanted to convert into a Windows Terminal console application, since the new windows terminal supports VT100 escape codes.
One of the questions I had while porting the Application to C++ under windows was:
How do I detect key sequences such as "Shift+Arrow Key" and "Shift+Ctrl+Arrow Key". When I try to use getch() it doesn't seem to detect the shift key in combination with arrow keys.
Here's How I'm currently detecting key presses in my Console Application:
#define KEY_BACKSPACE 0x101
#define KEY_ESC 0x102
#define KEY_INS 0x103
#define KEY_DEL 0x104
#define KEY_LEFT 0x105
#define KEY_RIGHT 0x106
#define KEY_UP 0x107
#define KEY_DOWN 0x108
#define KEY_HOME 0x109
#define KEY_END 0x10A
#define KEY_ENTER 0x10B
#define KEY_TAB 0x10C
#define KEY_PGUP 0x10D
#define KEY_PGDN 0x10E
#define KEY_CTRL_LEFT 0x10F
#define KEY_CTRL_RIGHT 0x110
#define KEY_CTRL_UP 0x111
#define KEY_CTRL_DOWN 0x112
#define KEY_CTRL_HOME 0x113
#define KEY_CTRL_END 0x114
#define KEY_CTRL_TAB 0x115
#define KEY_SHIFT_LEFT 0x116
#define KEY_SHIFT_RIGHT 0x117
#define KEY_SHIFT_UP 0x118
#define KEY_SHIFT_DOWN 0x119
#define KEY_SHIFT_PGUP 0x11A
#define KEY_SHIFT_PGDN 0x11B
#define KEY_SHIFT_HOME 0x11C
#define KEY_SHIFT_END 0x11D
#define KEY_SHIFT_TAB 0x11E
#define KEY_SHIFT_CTRL_LEFT 0x11F
#define KEY_SHIFT_CTRL_RIGHT 0x120
#define KEY_SHIFT_CTRL_UP 0x121
#define KEY_SHIFT_CTRL_DOWN 0x122
#define KEY_SHIFT_CTRL_HOME 0x123
#define KEY_SHIFT_CTRL_END 0x124
#define KEY_F1 0x125
#define KEY_F3 0x126
#define KEY_F5 0x127
#define KEY_ALT_LEFT 0x128
#define KEY_ALT_RIGHT 0x129
#define KEY_ALT_UP 0x130
#define KEY_ALT_DOWN 0x131
#define KEY_ALT_HOME 0x132
#define KEY_ALT_END 0x133
#define KEY_ALT_TAB 0x134
#define KEY_ALT_PGUP 0x135
#define KEY_ALT_PGDN 0x136
#define KEY_UNKNOWN 0xFFF
#if defined(WIN32) || defined(_WIN64)
#include "windows.h"
#include "conio.h"
#endif
int getkey_win32() {
int c1;
int c2;
c1 = (int)getch();
// unmapable How to detect Shift + Arrow Key??
//#define KEY_SHIFT_LEFT 0x116
//#define KEY_SHIFT_RIGHT 0x117
//#define KEY_SHIFT_UP 0x118
//#define KEY_SHIFT_DOWN 0x119
//#define KEY_SHIFT_PGUP 0x11A
//#define KEY_SHIFT_PGDN 0x11B
//#define KEY_SHIFT_HOME 0x11C
//#define KEY_SHIFT_END 0x11D
//#define KEY_SHIFT_CTRL_LEFT 0x11F
//#define KEY_SHIFT_CTRL_RIGHT 0x120
//#define KEY_SHIFT_CTRL_UP 0x121
//#define KEY_SHIFT_CTRL_DOWN 0x122
//#define KEY_SHIFT_CTRL_HOME 0x123
//#define KEY_SHIFT_CTRL_END 0x124
if (c1 == 0) {
c2 = (int)getch();
switch(c2) {
case 0x9b: return KEY_ALT_LEFT;
case 0x9d: return KEY_ALT_RIGHT;
case 0x98: return KEY_ALT_UP;
case 0xa0: return KEY_ALT_DOWN;
case 0x99: return KEY_ALT_PGUP;
case 0xa1: return KEY_ALT_PGDN;
case 0x97: return KEY_ALT_HOME;
case 0x9F: return KEY_ALT_END;
case 0x3b: return KEY_F1;
case 0x3d: return KEY_F3;
case 0x3f: return KEY_F5;
default: return KEY_UNKNOWN;
}
}
else if (c1 == 0xe0) {
c2 = (int)getch();
switch(c2) {
case 0x73: return KEY_CTRL_LEFT;
case 0x74: return KEY_CTRL_RIGHT;
case 0x8d: return KEY_CTRL_UP;
case 0x91: return KEY_CTRL_DOWN;
case 0x77: return KEY_CTRL_HOME;
case 0x75: return KEY_CTRL_END;
case 0x52: return KEY_INS;
case 0x53: return KEY_DEL;
case 0x4b: return KEY_LEFT;
case 0x4d: return KEY_RIGHT;
case 0x48: return KEY_UP;
case 0x50: return KEY_DOWN;
case 0x47: return KEY_HOME;
case 0x4f: return KEY_END;
case 0x49: return KEY_PGUP;
case 0x51: return KEY_PGDN;
default: return KEY_UNKNOWN;
}
}
else {
switch(c1) {
case 0x08: return KEY_BACKSPACE;
case 0x1b: return KEY_ESC;
case 0x0d: return KEY_ENTER;
case 0x09: return KEY_TAB;
default: return c1;
}
}
}