2012-02-11 12 views
13

Tengo recursos binarios personalizados (cursores animados) que me gustaría almacenar como recursos en una lib estática en Visual Studio C++. Resulta que los recursos binarios personalizados no serán cargados por :: LoadCursor() o encontrados por :: FindResource() si es un recurso personalizado y en una biblioteca estática.¿Cómo cargar un recurso binario personalizado en una biblioteca estática de VC++ como parte de un dll?

This question da algunas alternativas.

Siguiendo su consejo, si agrego el archivo * .res a un archivo ejecutable como "Propiedad de configuración-> Enlazador-> Dependencia adicional", la biblioteca estática podrá encontrar el recurso.

PERO si la biblioteca estática es parte de una DLL y la vinculo como una Dependencia Adicional, ¡no se encuentra de nuevo!

¿Cómo puedo vincular los recursos en un dll?

O simplemente haga que el binario se encuentre en la lib estática? Los métodos en la pregunta son bastante engorrosos.

+0

No está muy claro si olvidó agregar el archivo .res requerido en el proyecto DLL. El modo de falla más típico es pasar el identificador del módulo equivocado a FindResource(). Debe ser el manejador del módulo de DLL. Lo obtienes de DllMain(). Y sí, pegar esto es engorroso por diseño. –

Respuesta

29

En el cuadro de diálogo Agregar recurso, haga clic en Importar, seleccione "Todos los archivos (.)" para que le permita importar archivos de cualquier tipo y luego seleccione el archivo que desea allí. Cuando aparezca el cuadro de diálogo Tipo de recurso personalizado, escriba RCDATA en el campo "Tipo de recurso".

Si abre el archivo .rc, verá algo como esto:

///////////////////////////////////////////////////////////////////////////// 
// 
// RCDATA 
// 

IDR_RCDATA1   RCDATA    "myfile.whatever" 

y generará resource.h con la línea siguiente:

#define IDR_RCDATA1     101 

En el código se accede a él como esto :

#include "resource.h" 
#include <windows.h> 

int main(int argc, char* argv[]) 
{ 
    HRSRC myResource = ::FindResource(NULL, MAKEINTRESOURCE(IDR_RCDATA1), RT_RCDATA); 
    HGLOBAL myResourceData = ::LoadResource(NULL, myResource); 
    void* pMyBinaryData = ::LockResource(myResourceData); 
    return 0; 
} 

donde pMyBinaryData es el puntero al primer byte de este ejecutable. Para obtener más información, visite Resource Functions

He aquí un ejemplo de cómo se podría ahorrar recursos binaria como éste en el disco:

#include "resource.h" 
#include <windows.h> 
#include <fstream> 

int main(int argc, char* argv[]) 
{ 
    HRSRC myResource = ::FindResource(NULL, MAKEINTRESOURCE(IDR_RCDATA1), RT_RCDATA); 
    unsigned int myResourceSize = ::SizeofResource(NULL, myResource); 
    HGLOBAL myResourceData = ::LoadResource(NULL, myResource); 
    void* pMyBinaryData = ::LockResource(myResourceData); 

    std::ofstream f("C:\\x.bin", std::ios::out | std::ios::binary); 
    f.write((char*)pMyBinaryData, myResourceSize); 
    f.close(); 

    return 0; 
} 

Cuando se construye proyecto con recursos de esa manera, este recurso se convertirá en parte de su programa (DLL)

+0

Y también para no olvidar desbloquear el recurso: 'BOOL bResult = :: UnlockResource (hRes);' y 'bResult = :: FreeResource (hRes);' – DitherSky

+11

@DitherSky: No. Ya no es necesario, consulte la documentación de [Función FreeResource] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms648044 (v = vs.85) .aspx): * "Esta función es obsoleta y solo es compatible con compatibilidad con versiones anteriores con Windows de 16 bits. Para las aplicaciones de Windows de 32 bits, no es necesario liberar los recursos cargados usando LoadResource. "* – LihO

+0

' UnlockResource' es simplemente una macro no operativa en el SDK, pero extrañamente 'FreeResource' tiene un real exportación no-operativa en 'kernel32' para backcomp. – wqw

Cuestiones relacionadas