1.引出句柄程序员
CDC问题:
1.CDC dc;dc.LineTo(point);没法运行函数
2.CDC *dc=GetDC();dc->LineTo(point);就能够运行了操作系统
MFC中有大量的句柄包装类。所谓句柄包装类,指的是这些类是封装了系统对象的句柄,并提供了一组成员函数做为访问系统对象的接口。指针
从这些句柄包装类的意义上能够看出,一个被彻底构造好,处于良好状态的MFC对象,其中的句柄成员必须是有效的,才能正常使用那些成员函数来操做这个对象。对象
因此通常的MFC句柄包装类的构建要完成两个任务:接口
第一,建立一个句柄包装类对象。内存
第二,初始化其中的系统对象句柄。资源
大部分的包装类对象的构建都一般分为两步进行:内存管理
一、建立一个对象;基础
二、经过create等相似的成员函数建立系统对象并初始化对象中的句柄。
固然这两部分也能够直接在构造函数中完成。此时通常须要一个系统对象句柄做为参数,或者另外一个被良好构造的句柄包装类对象作参数,以在构造函数中就能初始化句柄成员。其余方法还有经过Attach和Detach将部
分构造的对象和系统对象句柄绑定,或经过FromHandle得到一个临时的句柄包装类对象等。
如今问题就很清晰了:
CDC dc;dc.LineTo( point );//没法运行,是由于dc这个对象仅仅被部分构建,其中的系统对象句柄成员并无赋值为一个有效的绘图设备句柄,天然其后的LineTo调用就会失败。
而:
CDC *dc = GetDC();dc->LineTo( point );/*经过调用窗口类的GetDC()成员函数,将返回一个被良好构造的CDC对象(即该对象中的设备句柄成员已经被赋值为一个有效的
句柄),因此其后的LineTo操做就没问题。也就是问题的关键不在于对象建立于栈仍是堆中,而在因而否彻底构造好了一个句柄包装
类对象。*/
2.句柄究竟是什么东东呢,指针呢?
其实,句柄并无什么神奇之处,无论哪一种句柄,实际都是一个整数。它标识一种资源,如窗口、位图等等。就象你找一我的,必须知道它的地址同样,若是你要操做一种资源,必须先得到句柄。“取窗口句柄
()”并非只能取出窗口的句柄,全部窗口控件,如编辑框、标签等均可以用本命令取出本身的句柄,如:编辑框1.取窗口句柄()或标签1.取窗口句柄()。控件的句柄一样,任何控件都有它自身的特有属性,句柄
也就指它的特有属性(包括共性)。
句柄英文译做HANDLE,HANDLE的本意是把柄,把手的意思,是与操做系统打交道的东东。有人举过比较通俗的例子:你考上了大学,入学后,学校(操做系统)会给你一个学生证号。注意,这个号码是学校指
定的,你没法自选。有了这个号码(学生证,假设一证多用)享受学校提供的服务:如你就能够去图书馆借书,去食堂吃饭,去教室上课等 等。但你不能到食堂里买啤酒,由于学校不容许这种服务。而在计算机中系统
提供的服务就是API调用了。当你有了HANDLE,就能够义正词严地向系统提出调用API的服务。而指针的权力就大多了,有了指针你能够处处去喝酒,打架,学校(操做系统)管不着,因此句柄和指针的区别在于句柄
只能调用系统提供的服务。而句柄虽然是一个能相互区别的号码,但与咱们普通的ID号又有区别,普通的ID号是能够由程序员本身定义的,而句柄不行,它是对象生成时系统指定的,是为了区别系统中存在的各个对
象,这个句柄不是由程序员赋给的。
能够引用csdn上一我的的话来讲明句柄,指针对象实例之间的关系:
牧童遥指杏花村。牧童的手为指针,杏花村的牌子为句柄,杏花村酒店为对象的实例。
3.深刻探讨句柄
更透彻的说,句柄是一种指向指针的指针。你们都知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内存的。若是简单地理解,彷佛咱们只要获知这个内存的首地址,那么就能够随
时用这个地址访问对象。可是,若是您真的这样认为,那么您就大错特错了。咱们知道,Windows是一个以虚拟内存为基础的操做系统。在这种系统环境 下,Windows内存管理器常常在内存中来回移动对象,依此来
知足各类应用程序的内存须要。对象被移动意味着它的地址变化了。若是地址老是如此变化,咱们该到哪里去找该对象呢? 为了解决这个问题,Windows操做系统为各应用程序腾出一些内存储地址,用来专门登记各应
用对象在内存中的地址变化,而这个地址(存储单元的位置)本 身是不变的。Windows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样咱们只需记住这个句柄地址就能够间接地
知道对象具体在内存中的哪一个位置。这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。句柄地址(稳定) ─→记载着对象在内存中的地址─→对象在内存中的地址(不稳定) ─→实际
对象
本质:WINDOWS程序中并非用物理地址来标识一个内存块,文件,任务或动态装入模块的,相反的,WINDOWS API给这些项目分配肯定的句柄,并将句柄返回给应用程序,而后经过句柄来进行操做。 可是
必须注意的是程序每次重新启动,系统不能保证分配给这个程序的句柄仍是原来的那个句柄,并且绝大多数状况的确不同的。假如咱们把进入电影院看电影看 成是一个应用程序的启动运行,那么系统给应用程序分配
的句柄老是不同,这和每次电影院售给咱们的门票老是不一样的一个座位是同样的道理。