none
mfc多线程中创建窗口的问题 RRS feed

  • 问题

  •        MFC程序中不支持在线程中直接创建窗口,要在线程中创建窗口,一种方法是把一个窗口句柄传入线程中,然后需要创建窗口时给这个句柄发自定义消息,在自定义消息响应函数中创建相应的窗口。

           请问这背后的原理是什么?

    前无古人,后无来者

    2017年10月31日 10:23

全部回复

  •  在线程中是可以创建窗口的。比如类似这样的。
    UINT __cdecl ThreadProc(LPVOID lParam)
    {
     RegisterWndClass(...);
     InitializeInstance();
     ShowWindow(...);
     ...
     MSG msg;
     while(GetMessage(&msg, NULL, 0, 0))
     {
       TranslateMessage(&msg);
       DispatchMessage(&msg);
     }
     return 0;
    }


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    • 已建议为答案 Baron Bi 2017年12月12日 7:14
    2017年11月1日 1:41
    版主
  • Hi clever101,

    感谢在MSDN论坛发帖。

    >>MFC程序中不支持在线程中直接创建窗口,要在线程中创建窗口,一种方法是把一个窗口句柄传入线程中,然后需要创建窗口时给这个句柄发自定义消息,在自定义消息响应函数中创建相应的窗口。

    其实并没有不支持的说法,任何线程都可以创建窗口。创建窗口的线程拥有窗口及其关联的消息队列。 因此,线程必须提供单独的消息循环来处理其消息队列中的消息。

    在多线程MFC中,你要理解的是工作线程和UI线程的区别。工作线程通常用于处理用户不必等待继续使用应用程序的后台任务。UI线程通常用于处理用户输入并且独立于执行应用程序的其他部分的线程来响应用户事件。主应用程序线程(在你的CWinApp派生类中提供)已经创建并启动了一个UI线程。创建一个新的UI线程,就可以很方便的在里面进行创建窗口等一系列操作。

    如果你想再创建新的UI线程,你要做的第一件事是从CWinThread派生一个类。使用DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE宏声明并实现此类。具体内容可以参考以下文档。

    https://msdn.microsoft.com/en-us/library/b807sta6.aspx

    希望对你有所帮助。

    Best Regards,

    Sera Yu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    • 已编辑 Baron Bi 2017年11月1日 3:08
    • 已建议为答案 Baron Bi 2017年12月12日 7:14
    2017年11月1日 3:05
  • 什么叫做不支持在线程中直接创建窗口……MFC的Socket支持就是这么做的好吧?不过创建的是顶层窗口就是。

    在父子窗口属于不同线程的时候会出现问题。MFC的CWnd<->HWND映射是每个线程都有一个,一个控件会在其被创建的线程内有映射到控件对应的类,在其他线程都会被映射到一个CTempWnd对象。如果找不到正确的CWnd,CWnd::PreTranslateMessage之类需要映射到正确的控件类的功能会出错。

    另外父子窗口属于不同线程这种设计会有各种各样的鼠标光标、输入焦点、模态对话框堆栈等问题,经常会出现难以诊断的死锁。水平不够的话不建议去踩雷。



    Visual C++ MVP

    • 已建议为答案 Baron Bi 2017年12月12日 7:14
    2017年11月2日 1:15
    版主