句柄映射机制的实现
来源:互联网 发布:2016淘宝联盟导购推广 编辑:程序博客网 时间:2024/06/06 09:44
mfc里实现句柄映射借助了两个类:句柄映射辅助类,模块--线程状态类
1.句柄映射辅助类:
class CHandleMap
{
private: // implementation
CFixedAllocNoSync m_alloc;
void (PASCAL* m_pfnConstructObject)(CObject* pObject);
void (PASCAL* m_pfnDestructObject)(CObject* pObject);
CMapPtrToPtr m_permanentMap; //永久映射
CMapPtrToPtr m_temporaryMap; //临时映射
CRuntimeClass* m_pClass;
size_t m_nOffset; // offset of handles in the object
int m_nHandles; // 1 or 2 (for CDC)
// Constructor/Destructor
public:
CHandleMap(CRuntimeClass* pClass,
void (PASCAL* pfnConstructObject)(CObject* pObject),
void (PASCAL* pfnDestructObject)(CObject* pObject),
size_t nOffset, int nHandles = 1);
#ifdef _AFXDLL
~CHandleMap()
#else
virtual ~CHandleMap()
#endif
{ DeleteTemp(); }
// Operations
public:
CObject* FromHandle(HANDLE h); //从句柄获取MFC对象
void DeleteTemp(); //删除临时句柄
void SetPermanent(HANDLE h, CObject* permOb); //向永久映射中添加一个记录
void RemoveHandle(HANDLE h); //从永久映射里删除一个记录
CObject* LookupPermanent(HANDLE h); //查找永久映射表
CObject* LookupTemporary(HANDLE h); //查处临时映射表
friend class CWinThread;
};
2.模板--线程状态类
class AFX_MODULE_THREAD_STATE : public CNoTrackObject
{
public:
AFX_MODULE_THREAD_STATE();
virtual ~AFX_MODULE_THREAD_STATE();
// current CWinThread pointer
CWinThread* m_pCurrentWinThread;
// list of CFrameWnd objects for thread
CTypedSimpleList<CFrameWnd*> m_frameList;
// temporary/permanent map state
DWORD m_nTempMapLock; // if not 0, temp maps locked
CHandleMap* m_pmapHWND;
CHandleMap* m_pmapHMENU;
CHandleMap* m_pmapHDC;
CHandleMap* m_pmapHGDIOBJ;
CHandleMap* m_pmapHIMAGELIST;
..........................................................
模板--线程状态的初始化在CWinApp的构造函数里完成,也就是说它比WinMain更早,构造函数主要完成模块状态,模板--线程状态,
以及线程和全局对象的初始化。
每当一个窗口类调用Create或CreateEx时,都要设置钩子:
AfxHookWindowCreate(this);这个函数的作用在这不多讲了,总之它在执行过程中调用了:Attach(m_hWnd);
Attach()的定义如下:
BOOL CWnd::Attach(HWND hWndNew)
{
ASSERT(m_hWnd == NULL);
ASSERT(FromHandlePermanent(hWndNew) == NULL);
if (hWndNew == NULL)
return FALSE;
CHandleMap* pMap = afxMapHWND(TRUE); // create map if not exist
ASSERT(pMap != NULL);
pMap->SetPermanent(m_hWnd = hWndNew, this); //加入到永久映射中
#ifndef _AFX_NO_OCC_SUPPORT
AttachControlSite(pMap);
#endif
return TRUE;
}
CWnd有这样几个函数:FromHandle(HWND hWnd),FromHandlePermanent(HWND hWnd).它们都用到CHandleMap类
函数定义如下:
CWnd* PASCAL CWnd::FromHandle(HWND hWnd)
{
CHandleMap* pMap = afxMapHWND(TRUE); //如果不存在就创建它:afxMapHWND的作用
ASSERT(pMap != NULL);
CWnd* pWnd = (CWnd*)pMap->FromHandle(hWnd); //先从永久里找,再从临时中找,都找不到就创建一个Cwnd返回
#ifndef _AFX_NO_OCC_SUPPORT
pWnd->AttachControlSite(pMap);
#endif
ASSERT(pWnd == NULL || pWnd->m_hWnd == hWnd);
return pWnd;
}
CWnd* PASCAL CWnd::FromHandlePermanent(HWND hWnd)
{
CHandleMap* pMap = afxMapHWND();
CWnd* pWnd = NULL;
if (pMap != NULL)
{
// only look in the permanent map - does no allocations
pWnd = (CWnd*)pMap->LookupPermanent(hWnd); //只从永久映射里找,如果找不到就返回NULL.
ASSERT(pWnd == NULL || pWnd->m_hWnd == hWnd);
}
return pWnd;
}
当一个窗口函数要销毁的时候,也就是在它接收的最后一个WMNCDESTROY里会调用Detach()来解除窗口对象与CWnd对象的关系。
Detach()的定义如下:
HWND CWnd::Detach()
{
HWND hWnd = m_hWnd;
if (hWnd != NULL)
{
CHandleMap* pMap = afxMapHWND(); // don't create if not exist
if (pMap != NULL)
pMap->RemoveHandle(m_hWnd); //从永久映射里删除。
m_hWnd = NULL;
}
#ifndef _AFX_NO_OCC_SUPPORT
m_pCtrlSite = NULL;
#endif
return hWnd;
}
在程序空闲的时候,也就是在OnIdle函数,会自动删除临时的映射。
- 句柄映射机制的实现
- 消息映射机制的简单实现
- 消息映射机制的简单实现
- 映射机制的实现示例及介绍
- 简述MFC消息映射机制的实现
- java的映射机制
- Hibernate的映射机制
- servlet的映射机制
- DOM的映射机制
- MFC消息映射机制实现
- MFC消息映射机制的具体实现方法
- C实现大数据文件的内存映射机制
- 关于windows句柄机制的一些心得体会
- window操作系统下的句柄机制说明
- 映射窗口句柄对象
- MFC 对象与Win32 SDK 句柄的映射关系
- MFC对象与WIN32句柄的映射-TLS
- MFC的消息映射机制
- datalist内嵌与递归的后台代码
- MINIX3进程学习
- NBA Palace for Basketball Players
- vs中“Stack around the variable was corrupted”的解决方案
- Javascript 刷新框架及页面的方法总集
- 句柄映射机制的实现
- 博客缘起
- C#正则表达式
- 关于C++中函数参数是省略号的应用
- Chrome OS & Google Wave
- 功能覆盖率
- const函数重载
- C#笔试题
- Cindy中的Filter