Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 关于在没有WndProc的情况下运行win32事件循环的另一种方式的想法?_C++_Windows_Multithreading_Winapi_Event Loop - Fatal编程技术网

C++ 关于在没有WndProc的情况下运行win32事件循环的另一种方式的想法?

C++ 关于在没有WndProc的情况下运行win32事件循环的另一种方式的想法?,c++,windows,multithreading,winapi,event-loop,C++,Windows,Multithreading,Winapi,Event Loop,在处理多线程、回调、win32 api函数和其他麻烦时,我收到了一个idea事件。(呵呵) 如果在注册窗口类时,我没有定义全局(或在设计类时定义静态)回调函数,而是为lpfnWndProc分配了DefWindowProc,然后在单独的线程上运行整个事件循环,会怎么样 这样我就不必在遇到这个问题时就进行破解了 主线程继续执行,将您从while循环中解放出来,允许您做任何事情,甚至打开另一个窗口(耶!) “正常”方式: LRESULT回调WndProc(…) { …//处理事件信息 返回DefWin

在处理多线程、回调、win32 api函数和其他麻烦时,我收到了一个idea事件。(呵呵)

如果在注册窗口类时,我没有定义全局(或在设计类时定义静态)回调函数,而是为
lpfnWndProc
分配了
DefWindowProc
,然后在单独的线程上运行整个事件循环,会怎么样

这样我就不必在遇到
这个
问题时就进行破解了
主线程继续执行,将您从while循环中解放出来,允许您做任何事情,甚至打开另一个窗口(耶!)

“正常”方式:

LRESULT回调WndProc(…)
{
…//处理事件信息
返回DefWindowProc(…);
}
int回调WinMain(…)
{
…//初始化需要初始化的内容:)
WNDCLASSEX wc;
...
wc.lpfnWndProc=WndProc;
…//注册类、创建窗口等。。。
味精;
while(GetMessage(&msg,0,0)!=0)
{
…//TranslateMessage(&msg)如果您想要/需要它
DispatchMessage(&msg);//将消息分派给WndProc
}
返回静态_cast(msg.wParam);
}
我新发现的很棒的方式:

DWORD WINAPI MyAwesomeEventLoop(void*data)//在类中必须是静态的
{
…//对数据做任何需要的事情
味精;
while(GetMessage(&msg,0,0)!=0)
{
…//TranslateMessage(&msg)如果您想要/需要它
…//处理事件信息
//调用PostQuitMessage(0)以离开循环
}
返回静态_cast(msg.wParam);
}
int回调WndProc(…)
{
...
WNDCLASSEX wc;
...
wc.lpfnWndProc=DefWindowProc;
...
HANDLE-threadHandle=0;
//在类中实现时,使用“this”作为第四个参数
threadHandle=CreateThread(0,0,MyAwesomeEventLoop,0,0);
…//你现在可以随心所欲了!:)
//等待线程完成
//希望是因为调用了PostQuitMessage(0)
WaitForSingleObject(线程句柄,无限);
DWORD返回值=0;
GetExitCodeThread(threadHandle和returnValue);
闭柄(螺纹柄);
...
返回静态_cast(返回值);
}

你们觉得怎么样?

这并不能给你们带来任何好处,除非现在在通用事件循环中有特定于窗口类的事件处理代码,这很难看。如果需要后台工作,请使用辅助线程。将GUI和事件反应器保留在主线程中,并使用文档中描述的回调


如果您有一个实例处理windows的类,则即使在单线程代码中,也不应将其设置为全局的(否则您将在将来遭受痛苦的重构)。

获取MSDN上的消息文档:

阅读第一句话:“从调用线程的消息队列中检索消息。”


窗口的消息队列绑定到创建它的线程。由于您在主线程上创建了窗口,因此在新线程上运行的事件循环将不会收到该窗口的任何消息。如果要在另一个线程上运行事件循环,则需要先创建线程,然后在该线程上创建窗口。

例如,它们是全局的。为什么泛型事件循环难看?@acpluspluscoder:包含非泛型代码的泛型事件循环难看。如果它们不是全局性的,那么您使用的是
(Get/Set)WindowLongPtr
,所以我不明白您所说的“我不必绕过
这个问题”
是什么意思。好主意应该被执行,而不是被批评。您可能已经了解了有关Windows体系结构的一些重要内容,消息队列具有线程关联性。您的GetMessage()调用从未收到消息。这些类型的querstiosn实际上不适合StackOverflow。试试吧。投票赞成使用while
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);
}
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);
 }