• [MFC]关于Visual studio 2012的AfxGetMainWnd


    在MSDN上对AfxGetMainWnd的解释是如果OLE服务器有一个对象在某个容器中激活且这个容器也是激活的(有点拗口),这个函数返回容纳激活文档的框架窗口对象。如果没有本地激活对象或者应用程序不是一个OLE的服务器,这个函数简单返回应用对象CWinApplication的m_pMainWnd。如果AfxGetMainWnd在主线程中调用得到的是应用程序的主窗口,如果是在第二个线程中调用的得到的是和这个线程关联的主窗口。

    实际上并非这么简单,在一个动态加载的MFC常规DLL内部函数中调用这个函数可能会得到不同的结果,如果DLL中没有创建任何窗口,得到的会是主程序的主窗口,但是如果有创建窗口比如弹出一个模式对话框,在对话框的某个函数中调用AfxGetMainWnd就会得到这个对话框的窗口对象。具体的还是来看看这个函数是如何实现的吧。

    _AFXWIN_INLINE CWnd* AFXAPI AfxGetMainWnd()
        { CWinThread* pThread = AfxGetThread();
            return pThread != NULL ? pThread->GetMainWnd() : NULL; }
    
    CWinThread* AFXAPI AfxGetThread()
    {
        // check for current thread in module thread state
        AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
        CWinThread* pThread = pState->m_pCurrentWinThread;
        return pThread;
    }
    
    AFX_MODULE_THREAD_STATE* AFXAPI AfxGetModuleThreadState()
    {
        AFX_MODULE_THREAD_STATE* pResult=AfxGetModuleState()->m_thread.GetData();
        ENSURE(pResult != NULL);
        return pResult;
    }
    
    CWnd* CWinThread::GetMainWnd()
    {
        if (m_pActiveWnd != NULL)
            return m_pActiveWnd;    // probably in-place active
    
        // when not inplace active, just return main window
        if (m_pMainWnd != NULL)
            return m_pMainWnd;
    
        return CWnd::GetActiveWindow();
    }

    这里首先是取得当前的CWinThread对象,它是AFX_MODULE_THREAD_STATE的成员变量m_pCurrentWinThread,而AFX_MODULE_THREAD_STATE又是通过AfxGetModuleThreadState()函数得到的,它调用了AfxGetModuleState()函数,而说到AfxGetModuleState()我们必须讲到AFX_MANAGE_STATE(AfxGetStaticModuleState()),在DLL中导出一个函数时,这个函数的第一句我们一般都会调用AFX_MANAGE_STATE(AfxGetStaticModuleState()),它的作用就是切换模块相关的状态对象,这个状态对象包含了当前线程

    CThreadLocal<AFX_MODULE_THREAD_STATE>、当前应用CWinApp等信息,这些信息都是保存在线程TLS中的。因此在进入DLL中我们可能使用AFX_MANAGE_STATE(AfxGetStaticModuleState())切换了模块状态,自然得到和主程序模块不同的CWinThread对象。

    再来看CWinThread::GetMainWnd(),这和MSDN的解释差不多,如果有OLE激活对象返回激活窗口,没有就返回线程对象的主窗口,如果这个还为空,就获得当前应用程序的当前激活窗口,这个就实在说不定是那个窗口了,我们前面例子中说的DLL弹出模式对话框,自然就会得到这个模式对话框的窗口对象了,所以如果我们要在DLL中使用主程序框架窗口对象的化最好是从参数传入保存在DLL中吧。

    关于MODULE STATE有很多的文章介绍了,比如这篇:http://hi.baidu.com/rootlife/blog/item/2f37e354ad8cdc5bd10906be.html,讲得还是比较清楚的。

  • 相关阅读:
    计算机中如何表示数字-01机器数与真值
    计算机中如何表示数字-06浮点数
    Java基础类型与其二进制表示
    char类型与Unicode的编码
    数组的详细总结
    Java中的instanceof关键字
    java 启动多线程
    elasticsearch7.2 集群搭建 插件安装 和kibana安装
    java读取 properties配置文件的两种方式
    查询mysql 库和表占的大小
  • 原文地址:https://www.cnblogs.com/duanshuiliu/p/2629678.html
Copyright © 2020-2023  润新知