我想做到这一点,以使我的程序在发布ALT之前不会继续,因此我可以切换bool,而无需无限循环遍历if(istrue / isfalse)。
这是我的尝试
for (;;) {
if (GetAsyncKeyState(VK_MENU))
{
TPSWITCH = !TPSWITCH;
}
else
{
continue;
}
}
答案 0 :(得分:0)
GetAsyncKeyState
检查密钥的状态。当您按住ALT键时,每次都会返回向下状态,因此,每次进入循环时,都会执行TPSWITCH = !TPSWITCH
。尝试下面的代码,直到键按下:
for(;;)
{
if (GetAsyncKeyState(VK_MENU)&0x8000) //0x8000 ignore the least significant bit
{
while (GetAsyncKeyState(VK_MENU)&0x8000);
TPSWITCH = !TPSWITCH;
cout << "key up" << endl;
}
else
{
continue;
}
}
答案 1 :(得分:0)
如果您感兴趣的是语义丰富的用户操作(例如“单击”),则GetAsyncKeyState(...)返回的输出基本上位于所需水平之下。 GetAsyncKeyState(...)实际上只是告诉您此时某个键是向上还是向下-这不是您想要循环播放的键,因为正在运行的计算机程序正运行着许多离散时刻。
您需要做的是通过一个简单的状态机将这些状态更改“解析”为所需的用户操作。类似以下内容将起作用。我在其中包括一个用于运行消息循环的布尔值,因为如果您尝试在GUI应用程序中使用它,则整个应用程序在等待键时将冻结。添加消息循环作为练习。扩展此功能以支持双击作为另一项练习。
class KeyListener
{
private:
enum class State {
Preclick,
ClickInProgress,
ClickComplete
};
int vkey_;
State state_;
bool isDown() const
{
return GetAsyncKeyState(vkey_) & 0x8000;
}
State UpdateState()
{
switch (state_) {
case State::Preclick:
state_ = (isDown()) ? State::ClickInProgress : State::Preclick;
break;
case State::ClickInProgress:
state_ = (isDown()) ? State::ClickInProgress : State::ClickComplete;
break;
case State::ClickComplete:
state_ = (isDown()) ? State::ClickInProgress : State::Preclick;
break;
}
return state_;
}
public:
KeyListener(int vkey) : vkey_(vkey)
{
Reset();
}
void Reset()
{
state_ = (!isDown()) ? State::Preclick : State::ClickInProgress;
}
void WaitForClick(bool pump_messages = false)
{
while (UpdateState() != State::ClickComplete)
if (pump_messages) {
// .. put a message loop here.
}
}
};
int main()
{
KeyListener clicky(VK_SPACE);
std::cout << "Try clicking the space bar" << std::endl;
while (true)
{
clicky.WaitForClick();
std::cout << "<Space bar click>" << std::endl;
}
return 0;
}