解析 MFC 中的 FromHandle
MFC 对 Windows API 进行了封装,在很多方面都会提供便利。用 FromHandle 返回零时对象的指针,就可以调用各种类的方法。临时对象会在 OnIdle 中销毁。这里对 FromHandle 的实现原理从源码上进行解析。
//
// 1
//
CWnd* PASCAL CWnd::FromHandle(HWND hWnd)
{
CHandleMap* pMap = afxMapHWND(TRUE); //create map if not exist
ASSERT(pMap != NULL);
CWnd* pWnd = (CWnd*)pMap->FromHandle(hWnd);
#ifndef _AFX_NO_OCC_SUPPORT
pWnd->AttachControlSite(pMap);
#endif
ASSERT(pWnd == NULL || pWnd->m_hWnd == hWnd);
return pWnd;
}
这是 CWnd 的 FromHandle 方法,大致的意思为从 CHandleMap 中获取临时 CWnd 对象的指针。
//
// 2
//
CHandleMap* PASCAL afxMapHWND(BOOL bCreate)
{
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
if (pState->m_pmapHWND == NULL && bCreate)
{
BOOL bEnable = AfxEnableMemoryTracking(FALSE);
#ifndef _AFX_PORTABLE
_PNH pnhOldHandler = AfxSetNewHandler(&AfxCriticalNewHandler);
#endif pState->m_pmapHWND = new CHandleMap(RUNTIME_CLASS(CTempWnd),
offsetof(CWnd, m_hWnd));
#ifndef _AFX_PORTABLE
AfxSetNewHandler(pnhOldHandler);
#endif
AfxEnableMemoryTracking(bEnable);
}
return pState->m_pmapHWND;
}
再看
#define offsetof(s,m) (size_t)&(((s *)0)->m)
继续
//
// 3
//
CObject* CHandleMap::FromHandle(HANDLE h)
{
ASSERT(m_pClass != NULL);
ASSERT(m_nHandles == || m_nHandles == );
if (h == NULL)
return NULL;
CObject* pObject = LookupPermanent(h);
if (pObject != NULL)
return pObject; // return permanent one
else if ((pObject = LookupTemporary(h)) != NULL)
{
HANDLE* ph = (HANDLE*)((BYTE*)pObject + m_nOffset);
ASSERT(ph[] == h || ph[] == NULL);
ph[] = h;
if (m_nHandles == )
{
ASSERT(ph[] == h || ph[] == NULL);
ph[] = h;
}
return pObject; // return current temporary one
}
// This handle wasn't created by us, so we must create a temporary
// C++ object to wrap it. We don't want the user to see this memory
// allocation, so we turn tracing off.
BOOL bEnable = AfxEnableMemoryTracking(FALSE);
#ifndef _AFX_PORTABLE
_PNH pnhOldHandler = AfxSetNewHandler(&AfxCriticalNewHandler);
#endif
CObject* pTemp = NULL;
TRY
{
pTemp = m_pClass->CreateObject();
if (pTemp == NULL)
AfxThrowMemoryException();
m_temporaryMap.SetAt((LPVOID)h, pTemp);
}
CATCH_ALL(e)
{
#ifndef _AFX_PORTABLE
AfxSetNewHandler(pnhOldHandler);
#endif
AfxEnableMemoryTracking(bEnable);
THROW_LAST();
}
END_CATCH_ALL
#ifndef _AFX_PORTABLE
AfxSetNewHandler(pnhOldHandler);
#endif
AfxEnableMemoryTracking(bEnable);
// now set the handle in the object
HANDLE* ph = (HANDLE*)((BYTE*)pTemp + m_nOffset); // after CObject
ph[] = h;
if (m_nHandles == )
ph[] = h;
return pTemp;
}
解析 MFC 中的 FromHandle的更多相关文章
- 深入解析MFC -- 句柄与对象的关系
CWnd::FromHandlePermanent ——根据窗口句柄得到CWnd*指针 This function, unlike FromHandle, does not create tempor ...
- MFC中的一些视图
本章主要介绍MFC中主要的视图类,这些继承自Cview类. 继承关系如上图所示. 滚动视图 CscrollView给Cview添加了基本的滚动功能,它包含WM_VSCROLL和WM_HSCROLL消息 ...
- MFC中线程相关知识
MFC中把线程分为两种类型,UI线程和工作者线程. MFC中启动一个线程的最好方法是调用AfxBeginThread,有两个版本,一个用于启动Ui线程,另外一个用于启动工作者线程.在MFC程序中,只有 ...
- MFC中获取各个窗口之间的句柄或者指针对象的方法
MFC在非常多的对话框操作中,我们常常要用到在一个对话框中调用还有一个对话框的函数或变量.能够用例如以下方法来解决. HWND hWnd=::FindWindow(NULL,_T("S ...
- 深度解析VC中的消息(转发)
http://blog.csdn.net/chenlycly/article/details/7586067 这篇转发的文章总结的比较好,但是没有告诉我为什么ON_MESSAGE的返回值必须是LRES ...
- C运行时库(C Run-time Library)详解(提供的另一个最重要的功能是为应用程序添加启动函数。Visual C++对控制台程序默认使用单线程的静态链接库,而MFC中的CFile类已暗藏了多线程)
一.什么是C运行时库 1)C运行时库就是 C run-time library,是 C 而非 C++ 语言世界的概念:取这个名字就是因为你的 C 程序运行时需要这些库中的函数. 2)C 语言是所谓的“ ...
- 【VS开发】MFC中调用C函数模块的解决方案
[VS开发]MFC中调用C函数模块的解决方案 标签(空格分隔): [VS开发] 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:最近调试基于MFC的程序 ...
- 浅解析js中的对象
浅解析js中的对象 原文网址:http://www.cnblogs.com/foodoir/p/5971686.html,转载请注明出处. 前面的话: 说到对象,我首先想到的是每到过年过节见长辈的时候 ...
- MFC中使用FLASH
一.准备工作 第一步:下载并安装Adobe Flash Player. 从官方网站(http://get.adobe.com/cn/flashplayer/)上下载最新的Flash Player(大约 ...
随机推荐
- vue 里面输出带标签的html
使用 v-html 指令 <div v-html="'<P>11111111</P><P>11111111</P>'"> ...
- SQL SERVER2008 打开脚本总是报“未能完成操作,存储空间不足”
使用用SQLCMD命令行. 1.快捷键:win+R 2.输入cmd,确定 3.输入命令:sqlcmd -S <数据库服务器名称> -i C:\<脚本文件路径>.sql 如图所 ...
- 51nod1228
伯努利数 这个是答案 其中的b是伯努利数,可以n^2预处理 伯努利数n^2递推 #include<bits/stdc++.h> using namespace std; typedef l ...
- project工期出现小数问题
进入“选项”,点击“日程”,将默认“开始”.“结束”时间调整为“9点~18点.原为PREJECT 日历 (注意是日历~!!)默认的“8点~17点”,与preject系统默认时间“9点~18点”有差别~ ...
- SQL Server 盛宴系列 webcast
数据库学习站点,示例,视频 http://technet.microsoft.com/zh-cn/dd722671.aspx
- hdu-1181
变形课 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submis ...
- ShutdownHook作用
源地址:http://kim-miao.iteye.com/blog/1662550 void java.lang.Runtime.addShutdownHook(Thread hook) 该方法用来 ...
- C++11: Multi-core Programming – PPL Parallel Aggregation Explained
https://katyscode.wordpress.com/2013/08/17/c11-multi-core-programming-ppl-parallel-aggregation-expla ...
- html标签英文全称
更新: 2017/06/09 最近网页开发,一直会查html和css 感觉之前写的这个太杂了,现在主要是先查这个博文,然后查文档. -------------------------------- ...
- 2012 Noip提高组 Day2
1265. [NOIP2012] 同余方程 ★☆ 输入文件:mod.in 输出文件:mod.out 简单对比时间限制:1 s 内存限制:128 MB [题目描述] 求关于 x 的同余方 ...