C++ C++;:GetKeyState()必须运行一次
我需要监听我的微型应用程序的键盘键状态C++ C++;:GetKeyState()必须运行一次,c++,winapi,keyboard,keypress,C++,Winapi,Keyboard,Keypress,我需要监听我的微型应用程序的键盘键状态 #include <windows.h> #include <fstream> #include <iostream> using namespace std; int main() { while(1) { if(GetKeyState(VK_SPACE) & 0x80) { cout << "Space pressed.\
#include <windows.h>
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
while(1)
{
if(GetKeyState(VK_SPACE) & 0x80)
{
cout << "Space pressed.\r\n";
DoSpaceKeyTask();
}
if(GetKeyState(OTHER_KEY) & 0x80)
{
cout << "Other key pressed.\r\n";
DoOtherKeyTask();
}
}
return 0;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
而(1)
{
if(GetKeyState(VK_空间)&0x80)
{
请尝试以下方法:
#include <windows.h>
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
char lastSpaceState = 0, lastOtherKeyState = 0, spaceState, otherKeyState;
while(1)
{
spaceState = (GetKeyState(VK_SPACE & 0x80) != 0);
lastSpaceState = (spaceState && !lastSpaceState);
if(lastSpaceState)
{
cout << "Space pressed.\r\n";
DoSpaceKeyTask();
}
otherKeyState = (GetKeyState(OTHER_KEY) & 0x80 != 0);
lastOtherKeyState = (otherKeyState && !lastOtherKeyState);
if(lastOtherKeyState)
{
cout << "Other key pressed.\r\n";
DoOtherKeyTask();
}
}
return 0;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
char lastSpaceState=0,lastOtherKeyState=0,spaceState,otherKeyState;
而(1)
{
spaceState=(GetKeyState(VK_SPACE&0x80)!=0);
lastSpaceState=(spaceState&&!lastSpaceState);
if(lastSpaceState)
{
你想要一个windows钩子来钩住游戏,并对游戏得到的键盘输入做出反应。现在我还没有真正做过这种特定类型的钩子,但我可以给你一个关于流程的好主意。我会让你通过一个你需要的键的映射来减少空间,而不是一个巨大的重复开关,并找出任何sm我放进去的所有扭结
int main()
{
//I imagine the last argument here is the thread
//containing the game's message loop
HHOOK hook = SetWindowsHookEx (WH_CALLWNDPROC, hookProc, NULL, NULL);
//main loop
UnhookWindowsHookEx (hook);
}
LRESULT CALLBACK hookProc (int code, WPARAM wParam, LPARAM lParam)
{
if (code == HC_ACTION)
{
CWPSTRUCT details = *((LPCWPSTRUCT)lParam);
if (details.message == WM_KEYDOWN)
{
switch (details.wParam)
{
case KEY_ONE:
if (last [KEY_ONE] == UP)
{
DoKeyOneStuff();
last [KEY_ONE] = DOWN;
}
break;
}
}
else if (details.message == WM_KEYUP)
{
switch (details.wParam)
{
case KEY_ONE:
last [KEY_ONE] = UP;
break;
}
}
}
return CallNextHookEx (NULL, code, wParam, lParam);
}
注意我如何使用last[KEY\u ONE]
。我建议使用std::map
来存储vk代码所需的键。然后,您可以在地图中循环,并减少开关占用的大量空间。由于按钮保持按下的持续时间,您的函数会被多次调用。系统非常敏感。因此,这是一种解决方法。
您可以这样做(设置一个标志,该标志将在按键按下时指定一个值,然后在按键按下时重新签名)
int k=0;//标志
而(1){
//检查按键是否按下(按键向下)
如果((GetAsyncKeyState('0')&0x8000)和(&(k==0)){k=1;cout我认为您更愿意只在释放键时执行函数“一次”,而不是在按下键时
为了实现这个目标,您不需要任何额外的标志和帮助变量来定义、分配、分配到0,并将每个标志和帮助变量设置为1和重置为0等等。您所需要的只是:首先,您必须在while(1)的范围内使用GetKeyState函数当您按下某个键时进行检查。当表达式返回true时,执行器指针(执行一个代码行的箭头,当您跨入或跨过时,该箭头将前进到下一个代码行)将进入if语句的作用域。然后立即将其困在循环中,并在按下的键仍处于按下状态时将其困在循环中,并在执行函数之前停止它,在向上释放该键时释放它,然后让它执行函数
例如,要在按下并释放空格键时仅“一次”执行DoSpaceKeyTask功能,请执行以下代码:
while (1)
{
if (GetKeyState(VK_SPACE) & 0x80)
{
//The code here executes ONCE at the moment the space bar was pressed
cout << "Space pressed.\r\n";
while (GetKeyState(VK_SPACE) & 0x80) //You can write there ';' instead '{' and '}' below
{
//The executor pointer is trapped here while space bar is depressed and it will be free once space bar is released
}
//The code here executes ONCE at the moment the space bar was released
cout << "Space released.\r\n";
DoSpaceKeyTask();
}
}
while(1)
{
if(GetKeyState(VK_空间)&0x80)
{
//这里的代码在按下空格键时执行一次
cout我也遇到了同样的问题。我有几个键,就像切换按钮一样,每次按下只想注册一次键事件。我的解决方案是制作一个简单的对象来处理逻辑。这可以保持主代码干净:
class KeyToggle {
public:
KeyToggle(int key):mKey(key),mActive(false){}
operator bool() {
if(GetAsyncKeyState(mKey)){
if (!mActive){
mActive = true;
return true;
}
}
else
mActive = false;
return false;
}
private:
int mKey;
bool mActive;
};
下面是用法:
#include <windows.h>
KeyToggle toggleT(0x54); // T key toggle
KeyToggle toggleF(0x46); // F key toggle
void main(void)
{
while(true){
if(toggleT) {;} // do something
if(toggleF) {;} // do something
}
}
#包括
KeyToggle toggleT(0x54);//T键切换
按键切换切换F(0x46);//F按键切换
真空总管(真空)
{
while(true){
如果(toggleT){;}//做某事
如果(toggleF){;}//做某事
}
}
我知道这是一个非常老的线程,但我仍然想分享我的解决方案。我认为创建某种“标志”或“开关”是真的不需要的。下面是我循环所有关键代码的代码:
while (true)
{
for (int i = 0x01; i < 0xFE; i++)
{
if (GetKeyState(i) & 0x8000)
{
std::cout << (char)i << "\n";
while (GetKeyState(i) & 0x8000) {}
}
}
}
while(true)
{
对于(int i=0x01;i<0xFE;i++)
{
if(GetKeyState(i)&0x8000)
{
试一下这样的东西
while (!GetKeyState(VK_SPACE) && !GetKeyState('A') == 1) {
//std::cout << "Key not pressed... \n";
Sleep(40);
}
if (GetKeyState('A')) {
std::cout << "\"A \" key pressed... \n";
}
else if (GetKeyState(VK_SPACE)) {
std::cout << "Space key pressed... \n";
}
while(!GetKeyState(VK_空间)和&!GetKeyState('A')==1){
//std::cout 1.您希望该循环使用GetAsyncKeyState
。2.您必须使用0x8000
来屏蔽它。此外,您还可以使用while(GetAsyncKeyState(…)&0x8000)
等待它上升。这里有一个关于第1点的很好的宣传:嗨,克里斯,GetAsyncKeyState和0x8000仍然是一样的。有什么想法吗?你应该使用一个状态机制,如下图所示,或者使用一些通知你按键/按下的东西,比如窗口或钩子。哦,这会让事情变得更清楚一些。你正在寻找的函数或者是SetWindowsHookEx
。各种钩子有很多很好的例子,但是你想要的是钩子游戏窗口的消息过程。钩子它以检查关键事件,并适当地处理它们。这不是一个真正的旧的或现代的情况。GetKeyState
用于当你需要状态时的消息消息已发送。GetAsyncKeyState
表示当前状态。另外,0x80是10000000。文档中说,如果它是向下的,则会设置高位,并且它返回的是短的,因此是10000000000000或0x8000。我感谢您的回复,但是如果有5个或更多的键,它将是一个完全混乱的状态。@AnılÜnal,您可以使用调用钩子。类似(非真实语法):if(WM_KEYDOWN){switch(code){case SPACE:if(last==UP)DoSomething();…}}
并使用WM_KEYDOWN
和WM_KEYDOWN
消息设置状态。在键盘操作发生之前不应调用钩子;否则它应该是空闲的。
while (true)
{
for (int i = 0x01; i < 0xFE; i++)
{
if (GetKeyState(i) & 0x8000)
{
std::cout << (char)i << "\n";
while (GetKeyState(i) & 0x8000) {}
}
}
}
while (!GetKeyState(VK_SPACE) && !GetKeyState('A') == 1) {
//std::cout << "Key not pressed... \n";
Sleep(40);
}
if (GetKeyState('A')) {
std::cout << "\"A \" key pressed... \n";
}
else if (GetKeyState(VK_SPACE)) {
std::cout << "Space key pressed... \n";
}