等到释放钥匙

时间:2019-05-11 16:32:16

标签: c++ winapi

我想做到这一点,以使我的程序在发布ALT之前不会继续,因此我可以切换bool,而无需无限循环遍历if(istrue / isfalse)。

这是我的尝试

        for (;;) {
    if (GetAsyncKeyState(VK_MENU))
    {
        TPSWITCH = !TPSWITCH;   
    }
    else
    {
        continue;
    }
}

2 个答案:

答案 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;
}