当一个文件被映射到调用进程的地址空间时,GetModuleHandle函数得到其中某一模块的句柄。
使用GetModuleHandle函数格式:
HMODULE GetModuleHandle( LPCTSTR lpModuleName);
参数 lpModuleName:
[in]用指针指向一个包含模块名以NULL字符结尾的串,模块是.dll或.exe文件。如果文件扩展名省略,则增加默认的扩展名.dll。文件名串可以是省略号(...),表示模块名没有扩展名。这个串不是必须指定一个路径。当指定一个路径时,确定要用反斜线(\),而不是斜线(/)。这个模块名将和当前映射到调用进程地址空间的模块名进行独立地比较。 假如这个参数是NULL,函数将返回创建调用进程(.exe文件)的文件的句柄。
返回值:
如果函数调用成功,返回值是某一模块的句柄。 如果函数调用失败,返回NULL。要得知更多的出错信息,调用GetLastError。
注释:
返回句柄不是全局的或可继承的。它不能被其它进程复制或使用。 假如lpModuleName没有包含路径,而且有多个相同的文件名和扩展名,将不能预测返回哪一个模块的句柄。要解决这个问题,需要指定路径。用side-by-side assemblies指定,或用GetModuleHandleEx来指定一个内存区而不是一个DLL名。 GetModuleHandle函数对一个映像的模块返回一个句柄,而不会增加引用(reference)数。然而,在传递这个句柄给FreeLibrary函数时,要当心,因为,这样传递会导致一个DLL模块过早地不能被映像。 这个函数在多线程程序中必须谨慎使用。不能保证这个模块句柄在函数返回时和使用时是有效的。比如,一个线程得到模块句柄,但在使用这个句柄之前,第二个线程释放了这个模块。假如这个系统载入另一个模块,它可以再次使用最近释放了的句柄。然而,第一个线程拥有一个模块的句柄,这个模块不同于先前那个模块。
使用GetModuleHandle函数格式:
HMODULE GetModuleHandle( LPCTSTR lpModuleName);
参数 lpModuleName:
[in]用指针指向一个包含模块名以NULL字符结尾的串,模块是.dll或.exe文件。如果文件扩展名省略,则增加默认的扩展名.dll。文件名串可以是省略号(...),表示模块名没有扩展名。这个串不是必须指定一个路径。当指定一个路径时,确定要用反斜线(\),而不是斜线(/)。这个模块名将和当前映射到调用进程地址空间的模块名进行独立地比较。 假如这个参数是NULL,函数将返回创建调用进程(.exe文件)的文件的句柄。
返回值:
如果函数调用成功,返回值是某一模块的句柄。 如果函数调用失败,返回NULL。要得知更多的出错信息,调用GetLastError。
注释:
返回句柄不是全局的或可继承的。它不能被其它进程复制或使用。 假如lpModuleName没有包含路径,而且有多个相同的文件名和扩展名,将不能预测返回哪一个模块的句柄。要解决这个问题,需要指定路径。用side-by-side assemblies指定,或用GetModuleHandleEx来指定一个内存区而不是一个DLL名。 GetModuleHandle函数对一个映像的模块返回一个句柄,而不会增加引用(reference)数。然而,在传递这个句柄给FreeLibrary函数时,要当心,因为,这样传递会导致一个DLL模块过早地不能被映像。 这个函数在多线程程序中必须谨慎使用。不能保证这个模块句柄在函数返回时和使用时是有效的。比如,一个线程得到模块句柄,但在使用这个句柄之前,第二个线程释放了这个模块。假如这个系统载入另一个模块,它可以再次使用最近释放了的句柄。然而,第一个线程拥有一个模块的句柄,这个模块不同于先前那个模块。
GetModuleHandle和AfxGetInstanceHandle和CWinApp->m_hInstance的区别
在工作中遇到一个问题,就是在一个DLL中想改变这个DLL的窗口的ICON,于是写了如下的代码:
HICON hicon=LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_ICON1));
if (hicon!=NULL)
{
LRESULT result=SendMessage(m_hWnd,WM_SETICON,ICON_SMALL,(LPARAM)hicon);
}
HICON hicon=LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_ICON1));
if (hicon!=NULL)
{
LRESULT result=SendMessage(m_hWnd,WM_SETICON,ICON_SMALL,(LPARAM)hicon);
}
结果发现没有成功,hicon=NULL,调试发现是LastError=1813,说是找不到指定的资源。
后面换成了这样的代码就可以了:
HICON hicon=LoadIcon(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDI_ICON1));
if (hicon!=NULL)
{
LRESULT result=SendMessage(m_hWnd,WM_SETICON,ICON_SMALL,(LPARAM)hicon);
}
HICON hicon=LoadIcon(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDI_ICON1));
if (hicon!=NULL)
{
LRESULT result=SendMessage(m_hWnd,WM_SETICON,ICON_SMALL,(LPARAM)hicon);
}
换成下面这种也可以:
HICON hicon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));
if (hicon!=NULL)
{
LRESULT result=SendMessage(m_hWnd,WM_SETICON,ICON_SMALL,(LPARAM)hicon);
}
HICON hicon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));
if (hicon!=NULL)
{
LRESULT result=SendMessage(m_hWnd,WM_SETICON,ICON_SMALL,(LPARAM)hicon);
}
百思不得其解,后面查MSDN和网络,了解到是由于DLL的句柄跟Application的句柄混淆不清的原因,这里需要的是DLL的句柄。
1.GetModuleHandle(LPCTSTR lpModuleName)
If this parameter is NULL, GetModuleHandle returns a handle to the file used to create the calling process (.exe file).
如果参数为空,那么获取的就是调用这个DLL 的exe的 句柄,也即application句柄,而不是DLL的句柄
If this parameter is NULL, GetModuleHandle returns a handle to the file used to create the calling process (.exe file).
如果参数为空,那么获取的就是调用这个DLL 的exe的 句柄,也即application句柄,而不是DLL的句柄
如果要获得当前DLL的句柄,要传入DLL的名称即可。
2.AfxGetInstanceHandle()
An HINSTANCE to the current instance of the application. If called from within a DLL linked with the USRDLL version of MFC, an HINSTANCE to the DLL is returned.
返回的是一个application的句柄,但是如果这个函数是从一个MFC的USRDLL版本DLL的内部被调用,那么返回的就是这个DLL的句柄
An HINSTANCE to the current instance of the application. If called from within a DLL linked with the USRDLL version of MFC, an HINSTANCE to the DLL is returned.
返回的是一个application的句柄,但是如果这个函数是从一个MFC的USRDLL版本DLL的内部被调用,那么返回的就是这个DLL的句柄
3.CWinApp->m_hInstance
The m_hInstance data member is a handle to the current instance of the application running under Windows. This is returned by the global function AfxGetInstanceHandle. m_hInstance is a public variable of type HINSTANCE.
因为它是从 AfxGetInstanceHandle()返回来获得的,所以跟AfxGetInstanceHandle()的返回值一样。
The m_hInstance data member is a handle to the current instance of the application running under Windows. This is returned by the global function AfxGetInstanceHandle. m_hInstance is a public variable of type HINSTANCE.
因为它是从 AfxGetInstanceHandle()返回来获得的,所以跟AfxGetInstanceHandle()的返回值一样。