我目前正在使用c ++和Windows API创建一个需要用户从键盘输入的程序。
我当前的解决方案正在工作,但我想问一问是否有更好的方法来实现我想要做的事情。
当前解决方案:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
switch (message){
case WM_CHAR:
switch (wParam) {
case 119:
std::cout << "W" << std::endl;
break;
case 97:
std::cout << "A" << std::endl;
break;
case 115:
std::cout << "S" << std::endl;
break;
case 100:
std::cout << "D" << std::endl;
break;
}
break;
return 0;
}
如果要获取键盘上的每个键,则必须为每个键设置一个外壳。有更好的方法吗?
此外,在线上是否有任何参考资料可供我获取每个钥匙的代码?
编辑:我想为每个单独的键实现逻辑。首先应该提到我的道歉。
谢谢
答案 0 :(得分:2)
如果您真的只是想打印每个键ASCII table being mapped directly in this case,很明显的是将其存储在case WM_CHAR:
内,而不是整个第二个switch
:
std::wcout << static_cast<wchar_t>(wParam) << std::endl;
如果您希望能够为每个键定义一个单独的特定处理程序逻辑,则以下示例可能是一个更好的模式,因为它将简化WndProc()
的逻辑并添加一个级别间接处理,使您可以将处理程序本身视为一流的对象:
#include <iostream>
#include <functional>
#include <map>
#include <Windows.h>
std::map<uint32_t, std::function<void()>> gKeyCallback;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CHAR:
auto mapIter = gKeyCallback.find(static_cast<uint32_t>(wParam));
if (mapIter != gKeyCallback.end())
mapIter->second();
break;
}
return 0;
}
int main()
{
gKeyCallback['W'] = [] {std::cout << "Handler for 'W'" << std::endl; };
gKeyCallback['A'] = [] {std::cout << "Handler for 'A'" << std::endl; };
gKeyCallback['S'] = [] {std::cout << "Handler for 'S'" << std::endl; };
gKeyCallback['D'] = [] {std::cout << "Handler for 'D'" << std::endl; };
return 0;
}
这个想法包括持有一个映射容器,从而能够为每个给定的键获取适当的处理程序回调函数。您可以更改原型以适合您的需求。 lambda expression符号用于使每个密钥处理程序的初始化在眼睛上不那么费劲,并且以后更易于维护:
此行:
std::map<uint32_t, std::function<void()>> gKeyCallback;
定义映射容器(又称字典)对象。它是type std::map
的名称,在这里它表示从类型uint32_t
到处理程序回调函数类型的映射-当前是统一的void()
回调。
此行的作用:
gKeyCallback['W'] = [] {std::cout << "Handler for 'W'" << std::endl; };
是映射键值119
(ASCII值'W'
)到它想要的特定逻辑,在{}
(花括号)内指定。这里的关键语法元素是[]
。 Here you can read all about how to use this lambda expression syntax。
注意:绝对不是使用全局变量(gKeyCallback
)的建议,只是为了简化代码示例而已。