|
MFC在每个线程里面,保存了一些只跟线程相关的变量。MFC在两个地方用到了TLS: THREAD_LOCAL(_AFX_THREAD_STATE, _afxThreadState)//在afxstate.cpp中,全局变量 CThreadLocal<AFX_MODULE_THREAD_STATE> m_thread;//在类AFX_MODULE_STATE中的成员变量
其实这两个变量都是通过template<class TYPE> CThreadLocal来定义的,类型分别是_AFX_THREAD_STATE和AFX_MODULE_THREAD_STATE。它们的关系如下:
从thread到module又到thread的,有点搞,下面的示意图是我自己的理解:
对于thread1而言,它需要在不同的module之间切换,所有它有Previous module和当前module的指针,MFC利用它来准确的获得资源的hinstance。而对于user.dll来说,它是可以被不同的process载入的,所以它也要在不同的thread中保存自己的信息。 我们来看一下为什么MFC要把这些变量保存在tls中。 _AFX_THREAD_STATE里面还没有仔细研究 ;-( AFX_MODULE_THREAD_STATE中: class AFX_MODULE_THREAD_STATE : public CNoTrackObject { // list of CFrameWnd objects for thread CTypedSimpleList<CFrameWnd*> m_frameList; //(1)主要是为了执行OnIdle // temporary/permanent map state CHandleMap* m_pmapHWND;//(2)HWND属于创建这个HWND的线程 CHandleMap* m_pmapHMENU; CHandleMap* m_pmapHDC; CHandleMap* m_pmapHGDIOBJ; CHandleMap* m_pmapHIMAGELIST; // common controls thread state CToolTipCtrl* m_pToolTip; CWnd* m_pLastHit; // last window to own tooltip INT_PTR m_nLastHit; // last hittest code TOOLINFO* m_pLastInfo; // last TOOLINFO structure INT_PTR m_nLastStatus; // last flyby status message CControlBar* m_pLastStatus; // last flyby status control bar }; (1)消息循环是一个thread一个,所有OnIdle也是一个消息循环一个,然后里面把当前thread创建的所有framewnd遍历一边来执行OnIdle。 (2)中是HWND到CWnd*的映射,这个在TLS内。这也是不同线程间不能传递CWnd*的原因。 很复杂;-(
|