Windows:子線程中創建窗口


一般來講,UI的所有操作都必須在主線程,否則會出現未知錯誤。但有時候我們會需要一個功能比較單一的窗口,同時希望他在一個單獨的線程運行。並不影響主線程的效率。

下面說明一下新建子線程創建的新窗口的方法,關鍵在於在子線程中,有一套自己的事件循環機制,即可脫離主線程單獨運行

LRESULT CALLBACK WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
	return DefWindowProc(hWnd, wMsg, wParam, lParam);
}

void CreateWndInThread(int nWidth, int nHeight)
{
	WNDCLASSEXA wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = GetModuleHandle(nullptr);
	wcex.hIcon = 0;
	wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszMenuName = NULL;

	char cName[MAX_PATH] = { 0 };
	GetModuleFileNameA(wcex.hInstance, cName, sizeof(cName));
	char* szApp = strrchr(cName, '\\') + 1;
	strchr(szApp, '.')[0] = '\0';

	wcex.lpszClassName = szApp;
	wcex.hIconSm = 0;
	RegisterClassExA(&wcex);

	g_hWnd = CreateWindowA(szApp, nullptr, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, nWidth, nHeight, NULL, NULL, wcex.hInstance, 0);

	ShowWindow(g_hWnd, SW_SHOW);
	UpdateWindow(g_hWnd);

	MSG msg;
	while (GetMessage(&msg, nullptr, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
}

  其實基本就是模擬win sdk創建窗口的方式,只是將整個動作包含到一個線程里而已

std::thread t(CreateWndInThread, 960, 480);
t.detach();

  在需要的時候,啟動一個線程,執行創建,這個線程在while (GetMessage(&msg, nullptr, 0, 0))的循環中負責處理這個子線程窗口的事件循環即可

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM