MSDN例程char szBuffer[80]; // print buffer for EnumResourceTypes DWORD cbWritten; // number of bytes written to res. info. file int cbString; // length of string in sprintf
BOOL EnumNamesFunc( HANDLE hModule, LPCTSTR lpType, LPTSTR lpName, LONG lParam);
BOOL EnumLangsFunc( HANDLE hModule, LPCTSTR lpType, LPCTSTR lpName, WORD wLang, LONG lParam);
// Load the .EXE whose resources you want to list. hExe = LoadLibrary("hand.exe");
if (hExe == NULL) { ErrorHandler("Could not load .EXE."); }
// Create a file to contain the resource info. hFile = CreateFile("resinfo.txt", // name of file GENERIC_READ | GENERIC_WRITE, // access mode 0, // share mode (LPSECURITY_ATTRIBUTES) NULL, // no security CREATE_ALWAYS, // create flags FILE_ATTRIBUTE_NORMAL, // file attributes (HANDLE) NULL); // no template if (hFile == INVALID_HANDLE_VALUE) { ErrorHandler("Could not open file."); }
// Find all of the loaded file's resources. cbString = sprintf(szBuffer, "The file contains the following resources:\n\n");
WriteFile(hFile, // file to hold resource info. szBuffer, // what to write to the file (DWORD) cbString, // number of bytes in szBuffer &cbWritten, // number of bytes written NULL); // no overlapped I/O
EnumResourceTypes(hExe, // module handle (ENUMRESTYPEPROC)EnumTypesFunc, // callback function 0); // extra parameter
// Unload the executable file whose resources were // enumerated and close the file created to contain // the resource information.
BOOL EnumTypesFunc( HANDLE hModule, // module handle LPTSTR lpType, // address of resource type LONG lParam) // extra parameter, could be // used for error checking { int cbString;
// Write the resource type to a resource information file. // The type may be a string or an unsigned decimal // integer, so test before printing.
BOOL EnumNamesFunc( HANDLE hModule, // module handle LPCTSTR lpType, // address of resource type LPTSTR lpName, // address of resource name LONG lParam) // extra parameter, could be // used for error checking { int cbString;
// Write the resource name to a resource information file. // The name may be a string or an unsigned decimal // integer, so test before printing.
// FUNCTION: EnumLangsFunc(HANDLE, LPSTR, LPSTR, WORD, LONG) // // PURPOSE: Resource language callback
BOOL EnumLangsFunc( HANDLE hModule, // module handle LPCTSTR lpType, // address of resource type LPCTSTR lpName, // address of resource name WORD wLang, // resource language LONG lParam) // extra parameter, could be used for error checking { HANDLE hResInfo; char szBuffer[80]; int cbString = 0;
谢谢大家,我把我的例子贴在下面,请高手看看:#define EXEEXAMPLE "C:\\temp\\shutdown.exe"HANDLE hFile; char szBuffer[256]; // print buffer for EnumResourceTypes DWORD cbWritten; // number of bytes written to res. info. file int cbString; // length of string in sprintf // Declare callback functions. BOOL EnumTypesFunc( HANDLE hModule, LPTSTR lpType, LONG lParam); BOOL EnumNamesFunc( HANDLE hModule, LPCTSTR lpType, LPTSTR lpName, LONG lParam); BOOL EnumLangsFunc( HANDLE hModule, LPCTSTR lpType, LPCTSTR lpName, WORD wLang, LONG lParam); char* ReadIconFromEXEFile( LPCTSTR szFileName,LPTSTR lpID , UINT uID) { char* lpIR = NULL, lpNew = NULL; HINSTANCE hLibrary;
// Load the DLL/EXE - NOTE: must be a 32bit EXE/DLL for this to work if( (hLibrary = LoadLibraryEx( szFileName, NULL, LOAD_LIBRARY_AS_DATAFILE )) == NULL ) { // Failed to load - abort MessageBox(AfxGetMainWnd()->m_hWnd , "装入文件时出错 - 请选择一个WIN32的DLL或EXE文件!", szFileName, MB_OK ); return NULL; }
FreeLibrary( hLibrary ); return lpIR; } // FUNCTION: EnumTypesFunc(HANDLE, LPSTR, LONG) // // PURPOSE: Resource type callback BOOL EnumTypesFunc( HANDLE hModule, // module handle LPTSTR lpType, // address of resource type LONG lParam) // extra parameter, could be // used for error checking { int cbString; // Write the resource type to a resource information file. // The type may be a string or an unsigned decimal // integer, so test before printing. if ((ULONG)lpType & 0xFFFF0000) { cbString = sprintf(szBuffer, "Type: %s \n", lpType,(lpType == RT_STRING?"STRING!":"")); } else { cbString = sprintf(szBuffer, "Type: %u %s\n", (USHORT)lpType,(lpType == RT_STRING?"STRING!":"")); }
// Find the names of all resources of type lpType. EnumResourceNames((struct HINSTANCE__ *)hModule, lpType, (ENUMRESNAMEPROC)EnumNamesFunc, 0);
return TRUE; } // FUNCTION: EnumNamesFunc(HANDLE, LPSTR, LPSTR, LONG) // // PURPOSE: Resource name callback BOOL EnumNamesFunc( HANDLE hModule, // module handle LPCTSTR lpType, // address of resource type LPTSTR lpName, // address of resource name LONG lParam) // extra parameter, could be // used for error checking { int cbString; // Write the resource name to a resource information file. // The name may be a string or an unsigned decimal // integer, so test before printing. if ((ULONG)lpName & 0xFFFF0000) { cbString = sprintf(szBuffer, "\tName: %s\n", lpName);
WriteFile(hFile, szBuffer, (DWORD) cbString, &cbWritten, NULL); // Find the languages of all resources of type // lpType and name lpName. /* EnumResourceLanguages((struct HINSTANCE__ *)hModule, lpType, lpName, (ENUMRESLANGPROC)EnumLangsFunc, 0); */ return TRUE; } void CResReaderDlg::OnOK() { char szBuffer[256]; // print buffer for EnumResourceTypes DWORD cbWritten; // number of bytes written to res. info. file size_t cbString; // length of string in sprintf HRESULT hResult; HINSTANCE hExe;
// Load the .EXE whose resources you want to list. hExe = LoadLibrary(EXEEXAMPLE); if (hExe == NULL) { TRACE0("Could not load .EXE."); }
// Create a file to contain the resource info. hFile = CreateFile("resinfo.txt", // name of file GENERIC_READ | GENERIC_WRITE, // access mode 0, // share mode (LPSECURITY_ATTRIBUTES) NULL, // no security CREATE_ALWAYS, // create flags FILE_ATTRIBUTE_NORMAL, // file attributes (HANDLE) NULL); // no template if (hFile == INVALID_HANDLE_VALUE) { TRACE0("Could not open file."); }
// Find all of the loaded file's resources. cbString = sprintf(szBuffer, "The file contains the following resources:\n\n"); WriteFile(hFile, // file to hold resource info. szBuffer, // what to write to the file (DWORD) cbString, // number of bytes in szBuffer &cbWritten, // number of bytes written NULL); // no overlapped I/O
EnumResourceTypes(hExe, // module handle (ENUMRESTYPEPROC)EnumTypesFunc, // callback function 0); // extra parameter // Unload the executable file whose resources were // enumerated and close the file created to contain // the resource information. FreeLibrary(hExe); CloseHandle(hFile);
CDialog::OnOK(); }
如何理解?Creating a Resource List The following example creates a list of every resource in the Hand.exe file. The list is written to the Resinfo.txt file. The code demonstrates how to load the executable file, create a file in which to write resource information, and call the EnumResourceTypes function to send each resource type found in the module to the application-defined callback function EnumTypesFunc. See EnumResTypeProc for information on callback functions of this type. This callback function uses the EnumResourceNames function to pass the name of every resource within the specified type to another application-defined callback function, EnumNamesFunc. See EnumResNameProc for information on callback functions of this type. EnumNamesFunc uses the EnumResourceLanguages function to pass the language of every resource of the specified type and name to a third callback function, EnumLangsFunc. See EnumResLangProc for information on callback functions of this type. EnumLangsFunc writes information about the resource of the specified type, name, and language to the Resinfo.txt file. Note that the lpszType in EnumResTypeProc is either a resource identifier (ID) or a pointer to a string (containing a resource ID or type name); lpszType and lpszName in EnumResNameProc are similar. To use an enumerated resource, take the resource name or ID and call the appropriate function. For example, to load a string resource (RT_STRING), if lpszName in EnumResNameProc gives the resource ID (either directly or in a string that starts with the pound sign (#)), call LoadString. Otherwise, lpszName points to a string containing the resource name, so do the following: call FindResource or FindResourceEx with the resource name to get the resource handle; call LoadResource with the resource handle to get the global handle; call LockResource with the global handle to get a pointer to the resource data.
依msdn所说:to load a string resource (RT_STRING), if lpszName in EnumResNameProc gives the resource ID (either directly or in a string that starts with the pound sign (#)), call LoadString. Otherwise, lpszName points to a string containing the resource name, so do the following: 我读出的却不是,为什么?请大家看看用#####表示的代码。
请问 yndfcd(YNDFCD): 如何得到资源id?您说的对,我发现我紧接着用方法: 1。call FindResource or FindResourceEx with the resource name to get the resource handle; 2。call LoadResource with the resource handle to get the global handle; 3。call LockResource with the global handle to get a pointer to the resource data 得到了数据,它是unicode格式,每一段前面都有一些0字符,如何知道它的结构?还有我发现它的lpName和真实的resource id似乎有关系。但这些数据里没有resource id, 为什么?请问各位大师:lpName由谁决定,是编译器吗?与resource id有关吗?
你只要看一看资源的二进制格式的说明就知道了,资源的前面是一个入口,它由一个header和存放的数据组成。一个资源入口的内容如下: A DWORD that contains the size of the resource header A DWORD that contains the size of the resource data The resource type The resource name Additional resource information 由于LockResource将指针直接指向了Additional resource information所以得不到name和ID。可以直接读资源文件到得到ID。不过MSDN上没有介绍,可能要找一些非正式文档。 参看MSDN:Win32 Resource File Formats
衷心祝愿各位帮我的人长命百岁! To jiagh(无会): 这种办法不是我想要的。我的问题是发现一些工具(包括VC)都可以读到resource id,而调用这些api则不行。DoItFreely(Freely),yndfcd(YNDFCD)说的有道理,我再去试试。等这个问题解决了,我一定写篇FAQ来报答各位的帮助!
见http://www.csdn.net/develop/article/17/17421.shtm,PE文件格式的介绍
DWORD cbWritten; // number of bytes written to res. info. file
int cbString; // length of string in sprintf
// Declare callback functions.
BOOL EnumTypesFunc(
HANDLE hModule,
LPTSTR lpType,
LONG lParam);
BOOL EnumNamesFunc(
HANDLE hModule,
LPCTSTR lpType,
LPTSTR lpName,
LONG lParam);
BOOL EnumLangsFunc(
HANDLE hModule,
LPCTSTR lpType,
LPCTSTR lpName,
WORD wLang,
LONG lParam);
// Load the .EXE whose resources you want to list.
hExe = LoadLibrary("hand.exe");
if (hExe == NULL)
{
ErrorHandler("Could not load .EXE.");
}
// Create a file to contain the resource info.
hFile = CreateFile("resinfo.txt", // name of file
GENERIC_READ | GENERIC_WRITE, // access mode
0, // share mode
(LPSECURITY_ATTRIBUTES) NULL, // no security
CREATE_ALWAYS, // create flags
FILE_ATTRIBUTE_NORMAL, // file attributes
(HANDLE) NULL); // no template
if (hFile == INVALID_HANDLE_VALUE) {
ErrorHandler("Could not open file.");
}
// Find all of the loaded file's resources.
cbString = sprintf(szBuffer,
"The file contains the following resources:\n\n");
WriteFile(hFile, // file to hold resource info.
szBuffer, // what to write to the file
(DWORD) cbString, // number of bytes in szBuffer
&cbWritten, // number of bytes written
NULL); // no overlapped I/O
EnumResourceTypes(hExe, // module handle
(ENUMRESTYPEPROC)EnumTypesFunc, // callback function
0); // extra parameter
// Unload the executable file whose resources were
// enumerated and close the file created to contain
// the resource information.
FreeLibrary(hExe);
CloseHandle(hFile);
// FUNCTION: EnumTypesFunc(HANDLE, LPSTR, LONG)
//
// PURPOSE: Resource type callback
BOOL EnumTypesFunc(
HANDLE hModule, // module handle
LPTSTR lpType, // address of resource type
LONG lParam) // extra parameter, could be
// used for error checking
{
int cbString;
// Write the resource type to a resource information file.
// The type may be a string or an unsigned decimal
// integer, so test before printing.
if ((ULONG)lpType & 0xFFFF0000)
{
cbString = sprintf(szBuffer, "Type: %s\n", lpType);
}
else
{
cbString = sprintf(szBuffer, "Type: %u\n", (USHORT)lpType);
}
WriteFile(hFile, szBuffer, (DWORD) cbString,
&cbWritten, NULL);
// Find the names of all resources of type lpType.
EnumResourceNames(hModule,
lpType,
(ENUMRESNAMEPROC)EnumNamesFunc,
0);
return TRUE;
}
// FUNCTION: EnumNamesFunc(HANDLE, LPSTR, LPSTR, LONG)
//
// PURPOSE: Resource name callback
BOOL EnumNamesFunc(
HANDLE hModule, // module handle
LPCTSTR lpType, // address of resource type
LPTSTR lpName, // address of resource name
LONG lParam) // extra parameter, could be
// used for error checking
{
int cbString;
// Write the resource name to a resource information file.
// The name may be a string or an unsigned decimal
// integer, so test before printing.
if ((ULONG)lpName & 0xFFFF0000)
{
cbString = sprintf(szBuffer, "\tName: %s\n", lpName);
}
else
{
cbString = sprintf(szBuffer, "\tName: %u\n",
(USHORT)lpName);
}
WriteFile(hFile, szBuffer, (DWORD) cbString,
&cbWritten, NULL);
// Find the languages of all resources of type
// lpType and name lpName.
EnumResourceLanguages(hModule,
lpType,
lpName,
(ENUMRESLANGPROC)EnumLangsFunc,
0);
return TRUE;
}
// FUNCTION: EnumLangsFunc(HANDLE, LPSTR, LPSTR, WORD, LONG)
//
// PURPOSE: Resource language callback
BOOL EnumLangsFunc(
HANDLE hModule, // module handle
LPCTSTR lpType, // address of resource type
LPCTSTR lpName, // address of resource name
WORD wLang, // resource language
LONG lParam) // extra parameter, could be
used for error checking
{
HANDLE hResInfo;
char szBuffer[80];
int cbString = 0;
hResInfo = FindResourceEx(hModule, lpType, lpName, wLang);
// Write the resource language to the resource information file.
cbString = sprintf(szBuffer, "\t\tLanguage: %u\n", USHORT)wLang);
WriteFile(hFile, szBuffer, (DWORD) cbString,
&cbWritten, NULL);
// Write the resource handle and size to buffer.
cbString = sprintf(szBuffer,
"\t\thResInfo == %lx, Size == %lu\n\n",
hResInfo,
SizeofResource(hModule, hResInfo));
WriteFile(hFile, szBuffer, (DWORD) cbString,
&cbWritten, NULL);
return TRUE;
}
char szBuffer[256]; // print buffer for EnumResourceTypes
DWORD cbWritten; // number of bytes written to res. info. file
int cbString; // length of string in sprintf // Declare callback functions.
BOOL EnumTypesFunc(
HANDLE hModule,
LPTSTR lpType,
LONG lParam); BOOL EnumNamesFunc(
HANDLE hModule,
LPCTSTR lpType,
LPTSTR lpName,
LONG lParam); BOOL EnumLangsFunc(
HANDLE hModule,
LPCTSTR lpType,
LPCTSTR lpName,
WORD wLang,
LONG lParam); char* ReadIconFromEXEFile( LPCTSTR szFileName,LPTSTR lpID , UINT uID)
{
char* lpIR = NULL, lpNew = NULL;
HINSTANCE hLibrary;
// Load the DLL/EXE - NOTE: must be a 32bit EXE/DLL for this to work
if( (hLibrary = LoadLibraryEx( szFileName, NULL, LOAD_LIBRARY_AS_DATAFILE )) == NULL )
{
// Failed to load - abort
MessageBox(AfxGetMainWnd()->m_hWnd , "装入文件时出错 - 请选择一个WIN32的DLL或EXE文件!", szFileName, MB_OK );
return NULL;
}
HRSRC hRsrc = NULL;
HGLOBAL hGlobal = NULL;
UINT i;
// Find the group icon resource
if( (hRsrc = FindResource( hLibrary, lpID, RT_STRING )) == NULL )
{
FreeLibrary( hLibrary );
return NULL;
}
if( (hGlobal = LoadResource( hLibrary, hRsrc )) == NULL )
{
FreeLibrary( hLibrary );
return NULL;
}
memset (szBuffer, 0, 1000);
//###################################################################
//这样也读不到字符串内容. why???????????????????????????
//###################################################################
memcpy(szBuffer, LockResource(hGlobal),100);
////cbString = sprintf(szBuffer, "\tresource = %s\n", szBuffer);
//WriteFile(hFile, szBuffer, (DWORD) 100, &cbWritten, NULL);
memset (szBuffer, 0, 1000);
//###################################################################
//uID不是从vc中读出的id. why???????????????????????????
//###################################################################
LoadString(hLibrary, // handle to resource module
uID, // resource identifier
szBuffer, // resource buffer
256 // size of buffer
);
TRACE0(szBuffer);
cbString = sprintf(szBuffer, "\t %s\n", szBuffer);
WriteFile(hFile, szBuffer, (DWORD) cbString, &cbWritten, NULL);
FreeLibrary( hLibrary );
return lpIR;
}
// FUNCTION: EnumTypesFunc(HANDLE, LPSTR, LONG)
//
// PURPOSE: Resource type callback
BOOL EnumTypesFunc(
HANDLE hModule, // module handle
LPTSTR lpType, // address of resource type
LONG lParam) // extra parameter, could be
// used for error checking
{
int cbString;
// Write the resource type to a resource information file.
// The type may be a string or an unsigned decimal
// integer, so test before printing.
if ((ULONG)lpType & 0xFFFF0000)
{
cbString = sprintf(szBuffer, "Type: %s \n", lpType,(lpType == RT_STRING?"STRING!":""));
}
else
{
cbString = sprintf(szBuffer, "Type: %u %s\n", (USHORT)lpType,(lpType == RT_STRING?"STRING!":""));
}
WriteFile(hFile, szBuffer, (DWORD) cbString,
&cbWritten, NULL);
// Find the names of all resources of type lpType.
EnumResourceNames((struct HINSTANCE__ *)hModule,
lpType,
(ENUMRESNAMEPROC)EnumNamesFunc,
0);
return TRUE;
} // FUNCTION: EnumNamesFunc(HANDLE, LPSTR, LPSTR, LONG)
//
// PURPOSE: Resource name callback
BOOL EnumNamesFunc(
HANDLE hModule, // module handle
LPCTSTR lpType, // address of resource type
LPTSTR lpName, // address of resource name
LONG lParam) // extra parameter, could be
// used for error checking
{
int cbString;
// Write the resource name to a resource information file.
// The name may be a string or an unsigned decimal
// integer, so test before printing.
if ((ULONG)lpName & 0xFFFF0000)
{
cbString = sprintf(szBuffer, "\tName: %s\n", lpName);
if (lpType == RT_STRING){
ReadIconFromEXEFile( EXEEXAMPLE, lpName, 0);
};
}
else
{
//######################################################
// 为什么这儿得不到正确的id.????????????
//
//######################################################
cbString = sprintf(szBuffer, "\tName: %u\n",
(USHORT)lpName);
if (lpType == RT_STRING){
ReadIconFromEXEFile( EXEEXAMPLE, lpName, (USHORT)lpName);
};
}
WriteFile(hFile, szBuffer, (DWORD) cbString,
&cbWritten, NULL);
// Find the languages of all resources of type
// lpType and name lpName.
/*
EnumResourceLanguages((struct HINSTANCE__ *)hModule,
lpType,
lpName,
(ENUMRESLANGPROC)EnumLangsFunc,
0);
*/
return TRUE;
}
void CResReaderDlg::OnOK()
{
char szBuffer[256]; // print buffer for EnumResourceTypes
DWORD cbWritten; // number of bytes written to res. info. file
size_t cbString; // length of string in sprintf
HRESULT hResult;
HINSTANCE hExe;
// Load the .EXE whose resources you want to list.
hExe = LoadLibrary(EXEEXAMPLE);
if (hExe == NULL)
{
TRACE0("Could not load .EXE.");
}
// Create a file to contain the resource info.
hFile = CreateFile("resinfo.txt", // name of file
GENERIC_READ | GENERIC_WRITE, // access mode
0, // share mode
(LPSECURITY_ATTRIBUTES) NULL, // no security
CREATE_ALWAYS, // create flags
FILE_ATTRIBUTE_NORMAL, // file attributes
(HANDLE) NULL); // no template
if (hFile == INVALID_HANDLE_VALUE) {
TRACE0("Could not open file.");
}
// Find all of the loaded file's resources.
cbString = sprintf(szBuffer,
"The file contains the following resources:\n\n");
WriteFile(hFile, // file to hold resource info.
szBuffer, // what to write to the file
(DWORD) cbString, // number of bytes in szBuffer
&cbWritten, // number of bytes written
NULL); // no overlapped I/O
EnumResourceTypes(hExe, // module handle
(ENUMRESTYPEPROC)EnumTypesFunc, // callback function
0); // extra parameter
// Unload the executable file whose resources were
// enumerated and close the file created to contain
// the resource information.
FreeLibrary(hExe);
CloseHandle(hFile);
CDialog::OnOK();
}
The following example creates a list of every resource in the Hand.exe file. The list is written to the Resinfo.txt file. The code demonstrates how to load the executable file, create a file in which to write resource information, and call the EnumResourceTypes function to send each resource type found in the module to the application-defined callback function EnumTypesFunc. See EnumResTypeProc for information on callback functions of this type. This callback function uses the EnumResourceNames function to pass the name of every resource within the specified type to another application-defined callback function, EnumNamesFunc. See EnumResNameProc for information on callback functions of this type. EnumNamesFunc uses the EnumResourceLanguages function to pass the language of every resource of the specified type and name to a third callback function, EnumLangsFunc. See EnumResLangProc for information on callback functions of this type. EnumLangsFunc writes information about the resource of the specified type, name, and language to the Resinfo.txt file. Note that the lpszType in EnumResTypeProc is either a resource identifier (ID) or a pointer to a string (containing a resource ID or type name); lpszType and lpszName in EnumResNameProc are similar. To use an enumerated resource, take the resource name or ID and call the appropriate function. For example, to load a string resource (RT_STRING), if lpszName in EnumResNameProc gives the resource ID (either directly or in a string that starts with the pound sign (#)), call LoadString. Otherwise, lpszName points to a string containing the resource name, so do the following: call FindResource or FindResourceEx with the resource name to get the resource handle;
call LoadResource with the resource handle to get the global handle;
call LockResource with the global handle to get a pointer to the resource data.
// 为什么这儿得不到正确的id.????????????
//
//######################################################
此处读取的是资源的名称,而不是ID,
1。call FindResource or FindResourceEx with the resource name to get the resource handle;
2。call LoadResource with the resource handle to get the global handle;
3。call LockResource with the global handle to get a pointer to the resource data
得到了数据,它是unicode格式,每一段前面都有一些0字符,如何知道它的结构?还有我发现它的lpName和真实的resource id似乎有关系。但这些数据里没有resource id, 为什么?请问各位大师:lpName由谁决定,是编译器吗?与resource id有关吗?
并不要什么高深的PE格式!只需看看就会了!
1:我们先用VC把DLL或EXE文件打开(以资源编辑的形式打开),并找出你要获取的资源的ID号,并记下!
2:在你的代码中用LoadLibrary(DLL或EXE) 来获得句柄,然后再用LoadString, LoadCursor,LoadImage 等等的函数去得到你要的资源!
这不是很简单吗?下面是我刚才做的例子:我要从test.exe中得到字符串资源。于是我用VC把test.exe打开,得到ID号是101和102两个。
于在我的代码中将这样的取资源:
#include "stdafx.h"
#include <windows.h>
#include <iostream.h>#define STR1 101
#define STR2 102char *filename="test.exe";
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE m_h=::LoadLibrary(filename);
char *pstr = new char[50];
if (m_h!=NULL)
{
int m_size=LoadString((HINSTANCE)m_h,STR1,pstr,50);
if( m_size>0 )
{
cout<<pstr<<endl;
}
else
{
cout<<"failed LoadString"<<endl;
}
}else
{
cout<<"LoadLibrary failed"<<endl;
}
return 0;
}大家不妨去试一试!
A DWORD that contains the size of the resource header
A DWORD that contains the size of the resource data
The resource type
The resource name
Additional resource information
由于LockResource将指针直接指向了Additional resource information所以得不到name和ID。可以直接读资源文件到得到ID。不过MSDN上没有介绍,可能要找一些非正式文档。
参看MSDN:Win32 Resource File Formats
EnumResourceLanguages / EnumResourceTypes / EnumResourceNames回调
BOOL CALLBACK EnumResNameProc(
HMODULE hModule, // module handle
LPCTSTR lpszType, // resource type
LPTSTR lpszName, // resource name
LONG_PTR lParam // application-defined parameter
);回调函数返回的 lpszName 有几种情况:
1、(lpszName & 0xFFFF0000) == 0 即 (UINT)lpszName < 65536 则
Resource Id = (UINT)lpszName;2、否则,lpszName 指向一个 String , 如果 lpszName[0] == _T("#") 且 lpszName[1] 以后完全为数字,如 "#1024" ,则
Resource Id = _ttoi(&lpszName[1]); // "#1024" --> id = 10243、此时该资源没有 id ,仅有名称 lpszName