Skip to content

013 Ввод

badcoiq edited this page Jul 8, 2023 · 1 revision

Ввод

Для ввода надо иметь информацию о состоянии мыши и клавиатуры. Нужно сунуть всё это в структуру. Данная структура так-же будет использоваться в GUI.

Добавлю файл inc/badcoiq/[b]input[/b]/bqInput.h

Структура

struct bqInputData
{
	// Позиция курсора
	bqPointf m_mousePosition;

	// старая позиция курсора. для вычисления m_mouseMoveDelta
	bqPointf m_mousePositionOld;

	// На сколько переместился курсор
	bqPointf m_mouseMoveDelta;

	// На сколько покрутили колесо мыши
	float   m_mouseWheelDelta = 0.f;

	// Флаги для мышки
	uint32_t m_mouseButtonFlags = 0;

	// При вводе символа он сохраняется сюда
	char32_t m_character = 0;

	// состояния для кнопок клаиатуры
	uint64_t m_keyFlagsHit[2] = { 0,0 };
	uint64_t m_keyFlagsHold[2] = { 0,0 };
	uint64_t m_keyFlagsRelease[2] = { 0,0 };

	// Модификаторы клавиатуры (моя терминология)
	uint8_t m_keyboardModifier = 0;
};

Состояния хранятся в виде флагов. Я бы добавил все эти флаги сюда, но, возникла идея для оптимизации. Для клавиатуры я использую всего несколько uint64_t. Каждый кадр необходимо занулять Hit и Release. Проще сделать что-то типа

m_keyFlagsHit[0] = 0;
m_keyFlagsHit[1] = 0;
m_keyFlagsRelease[0] = 0;
m_keyFlagsRelease[1] = 0;

Все используемые кнопки влезают в 128 бит.

Надо начать объяснение с простого. У каждой клавиши есть свой код.

// keyboard button code
	enum : uint32_t {
		KEY_NONE = 0,
		KEY_BACKSPACE = 8,
		KEY_TAB = 9,
		KEY_ENTER = 13,
		KEY_SHIFT = 16,
		KEY_CTRL = 17,
		KEY_ALT = 18,
		и т.д.

Когда надо проверить, было ли нажатие (например Hit, первое нажатие), то, надо взять бит для нажатой кнопки из m_keyFlagsHit. Для этого есть маски

// masks
enum : uint64_t {
	KBIT_NONE = 0,
	KBIT_BACKSPACE = 0x1,
	KBIT_TAB = 0x2,
	KBIT_ENTER = 0x4,
	KBIT_SHIFT = 0x8,
	KBIT_CTRL = 0x10,
	KBIT_ALT = 0x20,
	KBIT_PAUSE = 0x40,
	KBIT_CAPS_LOCK = 0x80,
	KBIT_ESCAPE = 0x100,
	KBIT_SPACE = 0x200,
	KBIT_PGUP = 0x400,
	KBIT_PGDOWN = 0x800,

Напрмер, нажимаем Enter. Код клавиши 13. В m_keyFlagsHit[0] эта клавиша находится на третьей позиции

(00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000100)

Как быстро получить эту маску? Нужен массив, который будет хранить маски.

static const uint64_t g_keyToBin[] =
{
	0, //KEY_NONE = 0,
	0, 0, 0, 0, 0, 0, 0,
	KBIT_BACKSPACE,	//KEY_BACKSPACE = 8,
	KBIT_TAB,	//KEY_TAB = 9,
	0, 0, 0,
	KBIT_ENTER, //KEY_ENTER = 13,
	0, 0,
	KBIT_SHIFT, //KEY_SHIFT = 16,

g_keyToBin[13] даст значение KBIT_ENTER

Третий бит

(00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000100)

Если бит установлен для m_keyFlagsHit, то это означает что кнопка была нажата. Сигнал будет только один раз, так как m_keyFlagsHit обнулится. Если бит установлен для m_keyFlagsRelease, то это означает что кнопка была отжата. Так-же, сигнал будет только один раз, так как m_keyFlagsRelease обнулится. Если бит установлен для m_keyFlagsHold, то это значит что кнопка удерживается в зажатом положении.

Для удобства использования необходимо создать класс, который будет делать всё за нас.

// Класс с помощью которого можно узнать о состоянии клавиатуры и мышки
class bqInput
{
public:
	static bqInputData* GetData();
	static bqPointf& GetMousePosition();

	static void SetKeyHit(uint32_t, bool);
	static void SetKeyHold(uint32_t, bool);
	static void SetKeyRelease(uint32_t, bool);

	static bool IsKeyHit(uint32_t);
	static bool IsKeyHold(uint32_t);
	static bool IsKeyRelease(uint32_t);

	static void EnableLMBDown();
	static void EnableLMBHold();
	static void EnableLMBUp();
	static void EnableRMBDown();
	static void EnableRMBHold();
	static void EnableRMBUp();
	static void EnableMMBDown();
	static void EnableMMBHold();
	static void EnableMMBUp();
	static void EnableX1MBDown();
	static void EnableX1MBHold();
	static void EnableX1MBUp();
	static void EnableX2MBDown();
	static void EnableX2MBHold();
	static void EnableX2MBUp();

	static void DisableLMBDown();
	static void DisableLMBHold();
	static void DisableLMBUp();
	static void DisableRMBDown();
	static void DisableRMBHold();
	static void DisableRMBUp();
	static void DisableMMBDown();
	static void DisableMMBHold();
	static void DisableMMBUp();
	static void DisableX1MBDown();
	static void DisableX1MBHold();
	static void DisableX1MBUp();
	static void DisableX2MBDown();
	static void DisableX2MBHold();
	static void DisableX2MBUp();

	static bool IsLMBHit();
	static bool IsLMBHold();
	static bool IsLMBRelease();
	static bool IsRMBHit();
	static bool IsRMBHold();
	static bool IsRMBRelease();
	static bool IsMMBHit();
	static bool IsMMBHold();
	static bool IsMMBRelease();
	static bool IsX1MBHit();
	static bool IsX1MBHold();
	static bool IsX1MBRelease();
	static bool IsX2MBHit();
	static bool IsX2MBHold();
	static bool IsX2MBRelease();

	static const uint64_t* GetKeyToBin();

	// keyboard button code
	enum : uint32_t {
		KEY_NONE = 0,
		KEY_BACKSPACE = 8,
		KEY_TAB = 9,
		KEY_ENTER = 13,
		KEY_SHIFT = 16,
		KEY_CTRL = 17,
		KEY_ALT = 18,
		KEY_PAUSE = 19,
		KEY_CAPS_LOCK = 20,
		KEY_ESCAPE = 27,
		KEY_SPACE = 32,
		KEY_PGUP = 33,
		KEY_PGDOWN = 34,
		KEY_END = 35,
		KEY_HOME = 36,
		KEY_LEFT = 37,
		KEY_UP = 38,
		KEY_RIGHT = 39,
		KEY_DOWN = 40,
		KEY_PRTSCR = 44,
		KEY_INSERT = 45,
		KEY_DELETE = 46,
		KEY_0 = 48,
		KEY_1 = 49,
		KEY_2 = 50,
		KEY_3 = 51,
		KEY_4 = 52,
		KEY_5 = 53,
		KEY_6 = 54,
		KEY_7 = 55,
		KEY_8 = 56,
		KEY_9 = 57,
		KEY_A = 65,
		KEY_B = 66,
		KEY_C = 67,
		KEY_D = 68,
		KEY_E = 69,
		KEY_F = 70,
		KEY_G = 71,
		KEY_H = 72,
		KEY_I = 73,
		KEY_J = 74,
		KEY_K = 75,
		KEY_L = 76,
		KEY_M = 77,
		KEY_N = 78,
		KEY_O = 79,
		KEY_P = 80,
		KEY_Q = 81,
		KEY_R = 82,
		KEY_S = 83,
		KEY_T = 84,
		KEY_U = 85,
		KEY_V = 86,
		KEY_W = 87,
		KEY_X = 88,
		KEY_Y = 89,
		KEY_Z = 90,
		KEY_WIN = 91,
		KEY_CONTEXT = 93,
		KEY_NUM_0 = 96,
		KEY_NUM_1 = 97,
		KEY_NUM_2 = 98,
		KEY_NUM_3 = 99,
		KEY_NUM_4 = 100,
		KEY_NUM_5 = 101,
		KEY_NUM_6 = 102,
		KEY_NUM_7 = 103,
		KEY_NUM_8 = 104,
		KEY_NUM_9 = 105,
		KEY_NUM_MUL = 106, // *
		KEY_NUM_ADD = 107, // +
		KEY_NUM_SUB = 109, // -
		KEY_NUM_DOT = 110, // .
		KEY_NUM_SLASH = 111, // /
		KEY_F1 = 112,
		KEY_F2 = 113,
		KEY_F3 = 114,
		KEY_F4 = 115,
		KEY_F5 = 116,
		KEY_F6 = 117,
		KEY_F7 = 118,
		KEY_F8 = 119,
		KEY_F9 = 120,
		KEY_F10 = 121,
		KEY_F11 = 122,
		KEY_F12 = 123,
		KEY_NUM_LOCK = 144,
		KEY_SCROLL_LOCK = 145,
		KEY_LSHIFT = 160,
		KEY_RSHIFT = 161,
		KEY_LCTRL = 162,
		KEY_RCTRL = 163,
		KEY_LALT = 164,
		KEY_RALT = 165,
		KEY_FUNC_MY_COMP = 182, // Function key. open My computer
		KEY_FUNC_CALC = 183, // Function key. open Calculator
		KEY_COLON = 186, //;:
		KEY_ADD = 187, //=+
		KEY_COMMA = 188, //,<
		KEY_SUB = 189, //-_
		KEY_DOT = 190, //.>
		KEY_SLASH = 191, // /?
		KEY_TILDE = 192, //`~
		KEY_FIGURE_OPEN = 219, //[{
		KEY_BACKSLASH = 220, //\|
		KEY_FIGURE_CLOSE = 221, //]}
		KEY_QUOTE = 222, //'"
		KEY_end__,
	};
};

Коды клавиш так-же будут находится внутри класса.

Суну флаги в отдельный файл, так как может появиться желание использовать флаги напрямую.

inc/badcoiq/[b]input[/b]/bqInputEx.h

#include "badcoiq/input/bqInput.h"

namespace bq
{
	// для m_mouseButtonFlags
	enum
	{
		MouseFlag_LMBDOWN = 0x1,
		MouseFlag_LMBUP = 0x2,
		MouseFlag_RMBDOWN = 0x4,
		MouseFlag_RMBUP = 0x8,
		MouseFlag_MMBDOWN = 0x10,
		MouseFlag_MMBUP = 0x20,
		MouseFlag_X1MBDOWN = 0x40,
		MouseFlag_X1MBUP = 0x80,
		MouseFlag_X2MBDOWN = 0x100,
		MouseFlag_X2MBUP = 0x200,

		MouseFlag_LMBHOLD = 0x400,
		MouseFlag_RMBHOLD = 0x800,
		MouseFlag_MMBHOLD = 0x1000,
		MouseFlag_X1MBHOLD = 0x2000,
		MouseFlag_X2MBHOLD = 0x4000,
	};

	// для m_keyboardModifier
	enum
	{
		KeyboardMod_Clear = 0,
		KeyboardMod_Ctrl,
		KeyboardMod_Shift,
		KeyboardMod_Alt,
		KeyboardMod_CtrlShift,
		KeyboardMod_CtrlAlt,
		KeyboardMod_ShiftAlt,
		KeyboardMod_CtrlShiftAlt,
	};

	// Маски для получения бита
	enum : uint64_t
	{
		KeyboardBitMask_NONE = 0,
		KeyboardBitMask_BACKSPACE = 0x1,
		KeyboardBitMask_TAB = 0x2,
		KeyboardBitMask_ENTER = 0x4,
		KeyboardBitMask_SHIFT = 0x8,
		KeyboardBitMask_CTRL = 0x10,
		KeyboardBitMask_ALT = 0x20,
		KeyboardBitMask_PAUSE = 0x40,
		KeyboardBitMask_CAPS_LOCK = 0x80,
		KeyboardBitMask_ESCAPE = 0x100,
		KeyboardBitMask_SPACE = 0x200,
		KeyboardBitMask_PGUP = 0x400,
		KeyboardBitMask_PGDOWN = 0x800,
		KeyboardBitMask_END = 0x1000,
		KeyboardBitMask_HOME = 0x2000,
		KeyboardBitMask_LEFT = 0x4000,
		KeyboardBitMask_UP = 0x8000,
		KeyboardBitMask_RIGHT = 0x10000,
		KeyboardBitMask_DOWN = 0x20000,
		KeyboardBitMask_PRTSCR = 0x40000,
		KeyboardBitMask_INSERT = 0x80000,
		KeyboardBitMask_DELETE = 0x100000,
		KeyboardBitMask_0 = 0x200000,
		KeyboardBitMask_1 = 0x400000,
		KeyboardBitMask_2 = 0x800000,
		KeyboardBitMask_3 = 0x1000000,
		KeyboardBitMask_4 = 0x2000000,
		KeyboardBitMask_5 = 0x4000000,
		KeyboardBitMask_6 = 0x8000000,
		KeyboardBitMask_7 = 0x10000000,
		KeyboardBitMask_8 = 0x20000000,
		KeyboardBitMask_9 = 0x40000000,
		KeyboardBitMask_A = 0x80000000,
		KeyboardBitMask_B = 0x100000000,
		KeyboardBitMask_C = 0x200000000,
		KeyboardBitMask_D = 0x400000000,
		KeyboardBitMask_E = 0x800000000,
		KeyboardBitMask_F = 0x1000000000,
		KeyboardBitMask_G = 0x2000000000,
		KeyboardBitMask_H = 0x4000000000,
		KeyboardBitMask_I = 0x8000000000,
		KeyboardBitMask_J = 0x10000000000,
		KeyboardBitMask_K = 0x20000000000,
		KeyboardBitMask_L = 0x40000000000,
		KeyboardBitMask_M = 0x80000000000,
		KeyboardBitMask_N = 0x100000000000,
		KeyboardBitMask_O = 0x200000000000,
		KeyboardBitMask_P = 0x400000000000,
		KeyboardBitMask_Q = 0x800000000000,
		KeyboardBitMask_R = 0x1000000000000,
		KeyboardBitMask_S = 0x2000000000000,
		KeyboardBitMask_T = 0x4000000000000,
		KeyboardBitMask_U = 0x8000000000000,
		KeyboardBitMask_V = 0x10000000000000,
		KeyboardBitMask_W = 0x20000000000000,
		KeyboardBitMask_X = 0x40000000000000,
		KeyboardBitMask_Y = 0x80000000000000,
		KeyboardBitMask_Z = 0x100000000000000,
		KeyboardBitMask_WIN = 0x200000000000000,
		KeyboardBitMask_CONTEXT = 0x400000000000000,
		KeyboardBitMask_NUM_0 = 0x800000000000000,
		KeyboardBitMask_NUM_1 = 0x1,
		KeyboardBitMask_NUM_2 = 0x2,
		KeyboardBitMask_NUM_3 = 0x4,
		KeyboardBitMask_NUM_4 = 0x8,
		KeyboardBitMask_NUM_5 = 0x10,
		KeyboardBitMask_NUM_6 = 0x20,
		KeyboardBitMask_NUM_7 = 0x40,
		KeyboardBitMask_NUM_8 = 0x80,
		KeyboardBitMask_NUM_9 = 0x100,
		KeyboardBitMask_NUM_MUL = 0x200, // *
		KeyboardBitMask_NUM_ADD = 0x400, // +
		KeyboardBitMask_NUM_SUB = 0x800, // -
		KeyboardBitMask_NUM_DOT = 0x1000, // .
		KeyboardBitMask_NUM_SLASH = 0x2000, // /
		KeyboardBitMask_F1 = 0x4000,
		KeyboardBitMask_F2 = 0x8000,
		KeyboardBitMask_F3 = 0x10000,
		KeyboardBitMask_F4 = 0x20000,
		KeyboardBitMask_F5 = 0x40000,
		KeyboardBitMask_F6 = 0x80000,
		KeyboardBitMask_F7 = 0x100000,
		KeyboardBitMask_F8 = 0x200000,
		KeyboardBitMask_F9 = 0x400000,
		KeyboardBitMask_F10 = 0x800000,
		KeyboardBitMask_F11 = 0x1000000,
		KeyboardBitMask_F12 = 0x2000000,
		KeyboardBitMask_NUM_LOCK = 0x4000000,
		KeyboardBitMask_SCROLL_LOCK = 0x8000000,
		KeyboardBitMask_LSHIFT = 0x10000000,
		KeyboardBitMask_RSHIFT = 0x20000000,
		KeyboardBitMask_LCTRL = 0x40000000,
		KeyboardBitMask_RCTRL = 0x80000000,
		KeyboardBitMask_LALT = 0x100000000,
		KeyboardBitMask_RALT = 0x200000000,
		KeyboardBitMask_FUNC_MY_COMP = 0x400000000, // Function key. open My computer
		KeyboardBitMask_FUNC_CALC = 0x800000000, // Function key. open Calculator
		KeyboardBitMask_COLON = 0x1000000000, //;:
		KeyboardBitMask_ADD = 0x2000000000, //=+
		KeyboardBitMask_COMMA = 0x4000000000, //,<
		KeyboardBitMask_SUB = 0x8000000000, //-_
		KeyboardBitMask_DOT = 0x10000000000, //.>
		KeyboardBitMask_SLASH = 0x20000000000, // /?
		KeyboardBitMask_TILDE = 0x40000000000, //`~
		KeyboardBitMask_FIGURE_OPEN = 0x80000000000, //[{
		KeyboardBitMask_BACKSLASH = 0x100000000000, //\|
		KeyboardBitMask_FIGURE_CLOSE = 0x200000000000, //]}
		KeyboardBitMask_QUOTE = 0x400000000000, //'"
		KeyboardBitMask_end__,
	};
}

Массив g_keyToBin

src/badcoiq/[b]input[/b]/bqInput.cpp

static const uint64_t g_keyToBin[] =
{
	0, //KEY_NONE = 0,
	0, 0, 0, 0, 0, 0, 0,
	bq::KeyboardBitMask_BACKSPACE,	//KEY_BACKSPACE = 8,
	bq::KeyboardBitMask_TAB,	//KEY_TAB = 9,
	0, 0, 0,
	bq::KeyboardBitMask_ENTER, //KEY_ENTER = 13,
	0, 0,
	bq::KeyboardBitMask_SHIFT, //KEY_SHIFT = 16,
	bq::KeyboardBitMask_CTRL, //KEY_CTRL = 17,
	bq::KeyboardBitMask_ALT, //KEY_ALT = 18,
	bq::KeyboardBitMask_PAUSE,//KEY_PAUSE = 19,
	bq::KeyboardBitMask_CAPS_LOCK,//KEY_CAPS_LOCK = 20,
	0, 0, 0, 0, 0, 0,
	bq::KeyboardBitMask_ESCAPE, //KEY_ESCAPE = 27,
	0, 0, 0, 0,
	bq::KeyboardBitMask_SPACE, //KEY_SPACE = 32,
	bq::KeyboardBitMask_PGUP, //KEY_PGUP = 33,
	bq::KeyboardBitMask_PGDOWN, //KEY_PGDOWN = 34,
	bq::KeyboardBitMask_END, //KEY_END = 35,
	bq::KeyboardBitMask_HOME, //KEY_HOME = 36,
	bq::KeyboardBitMask_LEFT, //KEY_LEFT = 37,
	bq::KeyboardBitMask_UP, //KEY_UP = 38,
	bq::KeyboardBitMask_RIGHT, //KEY_RIGHT = 39,
	bq::KeyboardBitMask_DOWN, //KEY_DOWN = 40,
	0, 0, 0,
	bq::KeyboardBitMask_PRTSCR, //KEY_PRTSCR = 44,
	bq::KeyboardBitMask_INSERT, //KEY_INSERT = 45,
	bq::KeyboardBitMask_DELETE, //KEY_DELETE = 46,
	0,
	bq::KeyboardBitMask_0, //KEY_0 = 48,
	bq::KeyboardBitMask_1, //KEY_1 = 49,
	bq::KeyboardBitMask_2, //KEY_2 = 50,
	bq::KeyboardBitMask_3, //KEY_3 = 51,
	bq::KeyboardBitMask_4, //KEY_4 = 52,
	bq::KeyboardBitMask_5, //KEY_5 = 53,
	bq::KeyboardBitMask_6, //KEY_6 = 54,
	bq::KeyboardBitMask_7, //KEY_7 = 55,
	bq::KeyboardBitMask_8, //KEY_8 = 56,
	bq::KeyboardBitMask_9, //KEY_9 = 57,
	0, 0, 0, 0, 0, 0, 0,
	bq::KeyboardBitMask_A, //KEY_A = 65,
	bq::KeyboardBitMask_B, //KEY_B = 66,
	bq::KeyboardBitMask_C, //KEY_C = 67,
	bq::KeyboardBitMask_D, //KEY_D = 68,
	bq::KeyboardBitMask_E, //KEY_E = 69,
	bq::KeyboardBitMask_F, //KEY_F = 70,
	bq::KeyboardBitMask_G, //KEY_G = 71,
	bq::KeyboardBitMask_H, //KEY_H = 72,
	bq::KeyboardBitMask_I, //KEY_I = 73,
	bq::KeyboardBitMask_J, //KEY_J = 74,
	bq::KeyboardBitMask_K, //KEY_K = 75,
	bq::KeyboardBitMask_L, //KEY_L = 76,
	bq::KeyboardBitMask_M, //KEY_M = 77,
	bq::KeyboardBitMask_N, //KEY_N = 78,
	bq::KeyboardBitMask_O, //KEY_O = 79,
	bq::KeyboardBitMask_P, //KEY_P = 80,
	bq::KeyboardBitMask_Q, //KEY_Q = 81,
	bq::KeyboardBitMask_R, //KEY_R = 82,
	bq::KeyboardBitMask_S, //KEY_S = 83,
	bq::KeyboardBitMask_T, //KEY_T = 84,
	bq::KeyboardBitMask_U, //KEY_U = 85,
	bq::KeyboardBitMask_V, //KEY_V = 86,
	bq::KeyboardBitMask_W, //KEY_W = 87,
	bq::KeyboardBitMask_X, //KEY_X = 88,
	bq::KeyboardBitMask_Y, //KEY_Y = 89,
	bq::KeyboardBitMask_Z, //KEY_Z = 90,
	bq::KeyboardBitMask_WIN, //KEY_WIN = 91,
	0,
	bq::KeyboardBitMask_CONTEXT, //KEY_CONTEXT = 93,
	0, 0,
	bq::KeyboardBitMask_NUM_0, //KEY_NUM_0 = 96,
	bq::KeyboardBitMask_NUM_1, //KEY_NUM_1 = 97,
	bq::KeyboardBitMask_NUM_2, //KEY_NUM_2 = 98,
	bq::KeyboardBitMask_NUM_3, //KEY_NUM_3 = 99,
	bq::KeyboardBitMask_NUM_4, //KEY_NUM_4 = 100,
	bq::KeyboardBitMask_NUM_5, //KEY_NUM_5 = 101,
	bq::KeyboardBitMask_NUM_6, //KEY_NUM_6 = 102,
	bq::KeyboardBitMask_NUM_7, //KEY_NUM_7 = 103,
	bq::KeyboardBitMask_NUM_8, //KEY_NUM_8 = 104,
	bq::KeyboardBitMask_NUM_9, //KEY_NUM_9 = 105,
	bq::KeyboardBitMask_NUM_MUL,//	KEY_NUM_MUL = 106, // *
	bq::KeyboardBitMask_NUM_ADD, //KEY_NUM_ADD = 107, // +
	0,
	bq::KeyboardBitMask_NUM_SUB, //KEY_NUM_SUB = 109, // -
	bq::KeyboardBitMask_NUM_DOT, //KEY_NUM_DOT = 110, // .
	bq::KeyboardBitMask_NUM_SLASH, //KEY_NUM_SLASH = 111, // /
	bq::KeyboardBitMask_F1, //KEY_F1 = 112,
	bq::KeyboardBitMask_F2, //KEY_F2 = 113,
	bq::KeyboardBitMask_F3, //	KEY_F3 = 114,
	bq::KeyboardBitMask_F4, //KEY_F4 = 115,
	bq::KeyboardBitMask_F5, //KEY_F5 = 116,
	bq::KeyboardBitMask_F6, //KEY_F6 = 117,
	bq::KeyboardBitMask_F7, //KEY_F7 = 118,
	bq::KeyboardBitMask_F8, //KEY_F8 = 119,
	bq::KeyboardBitMask_F9, //KEY_F9 = 120,
	bq::KeyboardBitMask_F10, //KEY_F10 = 121,
	bq::KeyboardBitMask_F11, //KEY_F11 = 122,
	bq::KeyboardBitMask_F12, //KEY_F12 = 123,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		bq::KeyboardBitMask_NUM_LOCK,//	KEY_NUM_LOCK = 144,
		bq::KeyboardBitMask_SCROLL_LOCK, //KEY_SCROLL_LOCK = 145,
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		bq::KeyboardBitMask_LSHIFT, //KEY_LSHIFT = 160,
		bq::KeyboardBitMask_RSHIFT, //KEY_RSHIFT = 161,
		bq::KeyboardBitMask_LCTRL, //KEY_LCTRL = 162,
		bq::KeyboardBitMask_RCTRL, //KEY_RCTRL = 163,
		bq::KeyboardBitMask_LALT, //KEY_LALT = 164,
		bq::KeyboardBitMask_RALT, //KEY_RALT = 165,
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		bq::KeyboardBitMask_FUNC_MY_COMP, //KEY_FUNC_MY_COMP = 182, // Function key. open My computer
		bq::KeyboardBitMask_FUNC_CALC, //KEY_FUNC_CALC = 183, // Function key. open Calculator
		0, 0,
		bq::KeyboardBitMask_COLON, //KEY_COLON = 186, //;:
		bq::KeyboardBitMask_ADD, //KEY_ADD = 187, //=+
		bq::KeyboardBitMask_COMMA, //KEY_COMMA = 188, //,<
		bq::KeyboardBitMask_SUB, //KEY_SUB = 189, //-_
		bq::KeyboardBitMask_DOT, //KEY_DOT = 190, //.>
		bq::KeyboardBitMask_SLASH, //KEY_SLASH = 191, // /?
		bq::KeyboardBitMask_TILDE, //KEY_TILDE = 192, //`~
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		bq::KeyboardBitMask_FIGURE_OPEN, //KEY_FIGURE_OPEN = 219, //[{
		bq::KeyboardBitMask_BACKSLASH, //KEY_BACKSLASH = 220, //\|
		bq::KeyboardBitMask_FIGURE_CLOSE, //KEY_FIGURE_CLOSE = 221, //]}
		bq::KeyboardBitMask_QUOTE, //KEY_QUOTE = 222,
};

Реализация bqInput

#include "../framework/bqFrameworkImpl.h"

extern bqFrameworkImpl* g_framework;

static const uint64_t g_keyToBin[] = ...
...

bqInputData* bqInput::GetData()
{
	BQ_ASSERT_ST(g_framework);
	return &g_framework->m_input;
}

bqPointf& bqInput::GetMousePosition()
{
	BQ_ASSERT_ST(g_framework);
	return g_framework->m_input.m_mousePosition;
}

void bqInput::SetKeyHit(uint32_t k, bool v)
{
	BQ_ASSERT_ST(g_framework);

	uint64_t bit = g_keyToBin[k];

	if (k < bqInput::KEY_NUM_1)
	{
		if (v)
			g_framework->m_input.m_keyFlagsHit[0] |= bit;
		else
			g_framework->m_input.m_keyFlagsHit[0] &= ~bit;
	}
	else
	{
		if (v)
			g_framework->m_input.m_keyFlagsHit[1] |= bit;
		else
			g_framework->m_input.m_keyFlagsHit[1] &= ~bit;
	}
}

void bqInput::SetKeyHold(uint32_t k, bool v)
{
	BQ_ASSERT_ST(g_framework);

	uint64_t bit = g_keyToBin[k];

	if (k < bqInput::KEY_NUM_1)
	{
		if (v)
			g_framework->m_input.m_keyFlagsHold[0] |= bit;
		else
			g_framework->m_input.m_keyFlagsHold[0] &= ~bit;
	}
	else
	{
		if (v)
			g_framework->m_input.m_keyFlagsHold[1] |= bit;
		else
			g_framework->m_input.m_keyFlagsHold[1] &= ~bit;
	}
}

void bqInput::SetKeyRelease(uint32_t k, bool v)
{
	BQ_ASSERT_ST(g_framework);

	uint64_t bit = g_keyToBin[k];

	if (k < bqInput::KEY_NUM_1)
	{
		if (v)
			g_framework->m_input.m_keyFlagsRelease[0] |= bit;
		else
			g_framework->m_input.m_keyFlagsRelease[0] &= ~bit;
	}
	else
	{
		if (v)
			g_framework->m_input.m_keyFlagsRelease[1] |= bit;
		else
			g_framework->m_input.m_keyFlagsRelease[1] &= ~bit;
	}
}

bool bqInput::IsKeyHit(uint32_t i)
{
	BQ_ASSERT_ST(g_framework);

	uint64_t bit = g_keyToBin[i];

	if (i < bqInput::KEY_NUM_1) // первый uint64_t
		return (g_framework->m_input.m_keyFlagsHit[0] & bit);
	else
		return (g_framework->m_input.m_keyFlagsHit[1] & bit);
}

bool bqInput::IsKeyHold(uint32_t i)
{
	BQ_ASSERT_ST(g_framework);

	uint64_t bit = g_keyToBin[i];

	if (i < bqInput::KEY_NUM_1) // первый uint64_t
		return (g_framework->m_input.m_keyFlagsHold[0] & bit);
	else
		return (g_framework->m_input.m_keyFlagsHold[1] & bit);
}

bool bqInput::IsKeyRelease(uint32_t i)
{
	BQ_ASSERT_ST(g_framework);

	uint64_t bit = g_keyToBin[i];

	if (i < bqInput::KEY_NUM_1) // первый uint64_t
		return (g_framework->m_input.m_keyFlagsRelease[0] & bit);
	else
		return (g_framework->m_input.m_keyFlagsRelease[1] & bit);
}

void bqInput::EnableLMBDown() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_LMBDOWN; }
void bqInput::EnableLMBHold() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_LMBHOLD; }
void bqInput::EnableLMBUp() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_LMBUP; }
void bqInput::EnableRMBDown() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_RMBDOWN; }
void bqInput::EnableRMBHold() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_RMBHOLD; }
void bqInput::EnableRMBUp() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_RMBUP; }
void bqInput::EnableMMBDown() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_MMBDOWN; }
void bqInput::EnableMMBHold() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_MMBHOLD; }
void bqInput::EnableMMBUp() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_MMBUP; }
void bqInput::EnableX1MBDown() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_X1MBDOWN; }
void bqInput::EnableX1MBHold() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_X1MBHOLD; }
void bqInput::EnableX1MBUp() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_X1MBUP; }
void bqInput::EnableX2MBDown() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_X2MBDOWN; }
void bqInput::EnableX2MBHold() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_X2MBHOLD; }
void bqInput::EnableX2MBUp() { g_framework->m_input.m_mouseButtonFlags |= bq::MouseFlag_X2MBUP; }

void bqInput::DisableLMBDown() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_LMBDOWN; }
void bqInput::DisableLMBHold() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_LMBHOLD; }
void bqInput::DisableLMBUp() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_LMBUP; }
void bqInput::DisableRMBDown() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_RMBDOWN; }
void bqInput::DisableRMBHold() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_RMBHOLD; }
void bqInput::DisableRMBUp() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_RMBUP; }
void bqInput::DisableMMBDown() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_MMBDOWN; }
void bqInput::DisableMMBHold() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_MMBHOLD; }
void bqInput::DisableMMBUp() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_MMBUP; }
void bqInput::DisableX1MBDown() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_X1MBDOWN; }
void bqInput::DisableX1MBHold() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_X1MBHOLD; }
void bqInput::DisableX1MBUp() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_X1MBUP; }
void bqInput::DisableX2MBDown() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_X2MBDOWN; }
void bqInput::DisableX2MBHold() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_X2MBHOLD; }
void bqInput::DisableX2MBUp() { g_framework->m_input.m_mouseButtonFlags &= ~bq::MouseFlag_X2MBUP; }

bool bqInput::IsLMBHit() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_LMBDOWN) == bq::MouseFlag_LMBDOWN; }
bool bqInput::IsLMBHold() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_LMBHOLD) == bq::MouseFlag_LMBHOLD; }
bool bqInput::IsLMBRelease() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_LMBUP) == bq::MouseFlag_LMBUP; }
bool bqInput::IsRMBHit() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_RMBDOWN) == bq::MouseFlag_RMBDOWN; }
bool bqInput::IsRMBHold() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_RMBHOLD) == bq::MouseFlag_RMBHOLD; }
bool bqInput::IsRMBRelease() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_RMBUP) == bq::MouseFlag_RMBUP; }
bool bqInput::IsMMBHit() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_MMBDOWN) == bq::MouseFlag_MMBDOWN; }
bool bqInput::IsMMBHold() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_MMBHOLD) == bq::MouseFlag_MMBHOLD; }
bool bqInput::IsMMBRelease() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_MMBUP) == bq::MouseFlag_MMBUP; }
bool bqInput::IsX1MBHit() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_X1MBDOWN) == bq::MouseFlag_X1MBDOWN; }
bool bqInput::IsX1MBHold() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_X1MBHOLD) == bq::MouseFlag_X1MBHOLD; }
bool bqInput::IsX1MBRelease() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_X1MBUP) == bq::MouseFlag_X1MBUP; }
bool bqInput::IsX2MBHit() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_X2MBDOWN) == bq::MouseFlag_X2MBDOWN; }
bool bqInput::IsX2MBHold() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_X2MBHOLD) == bq::MouseFlag_X2MBHOLD; }
bool bqInput::IsX2MBRelease() { return (g_framework->m_input.m_mouseButtonFlags & bq::MouseFlag_X2MBUP) == bq::MouseFlag_X2MBUP; }


static const uint64_t* GetKeyToBin()
{
	return g_keyToBin;
}

Так как используется 2 переменные для хранения состояний кнопок, идёт проверка, если код клавиши меньше bqInput::KEY_NUM_1 то далее идёт работа с первой переменной, иначе со второй.

Засунул класс bqFrameworkImpl в свой include, чтобы можно было использовать глобальный g_framework. Так-же в bqFramework добавил объект для хранения ввода

class bqFrameworkImpl
{
public:
...

	bqInputData m_input;

...
};

Функция bqFramework::Update

Надо добавить две функции, перед вызовом оконной процедуры, и после.

bqInputUpdatePre();

#ifdef BQ_PLATFORM_WINDOWS
	// без этого окно не будет реагировать
	MSG msg;
	while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
	{
		GetMessage(&msg, NULL, 0, 0);
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
#endif

	bqInputUpdatePost();

Их реализация (в bqInput.cpp)

// обнуляем здесь
void bqInputUpdatePre()
{
	g_framework->m_input.m_mousePositionOld = g_framework->m_input.m_mousePosition;
	g_framework->m_input.m_mouseButtonFlags &= ~0x3FF;
	g_framework->m_input.m_mouseWheelDelta = 0;
	g_framework->m_input.m_character = 0;
	g_framework->m_input.m_keyFlagsHit[0] = 0;
	g_framework->m_input.m_keyFlagsHit[1] = 0;
	g_framework->m_input.m_keyFlagsRelease[0] = 0;
	g_framework->m_input.m_keyFlagsRelease[1] = 0;
}

// тут находим m_mouseMoveDelta и m_keyboardModifier
void bqInputUpdatePost()
{
	unsigned int ctrl_shift_alt = 0;
	if (bqInput::IsKeyHold(bqInput::KEY_LALT) || bqInput::IsKeyHold(bqInput::KEY_RALT))
		ctrl_shift_alt |= 1;

	if (bqInput::IsKeyHold(bqInput::KEY_LSHIFT) || bqInput::IsKeyHold(bqInput::KEY_RSHIFT))
		ctrl_shift_alt |= 2;

	if (bqInput::IsKeyHold(bqInput::KEY_LCTRL) || bqInput::IsKeyHold(bqInput::KEY_RCTRL))
		ctrl_shift_alt |= 4;

	switch (ctrl_shift_alt)
	{
	default:
	case 0:  g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_Clear;         break;
	case 1:  g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_Alt;           break;
	case 2:  g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_Shift;         break;
	case 3:  g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_ShiftAlt;      break;
	case 4:  g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_Ctrl;          break;
	case 5:  g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_CtrlAlt;       break;
	case 6:  g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_CtrlShift;     break;
	case 7:  g_framework->m_input.m_keyboardModifier = bq::KeyboardMod_CtrlShiftAlt;  break;
	}

	g_framework->m_input.m_mouseMoveDelta.x = g_framework->m_input.m_mousePosition.x - 
		g_framework->m_input.m_mousePositionOld.x;
	g_framework->m_input.m_mouseMoveDelta.y = g_framework->m_input.m_mousePosition.y - 
		g_framework->m_input.m_mousePositionOld.y;
}

Теперь надо пойти в оконную процедуру и получить состояния, заполнить bqInputData.

Оконная процедура

Для получения состояния о мышки использую Raw Input.

Оконное сообщение.

case WM_INPUT:
{
	if (pW)
	{
		HRAWINPUT hRawInput = (HRAWINPUT)lParam;
		UINT dataSize;
		GetRawInputData(hRawInput, RID_INPUT, NULL, &dataSize, sizeof(RAWINPUTHEADER));

		if (dataSize == 0 || dataSize > 0xff)
			break;

		bqWindowWin32* w32 = (bqWindowWin32*)pW->GetData()->m_implementation;

		void* dataBuf = &w32->m_rawInputData[0];
		GetRawInputData(hRawInput, RID_INPUT, dataBuf, &dataSize, sizeof(RAWINPUTHEADER));

		const RAWINPUT* raw = (const RAWINPUT*)dataBuf;
		if (raw->header.dwType == RIM_TYPEMOUSE)
		{
			HANDLE deviceHandle = raw->header.hDevice;

			const RAWMOUSE& mouseData = raw->data.mouse;

			USHORT flags = mouseData.usButtonFlags;
			short wheelDelta = (short)mouseData.usButtonData;
			LONG x = mouseData.lLastX, y = mouseData.lLastY;

			/*wprintf(
				L"Mouse: Device=0x%08X, Flags=%04x, WheelDelta=%d, X=%d, Y=%d\n",
				deviceHandle, flags, wheelDelta, x, y);*/

			bqInputData* id = bqInput::GetData();

			if (wheelDelta)
				id->m_mouseWheelDelta = (float)wheelDelta / (float)WHEEL_DELTA;

			RECT rct;
			GetWindowRect(hWnd, &rct);

			POINT cursorPoint;
			GetCursorPos(&cursorPoint);
			//ScreenToClient(hWnd, &cursorPoint);
			id->m_mousePosition.x = (float)(cursorPoint.x - rct.left - pW->GetBorderSize()->x);
			id->m_mousePosition.y = (float)(cursorPoint.y - rct.top - pW->GetBorderSize()->y);

			 printf("%i %i\n", cursorPoint.x, cursorPoint.y);

			if (flags)
			{
				if ((flags & 0x1) == 0x1)
				{
					bqInput::EnableLMBDown();
					bqInput::EnableLMBHold();
				}

				if ((flags & 0x2) == 0x2)
				{
					bqInput::EnableLMBUp();
					bqInput::DisableLMBHold();
				}

				if ((flags & 0x4) == 0x4)
				{
					bqInput::EnableRMBDown();
					bqInput::EnableRMBHold();
				}
				if ((flags & 0x8) == 0x8)
				{
					bqInput::EnableRMBUp();
					bqInput::DisableRMBHold();
				}

				if ((flags & 0x10) == 0x10)
				{
					bqInput::EnableMMBDown();
					bqInput::EnableMMBHold();
				}
				if ((flags & 0x20) == 0x20)
				{
					bqInput::EnableMMBUp();
					bqInput::DisableMMBHold();
				}

				if ((flags & 0x100) == 0x100)
				{
					bqInput::EnableX1MBDown();
					bqInput::EnableX1MBHold();
				}
				if ((flags & 0x200) == 0x200)
				{
					bqInput::EnableX1MBUp();
					bqInput::DisableX1MBHold();
				}

				if ((flags & 0x40) == 0x40)
				{
					bqInput::EnableX2MBDown();
					bqInput::EnableX2MBHold();
				}
				if ((flags & 0x80) == 0x80)
				{
					bqInput::EnableX2MBUp();
					bqInput::DisableX2MBHold();
				}

			}

		}
	}
}break;

Raw Input надо инициализировать. В bqFramework::Start добавляю

#ifdef BQ_PLATFORM_WINDOWS
		RAWINPUTDEVICE device;
		device.usUsagePage = 0x01;
		device.usUsage = 0x02;
		device.dwFlags = 0;
		device.hwndTarget = 0;
		RegisterRawInputDevices(&device, 1, sizeof device);
#endif

Возвращаюсь в оконную процедуру и получаю информацию о клавиатуре.

case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
case WM_KEYDOWN:
case WM_KEYUP:
{
	bool isPress = true;

	uint32_t key = (uint32_t)wParam;

	if (message == WM_SYSKEYUP) isPress = false;
	if (message == WM_KEYUP) isPress = false;

	if (key == bqInput::KEY_SHIFT)
	{ // shift -> lshift rshift
		key = MapVirtualKey(((lParam >> 16) & 255u), 3);
	}
	if (key == bqInput::KEY_CTRL)
	{ // ctrl -> lctrl rctrl
		key = MapVirtualKey(((lParam >> 16) & 255), 3);
		if (lParam & 0x1000000)
			key = 163;
	}

	if (key == bqInput::KEY_ALT)
	{ // alt -> lalt ralt
		key = MapVirtualKey(((lParam >> 16) & 255), 3);
		if (lParam & 0x1000000)
			key = 165;
		//printf("alt = %i\n",(int)ev.keyboardEvent.key);
	}

	if (isPress)
	{
		if (key < 256)
		{
			bqInput::SetKeyHold(key, true);
			bqInput::SetKeyHit(key, true);
		}
	}
	else
	{
		if (key < 256)
		{
			bqInput::SetKeyHold(key, false);
			bqInput::SetKeyRelease(key, true);
		}
	}

	if (message == WM_SYSKEYDOWN || message == WM_SYSKEYUP)
	{
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	else
	{
		return 0;
	}
}break;

Надо выключить активацию меню окна когда нажимаешь Alt

case WM_SYSCOMMAND:
	if ((wParam & 0xFFF0) == SC_SCREENSAVE ||
		(wParam & 0xFFF0) == SC_MONITORPOWER ||
		(wParam & 0xFFF0) == SC_KEYMENU
		)
	{
		return 0;
	}

Получение вводимого символа

case WM_CHAR:
{
	bqInputData* id = bqInput::GetData();
	id->m_character = wParam;
}break;

https://github.com/badcoiq/badcoiq/tree/e95238e96dbb36b17d0bef1700681eed96ca4ec6