如何在控制台应用程序中使用GetMessage()在Windows API中识别C ++中的键盘输入? [英] How can I recognize keyboard input in C++ with Windows API using GetMessage() in a console application?

查看:2355
本文介绍了如何在控制台应用程序中使用GetMessage()在Windows API中识别C ++中的键盘输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先是大图:我在Windows 7(64位)上尝试通过控制台程序同步两个外部设备。也就是说,设备1应该触发设备2.(为了好奇,设备1是NI USB-6525,我正在使用其更改检测功能。)

First the big picture: I'm trying to synchronize two external devices through a console program on Windows 7 (64-bit). That is, Device 1 should trigger Device 2. (For the curious, Device 1 is the NI USB-6525, and I'm using its Change Detection function.)

我在while循环中使用GetMessage()来等待由Device 1触发的消息。(由于我没有为该硬件编写软件,我不能改变我必须阅读此消息的事实。 )读取该消息后,调度。此调度导致对使用设备2执行测量的函数的回调,并将measurementComplete设置为 true 。一旦回调返回,循环结束。然后我执行清理,应用程序退出。

I'm using GetMessage() in a while loop to wait for a message that's triggered by Device 1. (Since I didn't write the software for that hardware, I can't change the fact that I have to read this message.) Once that message is read, it is dispatched. This dispatch results in a callback to a function that performs a measurement using Device 2 and sets measurementComplete to true. Once the callback returns, the loop ends. Then I perform cleanup and the application exits.

问题是,用户还应该能够在等待消息时中止,例如按下一个键。我试图执行检查,以查看接收到的消息是否来自其他线程或键盘,但它从来不识别键盘输入:

The problem is, the user should also be able to abort while waiting for the message, for example by pressing a key. I tried to implement a check to see whether the received message came from the other thread or the keyboard, but it never recognizes keyboard input:

#include <cstdio>
#include <windows.h>

using namespace std;

bool measurementComplete = false;
BOOL bRet = 0;
MSG threadMessage;

signed long __cdecl callbackFunction(type1 param1, type2 param2) // (pseudo args)
{
    measurementComplete = 1;
    performMeasurement();
    return 0;
}

int main (int argc, char* argv[])
{
    /* Load libraries, set up hardware,
       call NI function that looks for signal from Device 1 in separate thread
       and sends a Windows message upon signal detection */

    while (!measurementComplete) { // measurement has not yet been performed
        // wait for message
        puts("Waiting for message.");
        if ((bRet = GetMessage(&threadMessage, NULL, 0, 0)) != 0) { // if message available
            if (bRet == -1) {
                puts("Error: GetMessage() returned -1. The program will now exit.");
                break;
            } else {
                DispatchMessage(&threadMessage);
                if ((TranslateMessage(&threadMessage)) != 0) // if character message (indicates key press)
                    break;
            }
        }
        puts("Message handled.");
    }

/* perform cleanup */
return 0;
}

我是Windows API新手,所以我不熟悉用它。我在Code :: Blocks 13.12 IDE编程,并使用GCC。我没有MFC或任何付费产品喜欢从微软,所以我不能使用MFC函数或类。不幸的是,我发现类似问题的很多答案包括MFC函数。

I'm new to the Windows API, so I'm not that familiar with it. I'm programming in the Code::Blocks 13.12 IDE and using the GCC. I don't have MFC or any paid products like that from Microsoft, so I can't use MFC functions or classes. Unfortunately, many of the answers I found to similar questions included MFC functions.

根据我对这个问题的研究,似乎键盘消息可能没有窗口至。我试图创建一个消息窗口,如描述这里,但我总是得到错误18:没有更多的文件调用CreateWindowEx()。我可以提供该代码,如果要求,但我甚至不确定,我真的需要创建一个窗口。当我运行 FindWindowEx(HWND_MESSAGE,NULL,NULL,NULL); ,我可以看到这样的窗口已经存在。我不知道由该函数找到的窗口是不是以某种方式由我的二进制文件自动创建的窗口,或者它是否是由我的计算机上运行的另一个程序创建的消息窗口。此外,我不是已经有一个窗口(控制台窗口)?

From my research on this issue, it seems that the keyboard messages might not have a window to go to. I tried to create a message-only window such as described here, but I always get Error 18: There are no more files upon calling CreateWindowEx(). I can provide that code if requested, but I'm not even sure that I really need to create a window. When I run FindWindowEx(HWND_MESSAGE, NULL, NULL, NULL);, I can see that such a window already exists. I don't know whether the window that was found by that function is one that was somehow automatically created by my binary or whether it's a message-only window that was created by another program running on my computer. Besides, don't I already have a window (the console window)?

有没有人有任何提示,如何在我的控制台应用程序中的键盘输入消息系统?

Does anyone have any tips for how to direct keyboard input to the messaging system in my console application? Any help would be greatly appreciated.

推荐答案

确实,控制台应用程序没有窗口,因此他们可以'

Indeed, 'console app' does not have a 'window', hence they can't receive any messages (in a easy way).

如果我记得正确,你实际上可以编写代码,用消息泵创建一个不可见的窗口,这样所有的'消息将被分派。 *)

If I remember correctly, you actually can write code that will create an invisible window with message pump, so that all 'messages' will be dispatched. *)

但是,你有很多窗口相关的代码研究,写和mantain。它更容易开始一个Windows应用程序,并在启动时隐藏其窗口。您将从项目代码模板中免费获得所有消息泵代码。从窗口应用程序,你还可以分配和打开控制台窗口,如果你喜欢这种UI风格。

But then, you've got tons of window-related code to research, write and mantain. It's much easier to start with a 'windows app' and hide its window on startup. You will get all the messagepump code for free, from the project code template. From a windowed-app you can also allocate and open a console window, if you like that UI style.

*)你可以开始一个新的窗口应用程序项目和偷看里面看看窗口是如何注册一个wndproc例程来处理消息。在main()代码的某一点上,您将需要执行与空窗口项目执行的操作相同的操作。此外,请记住,您需要实际进入调度循环,并且阻塞您的线程,直到dispatchloop关闭(使用PostQuitMessage等) - 通常当应用程序接近信号(请注意,通常是你的代码必须监听并响应信号,你必须调用 PostQuitMessage 当你决定退出)。

*) You may start a new windowed-app project and peek inside to see how the window is registered with a 'wndproc' routine that will handle the messages. At some point of your main() code, you will need to perform just the same actions that the empty 'windowed' project performs. Also, remember that you will need to actually enter the dispatch loop and that this will block your thread until the dispatchloop is shutdown (with PostQuitMessage, etc) - typically when app gets close "signal" (note that usually it is your code that has to listen and react to that "signals", and you have to call PostQuitMessage when you decide to quit).

你不能逃脱,这里没有魔法!有东西要监听消息。如果您希望邮件通过并且还有一些并行工作,您需要:

You cannot escape that, there is no magic here! Something has to listen for messages. If you want the messages to pass and also have some parallel work, you will need either:


  • 两个线程,一个用于消息泵,一个因为所有的同步都很安全地在它们之间进行通信。

  • 或者,只有一个线程运行消息泵,然后REWRITE THE JOB通过消息与通知异步,所以任何notifs /回调也由messageloop处理

选择你最不喜欢的东西:)

Pick what you dislike the least :)

这篇关于如何在控制台应用程序中使用GetMessage()在Windows API中识别C ++中的键盘输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆