扬州谢馥春喷雾好用吗:什么是句柄?

来源:百度文库 编辑:高校问答 时间:2024/04/28 14:57:26

句柄是整个windows编程的基础。一个句柄是指使用的一个唯一的整数值,即一个四字节长的数值,来标识应用程序中的不同对象和同类对象中的不同的实例,诸如,一个窗口、按钮、图标、滚动条、输出设备、控件或者文件等。句柄是windows用来标志应用程序中建立的或是使用的唯一整数,windows使用了大量的句柄来标志很多对象。应用程序能够通过句柄访问相应的对象的信息,但是句柄不是一个指针,程序不能利用句柄来直接阅读文件中的信息。如果句柄不用在I/O文件中,它是毫无用处的。

1.句柄是找到一块内存的索引,作用:找到内存后通过调用Windows函数来修改数据
2.跟指针的区别是,我们通过指针可以直接修改里面的数据,不需要通过Windows函数来修改
3.微软这样做的原因是:封装重要的数据,不让我们自己直接修改,怕我们修改坏了。要修改通过委托Windows来修改

句柄是一个(通常为32位的)整数,它代表一个对象。Windows中的句柄类似传统C或者MS-DOS程序设计中使用的文件句柄。程序几乎总是通过呼叫Windows函数取得句柄。程序在其它Windows函数中使用这个句柄,以使用它代表的对象。

在 Windows 中,窗口可以有许多种。窗口可以是屏幕上的一块矩形封闭区域,比如您熟悉的应用程序窗口。窗体上的控件(例如列表框或滚动条)也可以是窗口,但并不是所有类型的控件都是窗口。桌面上的图标和桌面本身也是窗口。因为所有这些类型的对象都是窗口,所以 Windows 可以用类似的方式处理它们。Windows 给每个窗口一个唯一的句柄,通过句柄操纵该窗口。许多 API 函数可返回句柄或者接受句柄作参数。

创建窗口时,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的转化问题)

神呀,救救那些头脑呆板、一知半解的人吧!