我看到这有很多方法,但从未见过实际的工作代码片段。
我毫无疑问地试图创建一个带有新窗口和消息循环的新线程。我有一个必须打开一个窗口的功能&处理它的消息,并且必须在可以从没有现有消息循环(没有其他窗口)或通常的mfc消息循环或WTL消息循环的应用程序调用它的环境中运行。我看到了一些关于AddMessageLoop和Modules的东西?但它似乎是主要的应用程序。无论如何,那里可能有也可能没有WTL模块。需要一个带有基本消息循环的独立窗口。传入一个尚未打开窗口的WTL类,因此Window在与循环相同的线程中打开。是否还必须在新线程中创建类对象?
// 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);
答案 0 :(得分:0)
请参阅评论以了解所需的更改。 问题#1是&运算符不适用于WTL类 陷阱#2,永远不会命名你的事件。如果您链接未知的其他对象, 可能有人已使用相同的名称,并且Windows决定相同的名称表示相同的事件,即使使用多个CreateEvent()调用。无名, 没有所谓不同事件的“别名”。
非陷阱,如果您不希望“主”消息处理程序处理您的消息,您不需要_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);
答案 1 :(得分:0)
SetWindowLongPtr
和GetWindowLongPtr
,使用这些来从窗口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
在你的窗口过程中:
...
switch(msg)
{
case WM_ACTIVATE:
{
your_instance* inst = (your_instance*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
inst->cv->notify_one();
}
break;
...