c++visual-c++windows-messagesmessage-loop

Is it possible to create a message loop without creating a window in C++


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.


Solution

  • 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;
    }