acp*_*der 5 c++ windows winapi multithreading event-loop
在搞乱多线程,回调,win32 api功能以及其他麻烦的问题时,我收到了一个想法事件.(呵呵呵)
如果,而不是(设计一个类时或静态)回调函数定义一个全球性的,而不是我指派DefWindowProc为lpfnWndProc注册窗口类的时候,然后运行在一个单独的线程整个事件循环?
这样我就不必在类中实现回调this时解决问题,
并且主线程的执行继续进行,让你从那个被遗忘的循环中解放出来,允许你做任何事情,甚至打开另一个窗口(耶!)
"正常"方式:
LRESULT CALLBACK WndProc(...)
{
... // process event information
return DefWindowProc(...);
}
int CALLBACK WinMain(...)
{
... // initialize whatever needs initializing :)
WNDCLASSEX wc;
...
wc.lpfnWndProc = WndProc;
... // register the class, create the window, etc...
MSG msg;
while(GetMessage(&msg, 0, 0, 0) != 0)
{
... // TranslateMessage(&msg) if you want/need it
DispatchMessage(&msg); // dispatches the message to WndProc
}
return static_cast<int>(msg.wParam);
}
Run Code Online (Sandbox Code Playgroud)
我新发现的令人敬畏的方式:
DWORD WINAPI MyAwesomeEventLoop(void* data) // must be static in a class
{
... // do whatever you need with the data
MSG msg;
while(GetMessage(&msg, 0, 0, 0) != 0)
{
... // TranslateMessage(&msg) if you want/need it
... // process event information
// call PostQuitMessage(0) to leave the loop
}
return static_cast<DWORD>(msg.wParam);
}
int CALLBACK WndProc(...)
{
...
WNDCLASSEX wc;
...
wc.lpfnWndProc = DefWindowProc;
...
HANDLE threadHandle = 0;
// use "this" as the 4th parameter when implementing in a class
threadHandle = CreateThread(0, 0, MyAwesomeEventLoop, 0, 0, 0);
... // you are now free to do whatever you want! :)
// waits untill the thread finishes
// hopefully because PostQuitMessage(0) was called
WaitForSingleObject(threadHandle, INFINITE);
DWORD returnValue = 0;
GetExitCodeThread(threadHandle, &returnValue);
CloseHandle(threadHandle);
...
return static_cast<int>(returnValue);
}
Run Code Online (Sandbox Code Playgroud)
你们有什么感想?
小智 13
MSDN上的GetMessage文档:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644936(v=vs.85).aspx
阅读第一句话:"从调用线程的消息队列中检索消息."
窗口的消息队列与创建它的线程相关联.由于您在主线程上创建了窗口,因此在新线程上运行的事件循环将不会收到该窗口的任何消息.如果要在另一个线程上运行事件循环,则需要先创建线程,然后在该线程上创建窗口.
这并没有真正给你带来任何好处,除了现在你在通用事件循环中拥有特定于窗口类的事件处理代码,这实在是丑陋。如果需要后台工作,请使用工作线程。将 GUI 和事件反应器保留在主线程内,并按照文档使用回调。
如果您有一个实例处理窗口的类,那么即使在单线程代码中也不应该将它们设置为全局(否则将来您将遭受痛苦的重构)。
| 归档时间: |
|
| 查看次数: |
4175 次 |
| 最近记录: |