- 瑞瑞爱吃桃
-
句柄是一个(通常为32位的)整数,它代表一个对象。Windows中的句柄类似传统C或者MS-DOS程序设计中使用的文件句柄。程序几乎总是通过呼叫Windows函数取得句柄。程序在其它Windows函数中使用这个句柄,以使用它代表的对象。
在 Windows 中,窗口可以有许多种。窗口可以是屏幕上的一块矩形封闭区域,比如您熟悉的应用程序窗口。窗体上的控件(例如列表框或滚动条)也可以是窗口,但并不是所有类型的控件都是窗口。桌面上的图标和桌面本身也是窗口。因为所有这些类型的对象都是窗口,所以 Windows 可以用类似的方式处理它们。Windows 给每个窗口一个唯一的句柄,通过句柄操纵该窗口。许多 API 函数可返回句柄或者接受句柄作参数。
创建窗口时,Windows 给它指派一个句柄,窗口消失后句柄被释放。
- 真颛
-
楼上学的是什么句柄啊
所谓句柄实际上是一个数据,是一个Long(整长型)的数据。
句柄是WONDOWS用来标识被应用程序所建立或使用的对象的唯一整数,WINDOWS使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等。WINDOWS句柄有点象C语言中的文件句柄。
从上面的定义中的我们可以看到,句柄是一个标识符,是拿来标识对象或者项目的,它就象我们的姓名一样,每个人都会有一个,不同的人的姓名不一样,但是,也可能有一个名字和你一样的人。从数据类型上来看它只是一个16位的无符号整数。应用程序几乎总是通过调用一个WINDOWS函数来获得一个句柄,之后其他的WINDOWS函数就可以使用该句柄,以引用相应的对象。
如果想更透彻一点地认识句柄,我可以告诉大家,句柄是一种指向指针的指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问对象。但是,如果您真的这样认为,那么您就大错特错了。我们知道,Windows是一个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了。如果地址总是如此变化,我们该到哪里去找该对象呢?
为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。Windows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。
句柄地址(稳定)→记载着对象在内存中的地址————→对象在内存中的地址(不稳定)→实际对象
本质:WINDOWS程序中并不是用物理地址来标识一个内存块,文件,任务或动态装入模块的,相反的,WINDOWSAPI给这些项目分配确定的句柄,并将句柄返回给应用程序,然后通过句柄来进行操作。
但是必须注意的是程序每次从新启动,系统不能保证分配给这个程序的句柄还是原来的那个句柄,而且绝大多数情况的确不一样的。假如我们把进入电影院看电影看成是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和每次电影院售给我们的门票总是不同的一个座位是一样的道理。
- gitcloud
-
句柄是整个windows编程的基础。一个句柄是指使用的一个唯一的整数值,即一个四字节长的数值,来标识应用程序中的不同对象和同类对象中的不同的实例,诸如,一个窗口、按钮、图标、滚动条、输出设备、控件或者文件等。句柄是windows用来标志应用程序中建立的或是使用的唯一整数,windows使用了大量的句柄来标志很多对象。应用程序能够通过句柄访问相应的对象的信息,但是句柄不是一个指针,程序不能利用句柄来直接阅读文件中的信息。如果句柄不用在I/O文件中,它是毫无用处的。
- 以心消业
-
句柄就是一个序号。。用于管理内核对象的,比如你打开一个文件,就建立一个文件内核对象,这个内核对象就是一块内存结构,里面有文件路径,文件大小,当前文件指针等等信息。系统里面会打开很多的文件,就有很多很多的内核对象,这时候就建立一个句柄表的东西。表中每一个元素,都是一个内核对象的起始地址,然后给每一个对象对应一个序号。
这个序号就是我们说的句柄。
//句柄表类似于这样的结构,那个序号就是句柄了
-----------------------------------
0
第一个内核对象的地址
1
第二个内核对象的地址
2
第三个内核对象的地址
-------------------------------------
一定要注意它是序号,不是内核对象。
- 陶小凡
-
句柄是一种不透明指针,通常用来对用户隐藏数据结构实现,这样可以防止用户任意修改数据对象的内容,所有操作必须通过相应API进行,这是一种OOP中常见的概念,即信息隐藏(封装),好处是实现者可以随意修改数据结构实现也不用影响客户代码。比如Win32上有个叫HANDLE的类型,其定义成类型void*这种不透明指针,用户无从知道具体对应的结构体。
就像vbtrazz所说,也可以是资源编号,任何可以唯一标识一个对象的东西都可以说是句柄,好处上面已经提及。
- CarieVinne
-
1.句柄是找到一块内存的索引,作用:找到内存后通过调用Windows函数来修改数据
2.跟指针的区别是,我们通过指针可以直接修改里面的数据,不需要通过Windows函数来修改
3.微软这样做的原因是:封装重要的数据,不让我们自己直接修改,怕我们修改坏了。要修改通过委托Windows来修改
- 阳光下的日耳曼尼亚
-
typedef struct tagWND
{
LPCTSTR lpszClassName;
WNDPROC lpWndProc;
UINT uStyle;
UINT uExStyle;
LPCTSTR lpszTitle;
RECT rcWindow;
RECT rcClient;
....
} WND, *LPWND;
typedef HWND LPWND; // 给用户的头文件中则可以定义HWND为HANDLE,或DWORD。
在上面的例子中,窗口结构向用户隐藏,你只能通过HWND句柄使用系统调用来完成窗口操作。而在系统内部,则直接使用这个结构(为了提高效率)。如以下伪码:
BOOL GetWindowRect(HWND hWnd, LPRECT lpRect)
{
LPWND lpWnd32 = (LPWND)hWNd;
// 首先应该判断地址是否合法,这里略
*lpRect = lpWnd->rcWindow;
return TRUE;
}
在很多场合下句柄应该是个指针。当然,在一些情况下也可能是数组的索引。这取决与系统的定义。引入句柄可以屏蔽掉系统的内部实现,对于系统的稳定、健壮意义巨大,使系统易于升级。这一点通过Win16到Win32的平滑过渡即可看出。不过,句柄的引入也给理解带来了一定的困难。
我最后再做一些分析,如下:
单从概念上讲,句柄指一个对象的标识,而指针是一个对象的首地址。从实际处理的角度讲,即可以把句柄定义为指针,又可以把它定义为同类对象数组的索引,这两种处理方法都有优缺点,至于选用哪种方式,完全应该看实际需要,这可以说是一种程序设计上的技巧。那种单纯认为句柄是指针或索引的想法都是机械的、不确切的。
其实,在Windows中类似的处理是很多的、很灵活的。再具个相似的例子:
我们知道,在Windows中有个函数叫做CallWindowProc。故名思义,它的作用就是向指定的窗口过程传递一个消息。你也许会想,既然我已经有了窗口过程的指针,为什么我不可以直接通过这个指针调用该函数(这是C语言的内建功能)?事实上,在Win16中确实可以这么做,因为GetWindowLong返回的确实是该函数的指针。但在Win32下,GetWindowLong返回的并不是该函数的指针,而是一个包含函数指针的数据结构的指针(MSDN上说返回的是一个窗口函数地址或它的句柄,就是指的这种情况)。该数据结构是可变的,但只要你使用CallWindowProc来调用的话是不会出错的。这里我们又看到使用句柄处理带来的好处。(补充说明一点:微软在这里之所以这么处理,是为了解决16位/32位以及ANSI/UNICODE的转化问题)
神呀,救救那些头脑呆板、一知半解的人吧!
- 黑桃花
-
句柄概念在WINDOWS编程中是一个很重要的概念,在许多地方都扮演着重要的角色。但由此而产生的句柄概念也大同小异,比如:<<Microsoft
Windows
3
Developer"s
Workshop>>(Microsoft
Press,by
Richard
Wilton)一书中句柄的概念是:在Windows环境中,句柄是用来标识项目的,这些项目包括:
*.模块(module)
*.任务(task)
*.实例(instance)
*.文件(file)
*.内存块(block
of
memory)
*.菜单(menu)
*.控制(control)
*.字体(font)
*.资源(resource),包括图标(icon),光标(cursor),字符串(string)等