首页 > 代码库 > 实例句柄

实例句柄

Windows应用程序中,总需要加载应用程序文件到系统内存里,为了标识每个文件在内存的区别,Windows使用了句柄来标识这些文件。比如在一个应用程序里,有一个可执行文件(EXE)和多个动态连接库文件(DLL),这时可以标识可执行文件为0x1D000000,动态连接库文件为0x1D001000。这里的值只是举例,当系统运行应用程序时,就会分配实际的值给应用程序。加载到进程地址空间的每一个可执行文件或是DLL文件都被赋予了一个独一无二的实例句柄。可执行文件的实例句柄就是(w)WinMain函数的第一个参数hInstance。传递这个参数给Windows应用程序,这样在C语言编写的应用程序里,就可以从这个参数拿到Windows应用程序实例句柄了。在很多函数中都用到这个参数,例如:为了从可执行文件加载一个图标资源:

HICON   LoadIconHINSTANCE   hInstance ,   PCTSTR   pszIcdon

这里的第一个参数hInstance就是Windows应用程序实例句柄,如果想从EXE文件里加载图标,就把EXE文件的句柄传入;如果想从DLL文件里加载图标,就把DLL文件的句柄传入。hInstance参数实际上就是一个内存基地址,系统将可执行文件的映像加载到进程地址空间的这个位置。但是在Python的应用程序里,它的入口函数并不能直接拿到这个实例句柄参数,只能另想它法。山重水复疑无路,柳暗花明又一村。在浏览Win32API里,可以找到两个相关的API函数:GetModuleHandleGetModuleHandleEx。这两个函数都可以获取文件的实例句柄,它们的区别是GetModuleHandle适用单线程获取句柄,不增加模块的引用计数;GetModuleHandleEx可用于多线程句柄,可以增加模块的引用计数,因此每调用一次这个函数,就要释放一次库的引用计数。在Python的应用程序里,就可以使用这两个函数来获取实例句柄,如下面的例子:

#windows应用程序

#开发人员:蔡军生(QQ9073204) 深圳  2014-8-12

from ctypes import *

from ctypes.wintypes import *

 

hInst = windll.kernel32.GetModuleHandleW(None)

print(‘hInst: 0x%X‘ % hInst)

在这个例子里,聪明的你也许发现多导入了一个模块ctypes.wintypeswintypes是干什么用的呢?从前面学习ctypes已经知道可以使用ctypes里的类型,但是在转换为WIN32API时,就要记住比较多类型了。幸运的是wintypes已经帮我们做好基本常用的类型,比如:BYTEWORDDWORDUINTBOOLLPCWSTRCOLORREFHANDLEHWNDRECT等类型,如果需要更多关于这些类型,请查看python\Lib\ctypes\wintypes.py。有了这些类型,你就可以在Python里跟WIN32API的数据类型使用相同的形式了,而不必自己再去做脑力上的转换,这样可以省下不少时间,会大大提高开发效率。在这里通过windll.kernel32.GetModuleHandleW语句就可以获取当前进程的实例句柄,有了实例句柄,就可以向这个程序创建窗口、创建字体等事情了。