I was working with some Bluetooth library and for some Bluetooth callback, it is necessary to use Windows message loop. But as per my requirement, I need to create a normal C++ program without any GUI. Is it possible to create a message loop without a window?
main(){
Discovery disc;
disc.startDiscovery();
}
Discovery::startDiscovery(){
__hook(&CallBackFromLibrary::OnDiscoveryStarted, &obj, &Discovery::OnDiscoveryStarted);
__hook(&CallBackFromLibrary::OnDiscoveryComplete, &obj, &Discovery::OnDiscoveryComplete);
}
apiObject.discoverBluetoothDevices();
In this sample code, I should receive callbacks as OnDiscoveryStarted and OnDiscoveryComplete after calling apiObject.discoverBluetoothDevices().
Since they are using message loops for callbacks, I only got the callback on GUI application. How to receive the callback using message loops as the library documentation says message loops are required.
Yes, it's possible--Windows will associate a message queue with a thread when/if the thread tries to use one. There is a little bit of a race condition when doing this though. To post to the thread's message queue, you use PostThreadMessage
. But, the thread won't have a message queue until it calls a function to attempt to read from the message queue (ie, Windows doesn't create a message queue for the thread until the thread tries to use it).
To prevent a race condition, you usually want to do something on this order:
CreateThread
, passing it the handle of the event to be passed to the new threadPeekMessage
(not expecting any result, since the queue hasn't been created yet--but this forces its creation).PostThreadMessage
, secure in the "knowledge" that the child has a message queue, so this will work. Another possibility is for the child to create a window, but leave it hidden. The obvious advantage here is compatibility with code that expects to post/send messages to a normal message queue using SendMessage
, PostMessage
, SendMessageTimeout
, and so on, instead of the special PostThreadMessage
. The other obvious advantage is that it avoids the thread-message-queue dance outlined above.
When you get down to it, the primary characteristic of a Windows "window" isn't something on the display--it's a message queue, and what shows up on the display is just drawing that's done in response to some specific messages. A hidden window isn't a whole lot more than a message queue.
Message loop in non-GUI thread:
#include "stdafx.h"
#include <Windows.h>
#include <thread>
#include <iostream>
using namespace std;
void ThreadFunction()
{
MSG msg;
BOOL result;
for (;;)
{
result = GetMessage(&msg, nullptr, 0, 0);
if (result <= 0)
{
break;
}
cout << msg.message << " " << msg.wParam << " " << msg.lParam << endl;
//TranslateMessage(&msg);
//DispatchMessage(&msg);
}
}
int main()
{
thread t(ThreadFunction);
HANDLE h = t.native_handle();
DWORD dw = GetThreadId(h);
PostThreadMessage(dw, WM_APP + 1, 1, 2);
PostThreadMessage(dw, WM_APP + 2, 10, 20);
PostThreadMessage(dw, WM_QUIT, 10, 20);
t.join();
return 0;
}
Update :
According to the comment, this code is not compiled in gcc. Trying to reproduce this in VC++, I found that the program doesn't work in x64. This updated solution hopefully solves both problems:
#include "stdafx.h"
#include <Windows.h>
#include <thread>
#include <iostream>
using namespace std;
DWORD threadID{};
void ThreadFunction(HANDLE event_handle)
{
MSG msg;
BOOL result;
threadID = GetCurrentThreadId();
SetEvent(event_handle);
for (;;)
{
result = GetMessage(&msg, nullptr, 0, 0);
if (result <= 0)
{
break;
}
cout << msg.message << " " << msg.wParam << " " << msg.lParam << endl;
}
}
int main()
{
HANDLE e = CreateEvent(nullptr, FALSE, FALSE, nullptr);
thread t(ThreadFunction, e);
WaitForSingleObject(e, INFINITE);
CloseHandle(e);
PostThreadMessage(threadID, WM_APP + 1, 1, 2);
PostThreadMessage(threadID, WM_APP + 2, 10, 20);
PostThreadMessage(threadID, WM_QUIT, 10, 20);
t.join();
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.