在我的一個專案中,我需要在非主執行緒中創建一個視窗。我從來沒有這樣做過,所以我沒有太多經驗。
根據MSDN檔案和SO question,我應該能夠在其他執行緒中創建一個視窗,但我不能成功。即使在執行緒啟動例程中,我注冊了一個視窗類,創建了一個視窗并提供了一個訊息回圈,執行緒立即啟動并退出。此外,我無法除錯執行緒啟動例程,因此無法命中其中的斷點。
有什么我想念的嗎?我希望我不會錯過任何愚蠢的事情。
請考慮以下演示。感謝您抽出寶貴的時間。
#include <Windows.h>
#include <tchar.h>
HANDLE hThread;
DWORD WINAPI OtherUIThreadFunc(LPVOID args);
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HWND m_hwnd;
MSG msg;
WNDCLASSEX m_wcx;
const int MESSAGE_PROCESSED = 0;
const TCHAR* m_szClassName = _T("DemoWndCls");
const TCHAR* m_szWindowTitle = _T("Demo Window");
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int nCmdShow)
{
hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)OtherUIThreadFunc, hInstance, 0, NULL);
/*MSG msg;
ZeroMemory(&m_wcx, sizeof(m_wcx));
m_wcx.cbSize = sizeof(m_wcx);
m_wcx.style = CS_VREDRAW | CS_HREDRAW;
m_wcx.hInstance = hInstance;
m_wcx.lpszClassName = m_szClassName;
m_wcx.lpfnWndProc = WndProc;
m_wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
m_wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
m_wcx.hbrBackground = (HBRUSH)COLOR_WINDOW;
if (!RegisterClassEx(&m_wcx))
return false;
m_hwnd = CreateWindowEx(0, m_wcx.lpszClassName, m_szWindowTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 480, 360, NULL, NULL, hInstance, NULL);
if (!m_hwnd)
return false;
ShowWindow(m_hwnd, SW_NORMAL);
UpdateWindow(m_hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;*/
}
DWORD WINAPI OtherUIThreadFunc(LPVOID args)
{
HINSTANCE hInstance = (HINSTANCE)args;
ZeroMemory(&m_wcx, sizeof(m_wcx));
m_wcx.cbSize = sizeof(m_wcx);
m_wcx.style = CS_VREDRAW | CS_HREDRAW;
m_wcx.hInstance = hInstance;
m_wcx.lpszClassName = m_szClassName;
m_wcx.lpfnWndProc = WndProc;
m_wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
m_wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
m_wcx.hbrBackground = (HBRUSH)COLOR_WINDOW;
if (!RegisterClassEx(&m_wcx))
return false;
m_hwnd = CreateWindowEx(0, m_wcx.lpszClassName, m_szWindowTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 480, 360, NULL, NULL, hInstance, NULL);
if (!m_hwnd)
return false;
ShowWindow(m_hwnd, SW_NORMAL);
UpdateWindow(m_hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
return MESSAGE_PROCESSED;
case WM_DESTROY:
PostQuitMessage(0);
return MESSAGE_PROCESSED;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
uj5u.com熱心網友回復:
視窗創建成功(理論上,無論如何)。問題是主執行緒移動一個回傳,這導致運行時終止行程。
要解決此問題,您必須保持主執行緒處于活動狀態。呼叫WaitForSingleObject或訊息回圈是可能的選項。
這主要是遵循 C 和 C 約定的結果。在任何一種情況下,從main函式回傳都等效于呼叫exit()函式。這就解釋了為什么從主執行緒回傳會破壞整個程序。
額外閱讀:如果你從主執行緒回傳,行程是否退出?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/428303.html
