很多人谈论了指针跟句柄的区别,但是我觉得太杂了!什么说法都有,真的很希望谁能更清晰的发表一下看法,我想所有初学者都会非常感激的!

mohuifu_2000 2003-09-20 04:12:41
我是一初学者,正在被windows编程所吸引,但同时也遇到很多让人苦恼的问题,句柄跟指针的区别我想网上的谈论算够多了,但是什么意见都有,有时候看了这个高人的说法觉得有道理,并认为是那样,但是不久以后看了另一个人的提法,觉得他说的也是,所以我现在真的是搞不清了,希望哪位出来帮帮忙!
------------------------------------
以下转载vc知识库
[问题提出]
如果想对对话框的控件进行控制,那么首先要获得此控件的句柄(指针),然后对其操作.
[解决方法]
MFC提供了获取子窗口,指定控件和指定窗口句柄的函数:CWnd::GetDlgItem.
[实现程序]
假设你已有了名为My的对话框工程,并且有了一个ID=IDC_EDIT1的Edit控件:
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CEdit *m_Edit=(CEdit *)GetDlgItem(IDC_EDIT1);
m_Edit->SetWindowText("练习");
return TRUE;
}
-----------------------------------
第二:

以下是另一种说法:

  许多开始学习VC的朋友,最多听说的两个词莫过于指针于句柄了。
但是,确经常搞不清他们之间的区别。
首先,句柄是一个窗口的标志,也就是所有从CWND类继承下来的,多有句柄这个成员。
他能做的,也就是唯一代表一个桌面上的窗口罢了。而指针是一个地址,如果它指向了一个内存中的对象,那么就可以对它进行任意操作了,当然,并不局限于自己的应用程序,你如果能够获得别的应用程序的某个对象的指针,也可以进行操作。然而,如果要获得指针,首先,必须找到那个窗口的句柄,然后用函数FromHandle就可以得到他的指针了。好了,现在,你可以对窗口任意操作了
-------------------------------
第三:
以下另一种说法:
看看C++ 教材中是如何给句柄下定义的:“在Win32里,句柄是指向一个无值型对象(void *)的指针,是一个4

字节长的数据”。虽然我对它的本质是什么还是很迷惑,但我知道句柄并不是一个真正意义上的指针。从结构上看,

句柄的确是一个指针,尽管它没有指向用于存储某个对象的内存位置(很多书都这么说,这正是我的迷惑所在),而

实际上句柄指向的是一个包含了对该对象进行的引用的位置。在编程时,只要抓住了对象的句柄就可以对该对象进行

操作了

---------------------------------
我想问一下,通过对象的指针和通过对象的句柄来 操作对象到底有什么区别?
为什么有的说法是要先获取句柄以后在获取指针?


...全文
317 50 打赏 收藏 转发到动态 举报
写回复
用AI写文章
50 条回复
切换为时间正序
请发表友善的回复…
发表回复
zx_sanjin 2003-09-23
  • 打赏
  • 举报
回复
系统来管理句柄不是直接体现在安全性,<<操作系统>>的书,内存分配是要算法的,用户想要分配到一块内存首先要看哪些内存正在用,哪些内存没在用,然后从没在用的那部分中再选出符合条件的一段。难道这段算法要用户来指定吗?用户的麻烦事够多了,如果再让他来管理这东一块西一块的内存就难免会出问题,crash~~ 所以啊,安全了~~~~ 厚厚~~~
mohuifu_2000 2003-09-23
  • 打赏
  • 举报
回复
to codewarrior(会思考的草)

基本理解,我想更深入还是多实践了!谢谢各问. 呵呵.发分了!!
zzutligang 2003-09-23
  • 打赏
  • 举报
回复
听了大家说了这么多,好像这两个概念是只可意会,不可言传的。学习中ing...
zx_sanjin 2003-09-23
  • 打赏
  • 举报
回复
DD就是小弟弟,哈哈`~~

每个人的学习方法都不同,每个聪明的人都会认为自己的方法最有效,但是不一定就适合别人。虽然"会思考的草"跟许多人的想法一样,但不见得她(他)跟每个人的理解程度都一样,这也就是为什么C++跟Java都是牛人写出来的,但还是有很多高手在争论它们的优劣,存在即为真理,没什么值得争论的~~~~ (不过我鄙视VB,活活)

这段时间在看C++,虽然学了有2年多了,但做考试模拟题还是不及格,汗啊~~~~~
sdcer 2003-09-23
  • 打赏
  • 举报
回复
((CEdit*)GetDlgItem(IDC_EDIT***))->SetWindowText(...)
上面这个句子大家是否是认为得到了指针呢?其实也不是,它是得到句柄,所以,->以后的必是windows的某个函数,所以,你到底还是用到了如SetWindowText这样的函数,而不是直接对它的指针进行操作。
但有些函数(如GlobalAlloc()),这些函数虽然得到句柄,但却可以向指针强制转化,这当另当别论,它是为了兼容16位版本,不在大家考虑的通常情况之列。
会思考的草 2003-09-23
  • 打赏
  • 举报
回复
窗口就是窗口,和CWnd对象没有与生俱来的必然的联系!!Understand??
WNDCLASS != CWnd
会思考的草 2003-09-23
  • 打赏
  • 举报
回复
再次声明!
C++对象和WNDCLASS没有什么瓜葛!!!
会思考的草 2003-09-23
  • 打赏
  • 举报
回复
通过句柄获得指针?好像必须要先创建C++对象然后Attach吧?
安全性?体现在OS内部。对象的指针最终还是要通过句柄起作用,Windows本身是没有CWnd这个东西的,只有HWND。换句话说,windows只认HWND,不认CWnd*。
abcsdk 2003-09-23
  • 打赏
  • 举报
回复
羡慕
mohuifu_2000 2003-09-23
  • 打赏
  • 举报
回复
to ifengfeng(fengfeng):
是阿,DD是什么意思?会不会是很时髦的话?那你一定得贴出来让大家知道!!呵呵!
mohuifu_2000 2003-09-23
  • 打赏
  • 举报
回复
CWnd是如何封装WNDCLASS的,CWnd并不是直接把整个WNDCLASS都包装在内,而仅仅是包装了一个指向窗口的句柄,就是说,使用CWnd的指针,最后还是要转化成句柄对窗口进行操作。
CWnd
按这种说法:
CWnd* pWnd-----> ----------
| m_hWnd |------>WNDCLASS
| …… |
|其他成员|
----------
理解了上面你就能理解,为什么创建一个窗口(典型如工具条,状态栏)要经过两次操作,一次是建立C++对象CToolBar,此时CToolBar内的窗口句柄还是空,即不代表任何Window对象,第二次使用Create/CreateEx函数才是真正创建Windows对象,创建完了之后,CToolBar内的窗口句柄就有效了。

我想可以理解!但是我们同样可以通过窗口的句柄获得这个对象的指针,通过对象指针不是同样可以进行任意操作,那安全性还体现在哪里?

sdcer 2003-09-23
  • 打赏
  • 举报
回复
我在上面已经把句柄的作用机制讲了,事实上,如果真能理解它的作用机制(而并见得要非常得明白句柄和指针的对应表的结构,这个表的长度是多少,第一项写的什么,是二进制还是十六进制。。。),可以这么讲,事实上,句柄和指针的对应关系的细节,微软公司根本没有提供给用户,它是保密的,所以,你永远不可能知道它的全貌(但这和明白它的作用机制和使用方法并不矛盾),codewarrior(会思考的草),我想你是误会我的意思了,如果真能理解我和大家上面的发言,无论你用句柄用到多么出神入化的程度,都不会影响你的理解与发挥,关键看你到不到那个火候,是不是真正的理解它的作用机制(理解有的时候需要扒其筋,看其肉,有些时候是做不到的,正如句柄,人家微软都根本就没告诉你它的细节嘛),所以,你要做的是理解它是怎么工作的,而这也同样需要下一番工夫,所以这和(会思考的草)所言的不求甚解根本就是两个概念!
会思考的草 2003-09-23
  • 打赏
  • 举报
回复
to ifengfeng(fengfeng):
支持 codewarrior(会思考的草)

你要仔细研究一点小东西,你这一辈子可能都没见过其他DD。呵呵
==================================
谢谢,不过,你说的DD,啥意思呢?好奇地问。
会思考的草 2003-09-23
  • 打赏
  • 举报
回复
不是很赞成sdcer(独钓雪)的态度。我支持楼主刨根问底的精神,如侯捷所说,用一样东西,但不明白它内部作用机制,实在不高明。但是我觉得凡事应该“先知其然,后知其所以然”,如果连“知其然”都达不到就片面追求“高、深、精”,结果反而是伤了自己学习的兴趣。作为一个初学者,当然可以,也应该做到“只用,而不追究其本质”,但是用得熟练了,自然就应该探求内部的实质,不仅是对自己能力要求的提高,也是科学精神的体现。
sdcer 2003-09-23
  • 打赏
  • 举报
回复
我们编程中使用的窗口、控件,这些东西,实际上都是一种windows数据结构,但任何结构都是要在内存中运行、实现的,这就是说,窗口、控件这些东西也是在内存中存在的,试想,我们可以随便改变内存中窗口、控件这样的内存中的内容吗?显然不能,如果让你随便改变了,也许窗口、控件就不是现在的这个模样了,也许是改头换面,也许是根本无法显示(因为你改变了它的数据结构,即内存),所以,windows想出来句柄这个东西,知道索引和内容的关系吗?在这里,索引就相当于是句柄,而内容相当于内存地址(或者叫作指针),只要是程序中用到了hWnd等句柄形式,不论是我们使用的,操作系统提供给我们的,或者我们传递给操作系统的,都只是这个索引,先说你得到句柄的情况,当你得到这个索引后,你可以直接访问索引对应的内容吗?也不能,但是,你可以调用操作系统提供给你的函数,去间接的访问索引对应的内容(指针),至于操作系统是如何将索引转化为对应的指针的,这个谁也不知道,但你必须了解它的作用机制,另外,之所以在你的程序中需要自己定义句柄,也只是用于调用操作系统的函数!!记住,要理解它是什么样子的,但不要问句柄的实质,因为实质只有编写操作系统的可以知道,其它的人只可以使用它,理解它,这就足够了,但首先,你要明白它是怎么工作的,以及为什么这样工作。
ifengfeng 2003-09-23
  • 打赏
  • 举报
回复
支持 codewarrior(会思考的草)

你要仔细研究一点小东西,你这一辈子可能都没见过其他DD。呵呵
会思考的草 2003-09-23
  • 打赏
  • 举报
回复
看看保护模式的内存管理,了解386CPU的特点,再假设一下,如果你是Windows的设计者,你会直接向用户提供内存地址吗?
会思考的草 2003-09-23
  • 打赏
  • 举报
回复
还有,为什么要使用句柄而不是象在DOS下那样直接提供地址,我想有两个方面的原因,其一,Win32是抢占式多任务操作系统,为了内存保护的目的,不能直接向用户程序提供Window Object的指针,这样的话操作系统对内存的保护能力大大减弱;其二,Win32工作在80386保护模式下,根据保护模式的内存管理方式,Windows也不可能直接提供某个内存地址的指针,因为保护模式下的虚拟地址空间要经过映射才能转化成实际物理地址,Windows内部也经常进行换入换出的操作,各种Window Object也随之在内存中到处移动,如果直接提供物理地址,那么势必就破坏了虚拟内存的基石,因为Windows将无法进行页面换入换出的操作,系统性能将大打折扣。
会思考的草 2003-09-23
  • 打赏
  • 举报
回复
你说的没错,确实可以这样做,CDialog中的成员函数GetDlgItem返回的是CWnd*的指针。CDialog是从CWnd继承下来的,C++中允许把父类强制转换成子类的实例。
你可能还没有搞清楚,CWnd是如何封装WNDCLASS的,CWnd并不是直接把整个WNDCLASS都包装在内,而仅仅是包装了一个指向窗口的句柄,就是说,使用CWnd的指针,最后还是要转化成句柄对窗口进行操作。
CWnd
CWnd* pWnd-----> ----------
| m_hWnd |------>WNDCLASS
| …… |
|其他成员|
----------
理解了上面你就能理解,为什么创建一个窗口(典型如工具条,状态栏)要经过两次操作,一次是建立C++对象CToolBar,此时CToolBar内的窗口句柄还是空,即不代表任何Window对象,第二次使用Create/CreateEx函数才是真正创建Windows对象,创建完了之后,CToolBar内的窗口句柄就有效了。
zhu0918 2003-09-22
  • 打赏
  • 举报
回复
我自己的体会是,只看书是不会理解的,要动手去做,做得多了就能有自己的体会了!
我个人认为句柄和指针是一个对应关系而已!
加载更多回复(30)

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧