簡體   English   中英

C ++ WTL8.1如何在帶有消息循環的新線程中創建窗口?

[英]C++ WTL8.1 How to create a window in a new thread with message loop?

我看到了很多方法,但從未見過實際的工作代碼片段。

我無疑嘗試過這種天真的嘗試,以創建具有新窗口和消息循環的新線程。 我有一個必須打開一個窗口並處理其消息的函數,並且必須在可以從沒有現有消息循環(也沒有其他窗口)的應用程序中調用它的環境中運行,或者沒有通常的mfc消息循環或WTL消息循環。 我看到了一些有關AddMessageLoop和Modules的東西嗎? 但似乎是用於主要應用程序。 無論如何,那里可能沒有WTL模塊。 需要一個帶有基本消息循環的獨立窗口。 傳遞尚未打開window的WTL類,因此Window在與loop相同的線程中打開。 是否也必須在新線程中創建類對象?

// does not work.... 
static DWORD WINAPI MyRunThread(__in LPVOID lpParameter)
{
CMessageLoop theLoop;
WTLsubclass *nav = (WTLsubclass *) lpParameter;

nav->CreateWindow(); 
int nRet = theLoop.Run();

return nRet;
}

CreateThread(0,0,MyRunThread,&nav,0,0);

請參閱注釋以了解所需的更改。 Gotcha#1原為&運算符,不能在WTL類上使用。Gotcha#2,永遠不會為您的事件命名。 如果與未知的其他對象鏈接,則可能是有人已經使用了相同的名稱,即使使用了多個CreateEvent()調用,Windows也會確定相同的名稱表示相同的事件。 沒有名字,沒有所謂的不同事件的“混疊”。

非Gotcha,如果您不希望“主”消息處理程序處理您的消息,則不需要_Module或“講述”有關消息循環的任何內容。 如果您想要具有獨立循環的獨立窗口,請參見下文。

================================================== =

static DWORD WINAPI MyRunThread(__in LPVOID lpParameter)
{
CMessageLoop theLoop;
WTLsubclass *nav = (WTLsubclass *) lpParameter;

nav->CreateWindow(); 
SetEvent(WindowCreatedEvent) // signal event HANDLE type for worker thread

int nRet = theLoop.Run();

return nRet;
}

//CreateThread(0,0,MyRunThread,&nav,0,0); // & wont work on WTL class objects
// some genius overloaded the & operator on WTL class objects, just because in C++ you can

//Workaround to get address of WTL class object
CLASSnav nav[1];
CLASSnav *pnav = nav; // because arrays is address of first element.
CreateThread(0,0,MyRunThread,pnav,0,0);

SetWindowLongPtrGetWindowLongPtr ,使用它們從窗口proc中獲取您的實例,然后在WM_ACTIVATE上設置條件變量。

在您的客戶代碼中:

// Create window, this setups the window and runs a message loop, its guts are ran in a different thread
createwindow();
// Wait to be shown, this presumes the existence of a mutext (m) and a condition_variable (cv) in your instance
std::unique_lock<std::mutex> lock(m);
cv.wait_for(lock, std::chrono::milliseconds(800));

在窗口設置和創建期間,這可以在您的線程proc中:

// Create window (RegisterClass, CreateWindow, etc)
...
SetWindowLongPtr(hwnd, GWLP_USERDATA, /*your instance*/ ...);   
ShowWindow(hwnd, ...);
...
// Pump

在您的窗口proc中:

...
switch(msg)
{
    case WM_ACTIVATE:
    {
        your_instance* inst = (your_instance*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
        inst->cv->notify_one();
    }
    break;
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM