Hotkey
按键绑定、Toggle/Hold/Once 模式与持久化。
include/XBase/Hotkey.h · XBase::Hotkey
热键模块只处理按键到回调的映射与状态机。宿主负责每帧调用
Process(),并根据Hooks::IsKeyboardCaptureActive()决定是否暂停派发。
类型
enum class Key : std::uint16_t; // Windows 虚拟键编码,含鼠标键
struct Modifiers {
bool ctrl = false;
bool shift = false;
bool alt = false;
bool win = false;
};
enum class Mode {
Toggle, // 按下切换状态
Hold, // 按住生效,松开失效
Once // 仅触发一次
};
struct Binding {
std::string id;
Key key = Key::None;
Modifiers mods;
Mode mode = Mode::Toggle;
std::function<void(bool)> onChange;
bool state = false;
bool prevPressed = false;
};修饰键为包含语义:绑定要求 ctrl 时,按住 Ctrl+Alt 仍然触发。
生命周期与注册
void Init();
void Process();
bool Register(const std::string& id, Key key, Modifiers mods, Mode mode, std::function<void(bool)> callback);
bool Unregister(const std::string& id);
Binding* Get(const std::string& id);
std::vector<Binding*> GetAll();Process()每帧调用一次:轮询按键状态并派发onChange。不调用Process()时绑定不会触发。Toggle在按下沿切换state并回调新状态;Hold在状态变化时回调;Once只在按下沿回调一次true。- 相同
id重复Register()会替换原绑定,已加载的持久化键位优先生效。
XBase::Hotkey::Register("menu.toggle", XBase::Hotkey::Key::F4,
{}, XBase::Hotkey::Mode::Toggle, [](bool enabled) {
XBase::Hooks::SetMenuVisible(enabled);
});状态查询
bool IsPressed(Key key); // 当前帧的按下沿
bool IsKeyDown(Key key); // 当前是否按住
bool IsToggled(Key key); // 任一 Toggle 绑定处于激活状态IsPressed() 在 Process() 更新后有效,适合驱动一次性动作;持续状态用 IsKeyDown()。
持久化
void SaveBindings(const std::string& filePath = "");
void LoadBindings(const std::string& filePath = "");
std::string KeyToString(Key key);
Key StringToKey(const std::string& str);- 默认路径为
XBase\hotkeys.json;文件保存key、ctrl、shift、alt、win、mode。 LoadBindings()会在绑定已存在时立即应用键位,对之后注册的同id绑定同样生效。KeyToString()优先返回名称(F5、Space、LMB),未知键返回VK_0xNN;StringToKey()同时接受名称、十进制与0x前缀编码。
边界
- 热键基于全局按键轮询,与 ImGui 文本输入不互斥。菜单处于文本输入状态时,宿主应跳过
Process()或忽略冲突绑定。 - 绑定回调在游戏主线程执行,回调内不要做阻塞 IO。