c#中经常看到的句柄是什么意思?应该怎么使用啊?哪些控件有句柄啊?谢谢了!

figo10203 2006-11-01 08:35:23
本人在学习c#,遇到函数的提示信息经常看到需要什么句柄,问了一下老师,说是什么和操作系统有关,到底是什么东西啊,究竟是用在哪里的啊?怎么用?谢谢大家了!
...全文
978 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
sx_lxh 2006-11-01
  • 打赏
  • 举报
回复
精辟!
zzPandazz 2006-11-01
  • 打赏
  • 举报
回复
支持楼上的
jxhwei 2006-11-01
  • 打赏
  • 举报
回复
句柄实际上是一种指向某种资源的指针,但与指针又有所不同:指针对应着一个数据在内存中的地址,得到了指针就可以自由地修改该数据。Windows并不希望一般程序修改其内部数据结构,因为这样太不安全。所以Windows给每个使用GlobalAlloc等函数声明的内存区域指定一个句柄(本质上仍是一个指针,但不要直接操作它),平时你只是在调用API函数时利用这个句柄来说明要操作哪段内存。


--- 这段话说得比清晰。


牧童遥指杏花村
牧童的手为指针,杏花村的牌子为句柄,杏花村酒店为对象的实例.
牧童
--- 这个比喻也比较形象,指向杏花村的牌子的牧童可以是任何一个牧童,杏花村的牌子可总是那么一个^-^
oolongTea 2006-11-01
  • 打赏
  • 举报
回复
对于“句柄”,也曾经令自己很是折恼了一番,记得当时新人培训的时候,还为这个问题着实讨论了很久。句柄,其实也不是个什么东西,它的引入就是为了可以用一个唯一的信息将对象与其它对象区分开来。比如,你实例化了某个类的两个对象,这就需要为每个对象分配一个唯一标识来区分它们,不错,可以使用“指针”,是的,在我们接触到的面向对象的环境中都是使用对象的物理内存地址(指针)作为这个唯一标识。但是,如果你需要在内存中移动对象或交换到硬盘(比如操作系统就需要干这些事)呢,使用指针就比较可怕了(这下,你可以理解为什么操作系统中没有使用指针,而是使用句柄来标识内核对象了吧)。所以,句柄最好是没有意义的,随机的并且是唯一的数字!!!当然,基于引入句柄的目的,我们还是可以简单将其理解为指针。
from:http://community.hf-mstc.org/cs/blogs/ozheric/archive/2006/10/14/3310.aspx
oolongTea 2006-11-01
  • 打赏
  • 举报
回复
句柄的本质
一、书上定义:

<<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)等、GDI对象(GDI object),包括位图(bitmap),画刷(brush),元文件(metafile),调色板(palette),画笔(pen),区域 (region),以及设备描述表(device context)。

<<WINDOWS编程短平快>>(南京大学出版社):
句柄是WONDOWS用来标识被应用程序所建立或使用的对象的唯一整数,WINDOWS使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等。WINDOWS句柄有点象C语言中的文件句柄。

二、MFC源代码:

#ifdef STRICT
typedef void *HANDLE;
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endif

DECLARE_HANDLE(HMODULE);
DECLARE_HANDLE(HINSTANCE);
DECLARE_HANDLE(HLOCAL);
DECLARE_HANDLE(HGLOBAL);
DECLARE_HANDLE(HDC);
DECLARE_HANDLE(HRGN);
DECLARE_HANDLE(HWND);
DECLARE_HANDLE(HMENU);
DECLARE_HANDLE(HACCEL);
DECLARE_HANDLE(HTASK);


三、理解:
HANDLE就是PVOID,也就是无类型指针,
上面这些资源的句柄Handles都不过是指向struct的指针,至于这个struct的用处,连M$都说unused了,现在解释下M$这么做的意义,这就是所谓数据封装,你可以在你的程序中把M$的内部结构指针传来传去,可是你却不知道它到底指向的内容是什么。

句柄与指针确实是完全不同的两个概念。句柄仅仅是一个32位整数,WIN32中用于标记某个系统或进程的对象,可以理解为对象索引(由于M$未完全公开相关技术,在一定程度上只能如此理解),这个索引更像是一种映射关系(从句柄到对象指针的映射),而不是纯粹意义上的“数组下标”。


句柄可以理解为用于指向或标识内存的一块“资源”,这些资源如:文件(file)、内存块(block of memory)、菜单(menu)等等。操作系统通过句柄来定位核心对象和系统资源。
指针即为指向内存的“数据或指令”某一单元。

说的确切一点,句柄实际上是一种指向某种资源的指针,但与指针又有所不同:指针对应着一个数据在内存中的地址,得到了指针就可以自由地修改该数据。Windows并不希望一般程序修改其内部数据结构,因为这样太不安全。所以Windows给每个使用GlobalAlloc等函数声明的内存区域指定一个句柄(本质上仍是一个指针,但不要直接操作它),平时你只是在调用API函数时利用这个句柄来说明要操作哪段内存。


四、引喻:
牧童遥指杏花村
牧童的手为指针,杏花村的牌子为句柄,杏花村酒店为对象的实例.


附注:获得窗口句柄三种方法

1.HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName)

HWND FindWindowEx(HWND hwndParent, HWND hwndChildAfter,LPCTSTR lpClassName, LPCTSTR lpWindowName)

2.HWND WindowFromPoint(POINT& Point)//获得当前鼠标光标位置的窗口HWND

3.BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)

BOOL CALLBACK EnumChildWindows(HWND hWndParent, WNDENUMPROC lpEnumFunc,LPARAM lParam)

BOOL CALLBACK EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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