?? mfc教程9.htm
字號:
<P align=justify>_AFX_BASE_MODULE_STATE() : AFX_MODULE_STATE(TRUE,</P>
<P align=justify>AfxWndProcBase, _MFC_VER)</P>
<P align=justify>#else</P>
<P align=justify>_AFX_BASE_MODULE_STATE() : AFX_MODULE_STATE(TRUE)</P>
<P align=justify>#endif</P>
<P align=justify>{ }</P>
<P align=justify>};</P>
<P
align=justify>由定義可見,該類沒有在_AFX_MODULE_STATE類的基礎上增加數據。它類用來實現一個MFC應用程序模塊的狀態信息。</P>
<P align=justify></P>
<LI><A name=_Toc445889102></A><A name=_Toc445782505></A><A
name=_Toc452640966></A><A name=_Toc457299064></A><B>_AFX_THREAD_STATE</B>
<P></P>
<P align=justify>該類定義如下:</P>
<P align=justify>class _AFX_THREAD_STATE : public CNoTrackObject</P>
<P align=justify>{</P>
<P align=justify>public:</P>
<P align=justify>_AFX_THREAD_STATE();</P>
<P align=justify>virtual ~_AFX_THREAD_STATE();</P>
<P align=justify></P>
<P align=justify>// override for m_pModuleState in _AFX_APP_STATE</P>
<P align=justify>AFX_MODULE_STATE* m_pModuleState;</P>
<P align=justify>AFX_MODULE_STATE* m_pPrevModuleState;</P>
<P align=justify></P>
<P align=justify>// memory safety pool for temp maps</P>
<P align=justify>void* m_pSafetyPoolBuffer; // current buffer</P>
<P align=justify></P>
<P align=justify>// thread local exception context</P>
<P align=justify>AFX_EXCEPTION_CONTEXT m_exceptionContext;</P>
<P align=justify></P>
<P align=justify>// CWnd create, gray dialog hook, and other hook data</P>
<P align=justify>CWnd* m_pWndInit;</P>
<P align=justify>CWnd* m_pAlternateWndInit; // special case commdlg
hooking</P>
<P align=justify>DWORD m_dwPropStyle;</P>
<P align=justify>DWORD m_dwPropExStyle;</P>
<P align=justify>HWND m_hWndInit;</P>
<P align=justify>BOOL m_bDlgCreate;</P>
<P align=justify>HHOOK m_hHookOldCbtFilter;</P>
<P align=justify>HHOOK m_hHookOldMsgFilter;</P>
<P align=justify></P>
<P align=justify>// other CWnd modal data</P>
<P align=justify>MSG m_lastSentMsg; // see CWnd::WindowProc</P>
<P align=justify>HWND m_hTrackingWindow; // see CWnd::TrackPopupMenu</P>
<P align=justify>HMENU m_hTrackingMenu;</P>
<P align=justify>TCHAR m_szTempClassName[96]; // see
AfxRegisterWndClass</P>
<P align=justify>HWND m_hLockoutNotifyWindow; // see CWnd::OnCommand</P>
<P align=justify>BOOL m_bInMsgFilter;</P>
<P align=justify></P>
<P align=justify>// other framework modal data</P>
<P align=justify>CView* m_pRoutingView; // see
CCmdTarget::GetRoutingView</P>
<P align=justify>CFrameWnd*m_pRoutingFrame;//see
CmdTarget::GetRoutingFrame</P>
<P align=justify></P>
<P align=justify>// MFC/DB thread-local data</P>
<P align=justify>BOOL m_bWaitForDataSource;</P>
<P align=justify></P>
<P align=justify>// common controls thread state</P>
<P align=justify>CToolTipCtrl* m_pToolTip;</P>
<P align=justify>CWnd* m_pLastHit; // last window to own tooltip</P>
<P align=justify>int m_nLastHit; // last hittest code</P>
<P align=justify>TOOLINFO m_lastInfo; // last TOOLINFO structure</P>
<P align=justify>int m_nLastStatus; // last flyby status message</P>
<P align=justify>CControlBar* m_pLastStatus; // last flyby status control
bar</P>
<P align=justify></P>
<P align=justify>// OLE control thread-local data</P>
<P align=justify>CWnd* m_pWndPark; // "parking space" window</P>
<P align=justify>long m_nCtrlRef; // reference count on parking window</P>
<P align=justify>BOOL m_bNeedTerm; // TRUE if OleUninitialize needs to be
called</P>
<P align=justify>};</P>
<P align=justify>從定義可以看出,線程狀態的成員數據分如下幾類:</P>
<P
align=justify>指向模塊狀態信息的指針,支持本線程的窗口創建的變量,MFC命令和消息處理用到的信息,處理工具條提示信息(tooltip)的結構,和處理OLE相關的變量,等等。</P>
<P align=justify></P>
<LI><A name=_Toc445889103></A><A name=_Toc445782506></A><A
name=_Toc452640967></A><A
name=_Toc457299065></A><B>AFX_MODULE_THREAD_STATE</B>
<P></P></LI></OL>
<P align=justify>該類定義如下:</P>
<P align=justify>// AFX_MODULE_THREAD_STATE (local to thread *and*
module)</P>
<P align=justify>class AFX_MODULE_THREAD_STATE : public CNoTrackObject</P>
<P align=justify>{</P>
<P align=justify>public:</P>
<P align=justify>AFX_MODULE_THREAD_STATE();</P>
<P align=justify>virtual ~AFX_MODULE_THREAD_STATE();</P>
<P align=justify></P>
<P align=justify>// current CWinThread pointer</P>
<P align=justify>CWinThread* m_pCurrentWinThread;</P>
<P align=justify></P>
<P align=justify>// list of CFrameWnd objects for thread</P>
<P align=justify>CTypedSimpleList<CFrameWnd*> m_frameList;</P>
<P align=justify></P>
<P align=justify>// temporary/permanent map state</P>
<P align=justify>DWORD m_nTempMapLock; // if not 0, temp maps locked</P>
<P align=justify>CHandleMap* m_pmapHWND;</P>
<P align=justify>CHandleMap* m_pmapHMENU;</P>
<P align=justify>CHandleMap* m_pmapHDC;</P>
<P align=justify>CHandleMap* m_pmapHGDIOBJ;</P>
<P align=justify>CHandleMap* m_pmapHimageLIST;</P>
<P align=justify></P>
<P align=justify>// thread-local MFC new handler (separate from
C-runtime)</P>
<P align=justify>_PNH m_pfnNewHandler;</P>
<P align=justify></P>
<P align=justify>#ifndef _AFX_NO_SOCKET_SUPPORT</P>
<P align=justify>// WinSock specific thread state</P>
<P align=justify>HWND m_hSocketWindow;</P>
<P align=justify>CMapPtrToPtr m_mapSocketHandle;</P>
<P align=justify>CMapPtrToPtr m_mapDeadSockets;</P>
<P align=justify>CPtrList m_listSocketNotifications;</P>
<P align=justify>#endif</P>
<P align=justify>};</P>
<P align=justify>模塊-線程狀態的數據成員主要有:</P>
<P align=justify>指向當前線程對象(CWinThread對象)的指針m_pCurrentWinThread;</P>
<P
align=justify>當前線程的框架窗口對象(CFrameWnd對象)列表m_frameList(邊框窗口在創建時(見圖5-8)把自身添加到m-frameList中,銷毀時則刪除掉,通過列表m_frameList可以遍歷模塊所有的邊框窗口);</P>
<P align=justify>new操作的例外處理函數m_pfnNewHandler;</P>
<P align=justify>臨時映射鎖定標識m_nTempMapLock,防止并發修改臨時映射。</P>
<P align=justify>系列Windows對象-MFC對象的映射,如m_pmapHWND等。</P>
<P align=justify>這些數據成員都是線程和模塊私有的。</P>
<P align=justify></P>
<P align=justify>下一節討論MFC如何通過上述這些類來實現其狀態的管理。</P>
<P align=justify></P>
<LI><A name=_Toc445889104></A><A name=_Toc445782507></A><A
name=_Toc452640968></A><A name=_Toc457299066></A><B>線程局部存儲機制和狀態的實現</B>
<P></P>
<P
align=justify>MFC實現線程、模塊或者線程-模塊私有狀態的基礎是MFC的線程局部存儲機制。MFC定義了CThreadSlotData類型的全局變量_afxThreadData來為進程的線程分配線程局部存儲空間:</P>
<P align=justify>CThreadSlotData* _afxThreadData;</P>
<P
align=justify>在此基礎上,MFC定義了變量_afxThreadState來管理線程狀態,定義了變量_afxBaseModuleState來管理進程狀態。</P>
<P align=justify>THREAD_LOCAL(_AFX_THREAD_STATE, _afxThreadState)</P>
<P align=justify>PROCESS_LOCAL(_AFX_BASE_MODULE_STATE,
_afxBaseModuleState)</P>
<P
align=justify>對于每個THREAD_LOCAL宏定義的變量,進程的每個線程都有自己獨立的拷貝,這個變量在不同的線程里頭可以有不同的取值。</P>
<P
align=justify>對于每個PROCESS_LOCAL宏定義的變量,每個進程都有自己獨立的拷貝,這個變量在不同的進程里頭可以有不同的取值。</P>
<P align=justify>分別解釋這三個變量。</P>
<OL>
<P align=justify>
<LI><A name=_Toc445889105></A><A name=_Toc445782508></A><A
name=_Toc452640969></A><A
name=_Toc457299067></A><B>CThreadSlotData和_afxThreadData</B>
<P></P>
<OL>
<P align=justify>
<LI><B><A name=_Toc457299068></A>CThreadSlotData的定義</B>
<P></P>
<P
align=justify>以Win32線程局部存儲機制為基礎,MFC設計了類CThreadSlotData來提供管理線程局部存儲的功能,MFC應用程序使用該類的對象──全局變量_afxThreadData來管理本進程的線程局部存儲。CThreadSlotData類的定義如下:</P>
<P align=justify>class CThreadSlotData</P>
<P align=justify>{</P>
<P align=justify>public:</P>
<P align=justify>CThreadSlotData();</P>
<P align=justify></P>
<P align=justify>//Operations</P>
<P align=justify>int AllocSlot();</P>
<P align=justify>void FreeSlot(int nSlot);</P>
<P align=justify>void* GetValue(int nSlot);</P>
<P align=justify>void SetValue(int nSlot, void* pValue);</P>
<P align=justify>// delete all values in process/thread</P>
<P align=justify>void DeleteValues(HINSTANCE hInst, BOOL bAll =
FALSE);</P>
<P align=justify>// assign instance handle to just constructed slots</P>
<P align=justify>void AssignInstance(HINSTANCE hInst);</P>
<P align=justify></P>
<P align=justify>// Implementation</P>
<P align=justify>DWORD m_tlsIndex;// used to access system thread-local
storage</P>
<P align=justify>int m_nAlloc; // number of slots allocated (in
UINTs)</P>
<P align=justify>int m_nRover; // (optimization) for quick finding of
free slots</P>
<P align=justify>int m_nMax; // size of slot table below (in bits)</P>
<P align=justify>CSlotData* m_pSlotData; // state of each slot
(allocated or not)</P>
<P align=justify>//list of CThreadData structures</P>
<P align=justify>CTypedSimpleList<CThreadData*> m_list; </P>
<P align=justify>CRITICAL_SECTION m_sect;</P>
<P align=justify>// special version for threads only!</P>
<P align=justify>void* GetThreadValue(int nSlot);</P>
<P align=justify>void* PASCAL operator new(size_t, void* p){ return p;
}</P>
<P align=justify>void DeleteValues(CThreadData* pData, HINSTANCE
hInst);</P>
<P align=justify>~CThreadSlotData();</P>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -