c++ - 是否可以在不使用 C++ 创建窗口的情况下创建消息循环
问题描述
我正在使用一些蓝牙库和一些蓝牙回调,有必要使用 Windows 消息循环。但根据我的要求,我需要创建一个没有任何 GUI 的普通 C++ 程序。是否可以在没有窗口的情况下创建消息循环?
main(){
Discovery disc;
disc.startDiscovery();
}
Discovery::startDiscovery(){
__hook(&CallBackFromLibrary::OnDiscoveryStarted, &obj, &Discovery::OnDiscoveryStarted);
__hook(&CallBackFromLibrary::OnDiscoveryComplete, &obj, &Discovery::OnDiscoveryComplete);
}
apiObject.discoverBluetoothDevices();
在此示例代码中,我应该在调用 apiObject.discoverBluetoothDevices() 后收到回调为 OnDiscoveryStarted 和 OnDiscoveryComplete。
由于他们使用消息循环进行回调,所以我只在 GUI 应用程序上得到了回调。如何使用消息循环接收回调,因为库文档说需要消息循环。
解决方案
是的,这是可能的——当/如果线程尝试使用一个消息队列时,Windows 会将消息队列与一个线程相关联。但是,这样做时会有一点竞争条件。要发布到线程的消息队列,请使用PostThreadMessage
. 但是,在线程调用函数尝试从消息队列中读取之前,线程不会有消息队列(即,Windows 不会为线程创建消息队列,直到线程尝试使用它)。
为了防止竞争条件,您通常希望按此顺序执行某些操作:
- cal CreateEvent 创建一个事件(无信号)
- call
CreateThread
,将要传递给新线程的事件句柄传递给它 - 让父母等待事件
- 让孩子调用
PeekMessage
(不期待任何结果,因为尚未创建队列 - 但这会强制创建它)。 - 让孩子发出事件信号
- 现在父母将恢复,并且可以使用
PostThreadMessage
,安全的“知识”,孩子有一个消息队列,所以这将起作用。
另一种可能性是让孩子创建一个窗口,但将其隐藏。这里的明显优势是与期望使用SendMessage
, PostMessage
,SendMessageTimeout
等而不是特殊的PostThreadMessage
. 另一个明显的优点是它避免了上面概述的线程-消息-队列舞。
当您深入了解它时,Windows“窗口”的主要特征不是显示器上的东西——它是一个消息队列,显示器上显示的只是为响应某些特定消息而完成的绘图。隐藏的窗口不仅仅是一个消息队列。
推荐阅读
- python - 重塑(n 行 xn 列)python 列表到 pandas DataFame
- php - 将 PEM 格式的公钥传递给 openssl_pkey_get_public 会给出错误:0906D06C:PEM 例程:PEM_read_bio:no start line
- c++ - 如何将节点存储在数组 C++ 中?
- php - @ORM\ManyToOne(试图将对象而不是 int 值填充到列中的学说)
- javascript - 如何在 Node 的 Express Router 中使用两个或多个 route.js 文件?
- google-apps-script - 用于创建具有可见值的过滤器的 Google 表格脚本
- postgresql - 使用 PostgreSQL 创建类别树层次结构
- javascript - 如何在 Gatsby 中创建无边 graphql 元素?
- python - Amazon SageMaker 软最大标签必须在 [0, num_class)
- git - Pycharm,git:从master合并到分支