Uso de recursos
Esta sección contiene fragmentos de código para las siguientes tareas:
Actualización de recursos
En el ejemplo siguiente se copia un recurso de cuadro de diálogo de un archivo ejecutable, Hand.exe, a otro, Foot.exe, siguiendo estos pasos:
- Use la función LoadLibrary para cargar el archivo ejecutable Hand.exe.
- Use las funciones FindResource y LoadResource para buscar y cargar el recurso del cuadro de diálogo.
- Use la función LockResource para recuperar un puntero a los datos de recursos del cuadro de diálogo.
- Use la función BeginUpdateResource para abrir un identificador de actualización para Foot.exe.
- Use la función UpdateResource para copiar el recurso del cuadro de diálogo de Hand.exe a Foot.exe.
- Use la función EndUpdateResource para completar la actualización.
El código siguiente implementa estos pasos.
Advertencia de seguridad: El uso incorrecto de LoadLibrary puede poner en peligro la seguridad de la aplicación cargando el archivo DLL incorrecto. Consulte la documentación de LoadLibrary para obtener información sobre cómo cargar correctamente archivos DLL con diferentes versiones de Windows.
HGLOBAL hResLoad; // handle to loaded resource
HMODULE hExe; // handle to existing .EXE file
HRSRC hRes; // handle/ptr. to res. info. in hExe
HANDLE hUpdateRes; // update resource handle
LPVOID lpResLock; // pointer to resource data
BOOL result;
#define IDD_HAND_ABOUTBOX 103
#define IDD_FOOT_ABOUTBOX 110
// Load the .EXE file that contains the dialog box you want to copy.
hExe = LoadLibrary(TEXT("hand.exe"));
if (hExe == NULL)
{
ErrorHandler(TEXT("Could not load exe."));
return;
}
// Locate the dialog box resource in the .EXE file.
hRes = FindResource(hExe, MAKEINTRESOURCE(IDD_HAND_ABOUTBOX), RT_DIALOG);
if (hRes == NULL)
{
ErrorHandler(TEXT("Could not locate dialog box."));
return;
}
// Load the dialog box into global memory.
hResLoad = LoadResource(hExe, hRes);
if (hResLoad == NULL)
{
ErrorHandler(TEXT("Could not load dialog box."));
return;
}
// Lock the dialog box into global memory.
lpResLock = LockResource(hResLoad);
if (lpResLock == NULL)
{
ErrorHandler(TEXT("Could not lock dialog box."));
return;
}
// Open the file to which you want to add the dialog box resource.
hUpdateRes = BeginUpdateResource(TEXT("foot.exe"), FALSE);
if (hUpdateRes == NULL)
{
ErrorHandler(TEXT("Could not open file for writing."));
return;
}
// Add the dialog box resource to the update list.
result = UpdateResource(hUpdateRes, // update resource handle
RT_DIALOG, // change dialog box resource
MAKEINTRESOURCE(IDD_FOOT_ABOUTBOX), // dialog box id
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), // neutral language
lpResLock, // ptr to resource info
SizeofResource(hExe, hRes)); // size of resource info
if (result == FALSE)
{
ErrorHandler(TEXT("Could not add resource."));
return;
}
// Write changes to FOOT.EXE and then close it.
if (!EndUpdateResource(hUpdateRes, FALSE))
{
ErrorHandler(TEXT("Could not write changes to file."));
return;
}
// Clean up.
if (!FreeLibrary(hExe))
{
ErrorHandler(TEXT("Could not free executable."));
return;
}
Creación de una lista de recursos
En el ejemplo siguiente se crea una lista de todos los recursos del archivo Hand.exe. La lista se escribe en el archivo Resinfo.txt.
El código muestra cómo cargar el archivo ejecutable, crear un archivo en el que escribir información de recursos y llamar a la función EnumResourceTypes para enviar cada tipo de recurso que se encuentra en el módulo a la función EnumTypesFunc
de devolución de llamada definida por la aplicación . Vea EnumResTypeProc para obtener información sobre las funciones de devolución de llamada de este tipo. Esta función de devolución de llamada usa la función EnumResourceNames para pasar el nombre de cada recurso dentro del tipo especificado a otra función de devolución de llamada definida por la aplicación, EnumNamesFunc
. Vea EnumResNameProc para obtener información sobre las funciones de devolución de llamada de este tipo.
EnumNamesFunc
usa la función EnumResourceLanguages para pasar el lenguaje de todos los recursos del tipo y el nombre especificados a una tercera función de devolución de llamada, EnumLangsFunc
. Vea EnumResLangProc para obtener información sobre las funciones de devolución de llamada de este tipo.
EnumLangsFunc
escribe información sobre el recurso del tipo, el nombre y el idioma especificados en el archivo Resinfo.txt.
Tenga en cuenta que lpszType en EnumResTypeProc es un identificador de recurso o un puntero a una cadena (que contiene un identificador de recurso o un nombre de tipo); lpszType y lpszName en EnumResNameProc y EnumResLangProc son similares. Para cargar un recurso enumerado, simplemente llame a la función adecuada. Por ejemplo, si se enumera un recurso de menú (RT_MENU), pase lpszName a LoadMenu. Para recursos personalizados, pase lpszType y lpszName a FindResource.
El código actualizar recursos sigue un patrón similar para un recurso de cuadro de diálogo.
Advertencia de seguridad: El uso incorrecto de LoadLibrary puede poner en peligro la seguridad de la aplicación cargando el archivo DLL incorrecto. Consulte la documentación de LoadLibrary para obtener información sobre cómo cargar correctamente archivos DLL con diferentes versiones de Windows.
HANDLE g_hFile; // global handle to resource info file
// Declare callback functions.
BOOL EnumTypesFunc(
HMODULE hModule,
LPTSTR lpType,
LONG lParam);
BOOL EnumNamesFunc(
HMODULE hModule,
LPCTSTR lpType,
LPTSTR lpName,
LONG lParam);
BOOL EnumLangsFunc(
HMODULE hModule,
LPCTSTR lpType,
LPCTSTR lpName,
WORD wLang,
LONG lParam);
HMODULE hExe; // handle to .EXE file
TCHAR szBuffer[80]; // print buffer for info file
DWORD cbWritten; // number of bytes written to resource info file
size_t cbString; // length of string in szBuffer
HRESULT hResult;
// Load the .EXE whose resources you want to list.
hExe = LoadLibrary(TEXT("hand.exe"));
if (hExe == NULL)
{
// Add code to fail as securely as possible.
return;
}
// Create a file to contain the resource info.
g_hFile = CreateFile(TEXT("resinfo.txt"), // name of file
GENERIC_READ | GENERIC_WRITE, // access mode
0, // share mode
(LPSECURITY_ATTRIBUTES) NULL, // default security
CREATE_ALWAYS, // create flags
FILE_ATTRIBUTE_NORMAL, // file attributes
(HANDLE) NULL); // no template
if (g_hFile == INVALID_HANDLE_VALUE)
{
ErrorHandler(TEXT("Could not open file."));
return;
}
// Find all of the loaded file's resources.
hResult = StringCchPrintf(szBuffer, sizeof(szBuffer)/sizeof(TCHAR),
TEXT("The file contains the following resources:\r\n\r\n"));
if (FAILED(hResult))
{
// Add code to fail as securely as possible.
return;
}
hResult = StringCchLength(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), &cbString);
if (FAILED(hResult))
{
// Add code to fail as securely as possible.
return;
}
WriteFile(g_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(g_hFile);
// FUNCTION: EnumTypesFunc(HANDLE, LPSTR, LONG)
//
// PURPOSE: Resource type callback
BOOL EnumTypesFunc(
HMODULE hModule, // module handle
LPTSTR lpType, // address of resource type
LONG lParam) // extra parameter, could be
// used for error checking
{
TCHAR szBuffer[80]; // print buffer for info file
DWORD cbWritten; // number of bytes written to resource info file
size_t cbString;
HRESULT hResult;
// 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 (!IS_INTRESOURCE(lpType))
{
hResult = StringCchPrintf(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), TEXT("Type: %s\r\n"), lpType);
if (FAILED(hResult))
{
// Add code to fail as securely as possible.
return FALSE;
}
}
else
{
hResult = StringCchPrintf(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), TEXT("Type: %u\r\n"), (USHORT)lpType);
if (FAILED(hResult))
{
// Add code to fail as securely as possible.
return FALSE;
}
}
hResult = StringCchLength(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), &cbString);
if (FAILED(hResult))
{
// Add code to fail as securely as possible.
return FALSE;
}
WriteFile(g_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(
HMODULE 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
{
TCHAR szBuffer[80]; // print buffer for info file
DWORD cbWritten; // number of bytes written to resource info file
size_t cbString;
HRESULT hResult;
// 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 (!IS_INTRESOURCE(lpName))
{
hResult = StringCchPrintf(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), TEXT("\tName: %s\r\n"), lpName);
if (FAILED(hResult))
{
// Add code to fail as securely as possible.
return FALSE;
}
}
else
{
hResult = StringCchPrintf(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), TEXT("\tName: %u\r\n"), (USHORT)lpName);
if (FAILED(hResult))
{
// Add code to fail as securely as possible.
return FALSE;
}
}
hResult = StringCchLength(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), &cbString);
if (FAILED(hResult))
{
// Add code to fail as securely as possible.
return FALSE;
}
WriteFile(g_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(
HMODULE 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
{
HRSRC hResInfo;
TCHAR szBuffer[80]; // print buffer for info file
DWORD cbWritten; // number of bytes written to resource info file
size_t cbString;
HRESULT hResult;
hResInfo = FindResourceEx(hModule, lpType, lpName, wLang);
// Write the resource language to the resource information file.
hResult = StringCchPrintf(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), TEXT("\t\tLanguage: %u\r\n"), (USHORT) wLang);
if (FAILED(hResult))
{
// Add code to fail as securely as possible.
return FALSE;
}
hResult = StringCchLength(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), &cbString);
if (FAILED(hResult))
{
// Add code to fail as securely as possible.
return FALSE;
}
WriteFile(g_hFile, szBuffer, (DWORD) cbString, &cbWritten, NULL);
// Write the resource handle and size to buffer.
hResult = StringCchPrintf(szBuffer,
sizeof(szBuffer)/sizeof(TCHAR),
TEXT("\t\thResInfo == %lx, Size == %lu\r\n\r\n"),
hResInfo,
SizeofResource(hModule, hResInfo));
if (FAILED(hResult))
{
// Add code to fail as securely as possible.
return FALSE;
}
hResult = StringCchLength(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), &cbString);
if (FAILED(hResult))
{
// Add code to fail as securely as possible.
return FALSE;
}
WriteFile(g_hFile, szBuffer, (DWORD)cbString, &cbWritten, NULL);
return TRUE;
}