【发布时间】:2014-01-15 14:13:02
【问题描述】:
首先是大局:我正在尝试通过 Windows 7(64 位)上的控制台程序同步两个外部设备。也就是说,Device 1 应该触发 Device 2。(好奇的是,Device 1 是 NI USB-6525,我正在使用它的 Change Detection 功能。)
我在 while 循环中使用 GetMessage() 来等待由设备 1 触发的消息。(由于我没有为该硬件编写软件,我无法改变我必须阅读的事实此消息。)一旦读取该消息,它就是dispatched。此分派导致对使用设备 2 执行测量并将measurementComplete 设置为true 的函数进行回调。一旦回调返回,循环结束。然后我执行清理,应用程序退出。
问题是,用户还应该能够在等待消息时中止,例如通过按键。我尝试检查接收到的消息是来自其他线程还是来自键盘,但它永远无法识别键盘输入:
#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 或任何类似 Microsoft 的付费产品,所以我不能使用 MFC 函数或类。不幸的是,我发现的许多类似问题的答案都包含 MFC 函数。
根据我对这个问题的研究,键盘消息似乎没有可以访问的窗口。我尝试创建一个仅消息窗口,例如描述的here,但在调用 CreateWindowEx() 时我总是得到Error 18: There are no more files。如果需要,我可以提供该代码,但我什至不确定我是否真的需要创建一个窗口。当我运行FindWindowEx(HWND_MESSAGE, NULL, NULL, NULL); 时,我可以看到这样一个窗口已经存在。我不知道该函数找到的窗口是否是由我的二进制文件以某种方式自动创建的窗口,或者它是否是由我计算机上运行的另一个程序创建的仅消息窗口。另外,我不是已经有一个窗口(控制台窗口)了吗?
关于如何在我的控制台应用程序中将键盘输入定向到消息传递系统,是否有人有任何提示?任何帮助将不胜感激。
【问题讨论】:
-
这是不可能的。控制台窗口由一个完全不同的可执行文件管理,你不能乱用它。使用 ReadConsoleInput() 或 _getch()。
-
@HansPassant:为什么不回答?仅仅两行的解释和提示仍然是完全有效的答案,即使这么短;)
-
您好,感谢您的回复。不幸的是,GetMessage() 是一个阻塞函数,所以我想对信号事件或使用该函数的按键做出反应。我可以在循环中使用 PeekMessage() 代替,但那样我会忙于闲置。我可以在那个循环中暂停一段时间,但立即检测信号消息是我同步的关键。我现在明白我将无法检测到控制台窗口的输入;那么为此目的创建我自己的(仅消息)窗口会更有意义吗?或者有没有其他我没有考虑过的处理方式?
-
@HansPassant 那么,
kbhit()和PeekMessage()? (或者使用普通消息泵切换到 Windows 可执行文件?)
标签: c++ windows winapi console