2

当我有:

MessageBox(NULL, NULL , "MessageBox", NULL);

出现一个消息框,我的程序按我的意愿运行,直到用户在消息框上单击确定,然后程序结束。我试图放入一个无限循环以获得相同的效果,但这与消息框的工作方式不同。我不想要消息框的原因是它阻碍了用户对程序的查看,如果他们试图关闭它,程序就会停止。所以我基本上只是想要一个不可见的消息框或具有相同效果的东西。

编辑:澄清一下,该程序是游戏的原型。我正在使用挂钩来查找用户正在按下的键。这是该程序的简化版本:

#define WM_KEYDOWN                      0x0100
#define _WIN32_WINNT 0x0500

#include <iostream>
#include <windows.h>
#include <winuser.h>

using namespace std;

LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam){


PKBDLLHOOKSTRUCT keypointer = (PKBDLLHOOKSTRUCT)(lParam);
if (wParam==WM_KEYDOWN){

    switch(keypointer->vkCode){


        case VK_RIGHT:
            cout << "**RIGHT**";
            goto skip;
        case VK_LEFT:
            cout << "**LEFT**";
            goto skip;
        case VK_DOWN:
            cout << "**DOWN**";
            goto skip;
        case VK_UP: 
            cout << "**UP**";
        skip:
        default:
            cout << "";
    }
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {


SetWindowsHookEx(WH_KEYBOARD_LL, HookProc, hInstance, 0);

MessageBox(NULL, NULL , "KLMBOX", NULL);

return 0;

}

我只希望程序具有相同的功能,但不显示消息框!我不是专家,我只是在玩弄:http: //msdn.microsoft.com/en-us/library/windows/desktop/ms632589 (v=vs.85).aspx

4

3 回答 3

5

听起来您正在寻找的是一个消息循环MessageBox()这里有两件事:它显示对话框,但它还在内部提供自己的消息循环来处理对话框的输入。低级挂钩需要消息循环才能正常工作,而您的代码与 MessageBox 一起工作只是因为它提供的消息循环正在为您进行必要的消息处理。这就是为什么普通的无限循环不能作为替代品的原因——它没有适当地处理消息。

这是一个简单的,你可以剪切和粘贴:

MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

当您在代码中的其他位置(但仍在同一个线程上)决定要退出时 - 也许当您在挂钩中检测到某些组合键时 - 使用PostQuitMessage();这会将 WM_QUIT 消息发布到线程的队列中,当 GetMessage 检索到该消息时,它将返回 0 并且循环将退出。


说了这么多,首先这不是编写游戏的好方法。低级键盘钩子是矫枉过正的,在这里并不合适。如果您想在 Windows 应用程序中获取键盘输入,最简单的做法是创建您自己的窗口,它会在按键被按下/释放时接收 WM_KEYDOWN/UP 消息。

于 2012-02-09T23:02:18.327 回答
2

使用您的代码示例,看起来您正在尝试制作游戏,但结构完全错误。游戏通常有一个主循环,每次迭代检查输入,更新游戏状态,然后渲染。如果这是您想要的,我建议您查看现有的众多开放游戏引擎之一,并尝试一些输入教程。OGRE 3d 可能是一个很好的起点、良好的社区和良好的教程。

但是,如果这不是您想要的并且您确实想玩钩子,您将需要创建一个不同的线程。如果您创建一个无限循环,系统将永远无法处理挂钩。

做你想做的最简单的方法可能是打开一个窗口并使其不可见。使用您现在正在使用的原始 win32 API 创建一个窗口涉及到并且需要大量代码来完成。这是一个解释所涉及步骤的教程。

但同样,如果你想制作一个简单的游戏,我建议利用现有的引擎。那样你会取得更快的进步。祝你好运!

于 2012-02-09T18:45:16.573 回答
0

我不明白...你要不要消息框?如果不是,为什么要调用 MessageBox()?我相信消息框是模态的,这意味着用户必须以某种方式确认它(单击确定/取消),然后才能返回父界面。我相信它也是阻塞的,这意味着它不会在单独的线程上运行,并且会阻塞调用它的线程的执行,直到用户关闭它。

您的应用程序不应仅仅因为用户关闭消息框而关闭,除非您是这样专门编写的。我需要更多信息和可能的代码示例来告诉你为什么会发生这种情况,如果它是无意的。

于 2012-02-09T17:16:27.930 回答