当前位置:C++技术网 > 精选软件 > Windows零基础入门:4.5 获取窗口类所属的应用程序实例句柄

Windows零基础入门:4.5 获取窗口类所属的应用程序实例句柄

更新时间:2015-10-28 21:56:28浏览次数:1+次

    在前面的章节中,我们WNDCLASS结构体,它其中一个成员就是hInstance。它是一个实例句柄。我想,我们有必要再继续了解下。
    应用程序实例是由一个exe运行后产生的一个进程。而这个exe可以被运行很多次,也就产生了很多的进程。这里将这个exe视为单进程的程序,简化描述。而exe文件始终就只有一份,但是却产生了很多个进程。这里要排除程序限制exe一次只能运行一个进程的情况。而不管是哪样,这样创建出来的进程,就是一个应用程序的实例。每一次双击exe其实就是创建了一个应用程序的一个实例。那么这个实例就是用hInstance参数来唯一标识的。系统可以通过这个唯一的标识准确无误的停止一个实例的运行,而不会误伤其他实例。
    我们的窗口类是一个程序的界面,这个界面就是窗口。而这个窗口需要创建,就需要注册窗口类。有的窗口类是已经注册好的系统窗口类,有的是需要自己注册的。而每一个窗口类都是有与之关联的实例句柄的。这样就可以确定这个窗口类是在哪个实例注册的,也就是属于谁。
    而实例反应到内存层面,其实就是一段内存空间。那么窗口类属于不同的空间,也就在不同的空间中。在内存中,不同进程是相互隔离的,因此这个就是作用范围的问题。在一个进程注册的应用程序局部窗口类,就只能在这个进程内部的范围看见。
    有时候我们需要通过窗口的窗口类来确定这个进程的实例句柄,就可以个、通过窗口类关联的实例句柄来得到。得到实例句柄是有很多好处的,比如可以使用实例中的资源等。进程在内存中都视为模块,包括dll也是其中一个模块类型,因为他们都是以一个整体放在内存的一个区域的,这一段内存是连续的。这也是模块的叫法的依据之一。下面是一个简单的示意图,简单示意一下进程、dll都是以整块连续内存存储的,不必深究。

    Windows零基础入门:4.5 获取窗口类所属的应用程序实例句柄
    所以我们使用GetClassLong函数来获取窗口类对应的实例。别看这个函数第一个参数是窗口句柄,这里的窗口句柄只是作为一个中介罢了,最终都是与窗口类关联,这里讨论的就是窗口类关联的实例句柄。可以说窗口类属于这个实例句柄对应的进程。
    我们来获取这个句柄也是很简单的。代码如下:

HMODULE hModule = (HMODULE)GetClassLong(hwnd,GCL_HMODULE);
HICON hIcon = LoadIcon((HINSTANCE)hModule,lpIconName);
...

     这段代码是获取了窗口句柄hwnd对应的窗口类的实例句柄,然后通过实例句柄得到了lpIconName字符串名称指定的图标的句柄,然后后面就可以使用这个图标了。这里有几个地方需要解释下。
    我们前面说过了,GetClassLong返回值的类型永远是DWORD值,而这个类型只表示一个整数而已。但是示例句柄并不只是一个整数而已,有特别意义,所以是一个单独的类型。但是类型不一样,值是同一个,所以只要转换类型即可。这个好比1平时表示很小的一个数,但是在比赛的时候,这个1可不是一个数字那么简单。这个1可以代表第一,更多代表的是一个人的荣誉,一个国家的强大!虽然在内存中,HMODULE类型的值和DWORD值都是整数,区别就和上面的例子差不多。所以,我们返回的时候,要强制转换为模块句柄类型,这样就可以给hModule了。然而HMODULE是一个通用的类型,就好比学生是一个通用的称呼,具体的可以是大学生、中学生、初中生和小学生等。而模块句柄作为一个通用类型,指的是内存中那些一个整体区域存储的类型,比如进程、Dll等等。所以,我们要加载一个实例的资源,我们就要将这个通用类型转换成具体的类型传入LoadIcon函数。后面图标的使用,则不再这里说了。
    本节课并不难,知识点也不多,但是讨论的这些背景知识需要熟悉,也是对前面内容的巩固。