当前位置:C++技术网 > 资讯 > Windows零基础入门:4.1 获取窗口类信息之查询窗口类函数详细介绍

Windows零基础入门:4.1 获取窗口类信息之查询窗口类函数详细介绍

更新时间:2015-10-14 23:21:33浏览次数:1+次

    对于所有的世间万物来讲,生来病死,生死周期等等,无非可以总结为:增删改查!
    增即增加,从无到有叫做增加。增加是创造一个,让数量变多,或者从零到一。一个娃娃的出生叫做增,增加了一个家庭的人口,增加了世界上的一个人口,增加了家庭开销等等。
    删即删除,将已有的东西清除掉。万物凋零就是删除。计算机中删除文件等,太平常的事情了。
    改即修改,就是将一个东西的属性,比如人的坏毛病,一个字写错了,等等,都可以修正为另一个值。万事万物都是在不断的改,不断的变,变化的是属性的值而已。
    查即查询,就是得到一个东西的各个属性的信息,我们可以问,也可以投石问路等等。
    对于所有技术点,我们都可以遵循这四个操作,便可以将所有方面涵盖。对于一个信息或者一个事物来讲,只有这个四个,至于使用,则与他无关。使用是A拿B去修改A自己,对于B来讲,B没有任何改变,否则B就是在改变,也就是归类为改。在用B的过程,会造成A的属性改变,所以,如果B没有变,归类的中心是A,A在变。这里扯远了,不过就是说明这四点可以归类所有东西。暂时没有可以突破这四点的。不必纠结于这些东西。
    不管怎么样,对于编程来讲,所有信息无非就是这四点,如果你怕对于一个信息处理的不完整,请想到这四点,然后一个个解决,自然就是完整的。
    我们的窗口类,还差查和改两个环节。先来讲讲查询窗口类信息。

查询窗口类信息,GetClassLong
    对于获取窗口类信息来讲,因为前面讲了所有的基础知识,所以这里就简单了。主要介绍GetClassLong函数和GetClassLongPtr函数。
    这两个函数都是来查询窗口类信息的,所以函数名中含有Class单词。因为函数返回的值都是DWORD类型,和LONG类型的长度一样,将函数名取名为获取窗口类的LONG类型的值,意义在于表明函数返回的是通用的类型值。在获取了信息之后,一定要根据具体的类型转换一下。
    如果你要得到的是一个指针或者是句柄,这部分功能可以由GetClassLongPtr函数代替。GetClassLongPtr函数获取和处理非32位的值,更合适。因为在64位系统中,指针和句柄将是64位的,而在32位系统中指针和句柄的值才是32位的。为了让代码兼容性更强,除了获取和设置32位的DWORD值外的指针和句柄,建议使用GetClassLongPtr函数。使用上差不多,但是兼容性却大大提高了。
    GetClassLong函数和GetClassLongPtr声明如下:

DWORD WINAPI GetClassLong(HWND hWnd,int nIndex);
ULONG_PTR WINAPI GetClassLongPtr(HWND hWnd,int nIndex);
typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;
typedef unsigned long  DWORD;
     从声明中,我们可以看到,两个函数的参数一样,返回值似乎有点差别,不过在仔细看返回值类型,其实是一样的。只是ULONG_PTR类型重定义中多了一个_W64,编译器会根据这个标志来确定具体的类型的位数。如果是32位系统,则类型是32位的,如果是64位系统,则是64位的。
    GetClassLongPtr函数的Ptr全称为Pointer,就是指针的意思,这个函数就是强调了这一点,此函数对指针和句柄处理的更好。
    第一个参数为窗口的句柄。你可能会疑问,这里不是获取窗口类的信息吗?怎么指定的是窗口句柄作为参数呢?有疑问,最好是看MSDN的解释。MSDN解释说,这里确实是传入一个窗口的句柄,不过它会间接的指出这个窗口是由哪个窗口类创建出来的,从而就确定了窗口类了。
    是不是对于这种设计很困惑呢?有过开发经验的一定知道,我们经常操作窗口,都是用窗口句柄,我们并不关心这个窗口由哪个窗口类创建的。如果让你去获取窗口的窗口类名称,然后通过窗口类名称去获取窗口类的信息,则绕了一圈,实在是很麻烦。似乎还没有提供直接指定窗口类名称来获取窗口类信息的API函数。而通过指定窗口句柄,系统内部去找到这个窗口类,会让使用更加简单,出错率更低。不然写窗口类名字是容易出错的。实际上,这里是系统为我们多做了一步,应该明白这种设计初衷。
    那么第二个参数就是nIndex。这个参数的名字就是索引的意识,也就是一个编号。函数可以通过这个编号来查询对应的信息,编号就像是表格中的行号一样。
    这个编号可能取值都是固定的,因为函数提供的查询功能是有限的,或者说,窗口类的信息也是有限的。所以我们需要知道它的所有取值。Windows都为我们定义好了数字对应的宏,方便记忆和使用。
    GetClassLong的nIndex的可能取值如下:
GCW_ATOM:窗口类的唯一ID值。
GCL_CBCLSEXTRA:窗口类额外内存空间的字节数。
GCL_CBWNDEXTRA:窗口额外内存空间的字节数。
GCL_HBRBACKGROUND:窗口类指定的背景画刷句柄。
GCL_HCURSOR:窗口类执行的光标句柄。
GCL_HICON:窗口类指定的图标句柄。
GCL_HICONSM:窗口类指定的小图标句柄。
GCL_HMODULE:注册此窗口类的模块的句柄。
GCL_MENUNAME:窗口类指定的菜单名字字符串的指针。
GCL_STYLE:窗口类指定的窗口类风格。
GCL_WNDPROC:窗口类指定的窗口过程函数的地址或者代表窗口过程函数地址的句柄。

    GetClassLongPtr的nIndex的可能取值如下:
GCW_ATOM:窗口类的唯一ID值。
GCL_CBCLSEXTRA:窗口类额外内存空间的字节数。
GCL_CBWNDEXTRA:窗口额外内存空间的字节数。
GCLP_HBRBACKGROUND:窗口类指定的背景画刷句柄。
GCLP_HCURSOR:窗口类执行的光标句柄。 
GCLP_HICON:窗口类指定的图标句柄。
GCLP_HICONSM:窗口类指定的小图标句柄。
GCLP_HMODULE:注册此窗口类的模块的句柄。
GCLP_MENUNAME:窗口类指定的菜单名字字符串的指针。
GCL_STYLE:窗口类指定的窗口类风格。
GCLP_WNDPROC:窗口类指定的窗口过程函数的地址或者代表窗口过程函数地址的句柄。

    以上这些值,我将会单独详细解释,就不在这里铺开了。你可以看到,两个函数的取值宏的名字虽然不一样,但是一一对应,且作用是一样的。GCL是GetClassLong的缩写,GetClassLongPtr函数的取值宏就是在后面多加了一个P用来额外表面一下类型罢了。
    两个函数如果返回0表示失败,如果返回非零表示成功,返回值就是取出的需要的值。如果想知道出错的信息,可以调用GetLastError函数查询。