如何正确处理 SDL2 中的控制键组合
How to correctly handle control-key combinations in SDL2
在我基于 SDL 2.0 的应用程序中,我想同时处理 Control +
和 Control =
。
我知道我可以处理 SDL_KEYDOWN
事件,并结合 KEYMODE_CTRL
查找 SDLK_EQUALS
键码。甚至检查 KEYMOD_SHIFT' to distinguish between
+and
=`。但是,这不是可移植的,并且在这些符号映射到不同键的键盘上会中断。
我尝试过的另一件事是启用 SDL_StartTextInput()
然后收听 SDL_TEXTINPUT
事件。但是,这仅适用于可打印字符。它完全忽略控制序列。
正确的做法是什么?我看到 SDL 1.2 实际上在 SDL_Keysym
结构中有一个 unicode
字段。这肯定会让我更容易。有谁知道为什么删除它以及 SDL 2.0 中的等价物是什么?
这是一个示例,您可以如何将 unicode 输入作为 SDL_TEXTINPUT 而将其余输入作为 SDL_KEYDOWN:
#include "SDL.h"
int main(int argc, char *argv[]) {
int done = 0;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *w = SDL_CreateWindow("foo", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
640, 480, 0);
int lctrl = 0, rctrl = 0;
SDL_StartTextInput();
while (!done) {
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
done = 1;
break;
case SDL_TEXTINPUT: {
int ctrl_state = lctrl || rctrl;
printf("%s, ctrl %s\n", event.text.text, (ctrl_state) ? "pressed" : "released");
} break;
case SDL_KEYDOWN:
if(event.key.keysym.sym == SDLK_RCTRL) { rctrl = 1; }
else if(event.key.keysym.sym == SDLK_LCTRL) { lctrl = 1; }
break;
case SDL_KEYUP:
if(event.key.keysym.sym == SDLK_RCTRL) { rctrl = 0; }
else if(event.key.keysym.sym == SDLK_LCTRL) { lctrl = 0; }
break;
}
}
SDL_UpdateWindowSurface(w);
}
SDL_Quit();
return 0;
}
为了简化事情,它忽略了 SDL_TEXTEDITING,这可能(也可能不是)您想要的。也可以使用 SDL_GetKeyboardState
代替手动处理事件和累积修改键标志,结果相同。
在我基于 SDL 2.0 的应用程序中,我想同时处理 Control +
和 Control =
。
我知道我可以处理 SDL_KEYDOWN
事件,并结合 KEYMODE_CTRL
查找 SDLK_EQUALS
键码。甚至检查 KEYMOD_SHIFT' to distinguish between
+and
=`。但是,这不是可移植的,并且在这些符号映射到不同键的键盘上会中断。
我尝试过的另一件事是启用 SDL_StartTextInput()
然后收听 SDL_TEXTINPUT
事件。但是,这仅适用于可打印字符。它完全忽略控制序列。
正确的做法是什么?我看到 SDL 1.2 实际上在 SDL_Keysym
结构中有一个 unicode
字段。这肯定会让我更容易。有谁知道为什么删除它以及 SDL 2.0 中的等价物是什么?
这是一个示例,您可以如何将 unicode 输入作为 SDL_TEXTINPUT 而将其余输入作为 SDL_KEYDOWN:
#include "SDL.h"
int main(int argc, char *argv[]) {
int done = 0;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *w = SDL_CreateWindow("foo", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
640, 480, 0);
int lctrl = 0, rctrl = 0;
SDL_StartTextInput();
while (!done) {
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
done = 1;
break;
case SDL_TEXTINPUT: {
int ctrl_state = lctrl || rctrl;
printf("%s, ctrl %s\n", event.text.text, (ctrl_state) ? "pressed" : "released");
} break;
case SDL_KEYDOWN:
if(event.key.keysym.sym == SDLK_RCTRL) { rctrl = 1; }
else if(event.key.keysym.sym == SDLK_LCTRL) { lctrl = 1; }
break;
case SDL_KEYUP:
if(event.key.keysym.sym == SDLK_RCTRL) { rctrl = 0; }
else if(event.key.keysym.sym == SDLK_LCTRL) { lctrl = 0; }
break;
}
}
SDL_UpdateWindowSurface(w);
}
SDL_Quit();
return 0;
}
为了简化事情,它忽略了 SDL_TEXTEDITING,这可能(也可能不是)您想要的。也可以使用 SDL_GetKeyboardState
代替手动处理事件和累积修改键标志,结果相同。