如何在Windows上使用C ++访问低级硬件I / O功能?

时间:2015-09-03 19:03:30

标签: c++ input

我正在用C ++编写游戏,我需要检测用户何时按下某个键。通常,我会使用std::cin,但我有一个图形窗口,使用graphics.h,这是一个最初由古老的Borland Turbo C ++编译器提供的标题,但在线提供了相应的标题。所以,我会使用函数inportb();,函数定义如下:

inline unsigned char inportb(unsigned int port) {
    unsigned char ret;
    asm volatile ("inb %%dx,%%al":"=a"(ret):"d"(port));
    return ret;
}

来源:inportb

但在Windows中,像这样的直接低级硬件I / O受到保护,如果尝试,则该程序将被终止。所以我需要通过高级函数或API来访问该函数。

我的问题:我该怎么做?

3 个答案:

答案 0 :(得分:6)

如果您试图在游戏循环中间检测特定键的状态,GetAsyncKeyState将确定当时的特定状态。

if (GetAsyncKeyState(VK_LEFT) & 0x8000) != 0u)
{
    // ...
}

此函数采用virtual key代码(在本例中为左箭头键),获取状态,并在按位AND操作后确定密钥是否已关闭,然后关闭。

这些virtual key代码可以在WinUser.h中找到。 GetAsyncKeyStateGetKeyState的不同之处在于GetKeyState不反映与硬件相关的中断级状态(这就是我上面使用GetAsyncKeyState的原因)。如果您需要给定实例的所有关键状态(很少见),请考虑GetKeybardState

但是,如果您要等待关键事件(WM_KEYDOWNWM_CHARWM_KEYUP),则必须在window procedure中提供一个案例来处理事件

LRESULT WindowProc(UINT const message, WPARAM const wparam, LPARAM const lparam)
{
    switch(message)
    {

    // [ cases like WM_CREATE / WM_PAINT / WM_CLOSE / WM_DESTROY ]

    case WM_KEYDOWN:
        // handle event here
        break;

    case WM_CHAR:
        // handle event here
        break;

    case WM_KEYUP:
        // handle event here
        break;
    }
}

希望这有帮助。

答案 1 :(得分:2)

在Windows中有4种不同的方法可以检测输入。

  1. GetInputState ()(及其周围的API)(假设您不必支持Windows XP或更低版本)
  2. 您可以使用 GetKeyState ()(及其周围的API)进行投票,但您必须为要检查的每个键进行投票。您可以使用GetInputState()检查是否有任何值得检查的内容,如果有太多的密钥需要轮询。
  3. GetRawInputData ()(及其周围的API)。这将在XP中工作,但它是一个更丑陋的界面。此外,它只会输入连接到机器的实际硬件。因此,如果您远程会话进入Windows机器,它可能无法正常工作。您还需要了解哪些原始设备连接到系统,找出它们何时连接并找出它们何时分离。这个(RawInput)API支持所有这些,因此在编写游戏时你可能会玩得很开心。
  4. 挂钩函数,它允许您注册在发生输入事件时调用的回调。钩子注册了 SetWindowsHookEx ()(以及周围的API)。这是检测按键的最有效但最不可靠的方法。一些程序可以为相同的事件设置挂钩,并且API期望每个回调足够快地返回,以便其他注册者也可以立即得到通知。如果你甚至没有足够快地返回,你将不会被告知,但你的钩子函数将不再被调用......即使你取消注册回调并再次注册它们也不会。让这些工作,并在没有用户干预的情况下继续工作,是优秀键盘记录器的真正艺术出现的地方。

答案 2 :(得分:1)

几十年前我对Turbo C ++很开心:-)但如果我是你,我会尝试使用除C编译器之外的游戏引擎或lib,例如此SDL或Ogre(请参阅{ {3}}对于太长的清单而言。)

它们提供(除其他外)具有键盘事件的事件循环。

或者更少,您可能希望使用Windows或跨平台框架,例如Microsoft提供的MSVC(可以免费使用)或Qt(更加免费,现在附带一个方便的IDE)

玩得开心,给别人带来乐趣!