⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mfc

📁 很好的MFC书籍
💻
📖 第 1 页 / 共 5 页
字号:
      <P align=justify>#ifdef _AFXDLL</P>
      <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&lt;CFrameWnd*&gt; 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&lt;CThreadData*&gt; 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>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -