C++ WTL8.1 如何在具有消息循环的新线程中创建窗口
C++ WTL8.1 How to create a window in a new thread with message loop?
我看到这问了很多方法,但从未见过实际的工作代码截图。
我尝试过这个无疑是天真的尝试创建一个具有新窗口和消息循环的新线程。我有一个函数,它必须打开一个窗口并处理其消息,并且必须在可以从没有现有消息循环(也没有其他窗口)或通常的 mfc 消息循环或 WTL 消息循环的应用程序调用它的环境中运行。我看到了一些关于AddMessageLoop和Modules的东西?但这似乎是针对主要应用程序的。在任何情况下,那里可能有也可能没有 WTL 模块。需要一个具有基本消息循环的独立窗口。传入窗口尚未打开的 WTL 类,因此窗口在与循环相同的线程中打开。是否还必须在新线程中创建类对象?
// 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);
有关需要更改的内容,请参阅注释。陷阱 #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);
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));
在窗口设置和创建过程中,这可以在您的线程进程中:
// 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;
...
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 在C++中使用cURL和多线程
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在cuda线程之间共享大量常量数据
- 多线程:线程或进程.h - C++
- BOOST线程:线程还是进程
- 如何在线程线程内部制作内存?
- C++ - 多线程 - 线程之间的通信
- C++多线程:线程安全的内存分配
- 如何在 Linux 上强制 g++ 在协程切换线程时更新线程指针(对于 TLS)
- 如何确定流程的"经理"和"工作线程"线程的优先级(或为其设置调度策略)?
- 一旦另一个线程完成,就会生成一个新线程
- 是boost::线程线程安全的
- c++多线程-线程安全的代码
- 依靠额外的线程-线程安全
- Linux多线程——线程不会产生任何预期的输出
- 线程-线程创建问题
- 只在前一个线程完成时创建一个新线程
- 创建新线程时在lambda内部使用unique_ptr的线程安全性