Jump to content
  • Advertisement
Sign in to follow this  

[C++] possible to have win32 message loop on another thread?

This topic is 3011 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi I am just wondering is it possible to have the win32 message loop on another thread. Currently I tried placing the message loop on another thread and use AttachThreadInput(). However when running, the cursor forever stays in the "hourglass" mode and I can't click or do anything. Here is the e.g full code using PPL to create a agent for the message loop
#include <CodeAnalysis\Warnings.h>

#pragma warning(push)
#pragma warning(disable : ALL_CODE_ANALYSIS_WARNINGS)

#include <iostream>
#include <ppl.h>
#include <agents.h>
#include <Windows.h>

LRESULT __stdcall WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
	return DefWindowProc(hwnd, message, wParam, lParam);

class MessageAgent : public Concurrency::agent
	HWND hWindow;

	MessageAgent(HWND hWindow)
		: hWindow(hWindow)

	void run()
		SIZE_T windowThread = GetWindowThreadProcessId(hWindow, nullptr);
		SIZE_T currThread = GetCurrentThreadId();

		std::cout << "Current Thread: " << currThread << "\n";
		std::cout << "Window Thread: " << windowThread << "\n";

		if (AttachThreadInput(currThread, windowThread, TRUE) == FALSE)
			std::cout << "Attach Thread 1 fail\n";

		bool doLoop = true;
		MSG msg;

		while (doLoop)
			while(PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE) != FALSE)
				if (msg.message == WM_QUIT)
					doLoop = false;




int main()
	WNDCLASSEX windowClassEx;

	windowClassEx.cbSize = sizeof(WNDCLASSEX);
	windowClassEx.cbClsExtra = 0;
	windowClassEx.cbWndExtra = 0;
	windowClassEx.style = CS_CLASSDC;
	windowClassEx.hInstance = GetModuleHandle(nullptr);
	windowClassEx.lpfnWndProc = WndProc;
	windowClassEx.lpszMenuName = 0;
	windowClassEx.lpszClassName = L"Window Class Test";
	windowClassEx.hCursor = LoadCursor(nullptr, IDC_ARROW);
	windowClassEx.hIcon = LoadIcon(windowClassEx.hInstance, IDI_APPLICATION);
	windowClassEx.hIconSm = LoadIcon(windowClassEx.hInstance, IDI_APPLICATION);
	windowClassEx.hbrBackground = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));

	if (!RegisterClassEx(&windowClassEx))
		std::cout << "Fail to register window class\n";


	HWND windowHandle = CreateWindowEx(WS_EX_CLIENTEDGE, L"Window Class Test", L"Parallel Window Test",
		windowStyleFlags , 0, 0, 1024, 768, 0, 0, GetModuleHandle(nullptr), nullptr);

	if (windowHandle == nullptr)
		std::cout << "Fail to create window\n";

	ShowWindow(windowHandle, SW_SHOWNORMAL);

	std::cout << "Current Thread: " << GetCurrentThreadId() << "\n";

	MessageAgent msgAgent(windowHandle);

	UnregisterClass(L"Window Class Test", GetModuleHandle(nullptr));

	return 0;

#pragma warning(pop)

Share this post

Link to post
Share on other sites
It is certainly possible to have the message loop in a different thread, but it can be quite painful to do it that way.

I've found it much easier to leave the message loop in the original thread and run the game and rendering in a different thread (create all contexts in that one). Then it's a no brainer.

Share this post

Link to post
Share on other sites
hmm thats possible, but as a learning experience, is there anyway to make it work such that the message loop is on another thread?

I have read up msdn, and most of the articles just suggest attaching the threads input using AttachThreadInput(). But even after doing so the window still get into the "hourglass cursor" mode and become unresponsive.

Share this post

Link to post
Share on other sites
It probably is possible, but when I tried, I ended up hitting the monitor with the keyboard, shouting "fuck, fuck, fuck!", since a lot of Windows GUI functions assume that they are called from the original thread and silently fail if they aren't. Some of them are well-documented, some aren't. That can be super frustrating if you spend 2 days on something so trivial and have no clue just why for heaven's sake it won't work.

On the other hand, spawning off a thread, creating a context there, and doing the rendering in there was as much as 3 minutes of work.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!