Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

TresourceStream con archivo de Recursos .rc

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: TresourceStream con archivo de Recursos .rc Responder citando

Anteriormente en Studio 2010 tenia un código que no consigo hacer funcionar en RIO 1.3.
Tenia este código que podía llamar a varios archivos del fichero de recursos, pero ahora no sé como hacerlo sin tener que crear un puntero para cada uno de los ficheros contenido en el fichero de recursos.
CODIGO ANTIGUO:
Código:

String CAB = Ruta + L"dat.cab";
String RAR = Ruta + L"rar.exe";
if(!FileExists(RAR.w_str()))//Si no existe Rar.exe
      TResourceStream(0, L"C", RT_RCDATA).SaveToFile(CAB.w_str());

if(!FileExists(IMG.w_str()))
      TResourceStream(0, L"R", RT_RCDATA).SaveToFile(RAR.w_str());

//... y así sucesivamente hasta sacar todos los ficheros del RECURSO.



ERROR QUE ME APARECE:
[ilink32 Error] Error: Unresolved external 'System::Classes::TResourceStream::{1173}...' referenced from D:\BDS_10_3\TPV-START\WIN32\DEBUG\UNIDADTPVBARMAN_START.OBJ
[ilink32 Error] Error: Unable to perform link

Ahora solo he encontrado esta forma de hacerlo con la creación de un PUNTERO, puesto que la forma anterior compila en .cpp de la llamada pero al generar el fichero del proyecto me da error y no los consigo hacer funcionar.

CODIGO NUEVO:
Código:

String CAB = Ruta + L"dat.cab";
String RAR = Ruta + L"rar.exe";

TResourceStream *B = new TResourceStream((int)HInstance, "C", RT_RCDATA);
   __try
   {
      B->SaveToFile(CAB.w_str());
/* La pregunta es... ¿Como sacar los otros ficheros del recurso antes de destruir el PUNTERO?*/

   }
   __finally
      {
         delete B;
      }


Fichero de RECURSOS. IB_Replicador.rc
Código:

/*IB_Replicador.rc*/
C RCDATA "dat.cab"
R RCDATA "rar.exe"
D RCDATA "divisas.cab"
B RCDATA "Barman.dat"
W RCDATA "nzw.dll"
IMG_1 RCDATA "IMG\\Inicio_2.jpg"
IMG_2 RCDATA "IMG\\imagen_jpg_error.jpg"
IMG_3 RCDATA "IMG\\Inicio_3.jpg"
IMG_4 RCDATA "IMG\\imagen_articulos.jpg"
IMG_5 RCDATA "IMG\\imagen_comanda.jpg"
IMG_6 RCDATA "IMG\\imagen_familias.jpg"
IMG_7 RCDATA "IMG\\imagen_operador.jpg"
IMG_8 RCDATA "IMG\\BalanzaDibal.jpg"
IMG_9 RCDATA "IMG\\CashDro.jpg"
IMG_10 RCDATA "IMG\\CashGuard.jpg"
IMG_11 RCDATA "IMG\\CashKeeper.jpg"
IMG_12 RCDATA "IMG\\CashLogy.jpg"
IMG_13 RCDATA "IMG\\Modo_Limpieza.jpg"
IMG_14 RCDATA "IMG\\display.jpg"
IMG_15 RCDATA "IMG\\display_2.jpg"
IMG_16 RCDATA "IMG\\1024_768.jpg"
IMG_17 RCDATA "IMG\\1280_800.jpg"
IMG_18 RCDATA "IMG\\1280_1024.jpg"
IMG_19 RCDATA "IMG\\1360_768.jpg"
IMG_20 RCDATA "IMG\\1920_1080.jpg"
IMG_21 RCDATA "IMG\\Color1.jpg"
IMG_22 RCDATA "IMG\\Color2.jpg"
IMG_23 RCDATA "IMG\\Color3.jpg"
IMG_24 RCDATA "IMG\\Color4.jpg"
IMG_25 RCDATA "IMG\\Color5.jpg"
IMG_26 RCDATA "IMG\\Color6.jpg"
IMG_27 RCDATA "IMG\\Mesas_Repres_Iconos.jpg"
IMG_28 RCDATA "IMG\\Mesas_Cod_Daltonicos.jpg"
IMG_29 RCDATA "IMG\\porciones.jpg"

_________________
Muchos hombres no se equivocan jamás porque no se proponen nada razonable.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor
Mensaje    Asunto: Responder citando

Hola, la razón por la que no funciona como antiguamente es porque en la clase TResourceStream hay esta declaración sin implementación:

__fastcall virtual ~TResourceStream();

El compilador clásico de C++Builder lo compila, pero clang que es el compilador “moderno” que trae C++Builder (activo opcionalmente en las versiones viejas desde que empezó a venir y activado por defecto desde hace varias versiones) no lo compila si no hay implementación, por lo que tienes dos opciones, o bien cambias en las propiedades del proyecto al compilador clásico (MENÚ: Project -> Options... -> C++ Compiler -> Use 'classic' Borland compiler = true) o bien simplemente crear una instancia por cada archivo, para hacerlo más sencillo créate alguna función como por ejemplo:
Código:

// Añadimos: #include <memory>
// Si guardó algo devuelve true en caso contrario false
bool Guardar(const String& resname, const String& file, bool overwrite = false)
{
   try {
      if (!overwrite && FileExists(file)) return false;
      std::make_unique<TResourceStream>(0, resname, RT_RCDATA)->SaveToFile(file);
      return true;
   } catch (...) {
      return false;
   }
}

Y luego para usarlo:
Código:

Guardar("C", Ruta + L"dat.cab");
Guardar("R", Ruta + L"rar.exe");
...
Guardar("OTRO", Ruta + L"otro.txt", true /*<--si queremos que sobrescriba*/);


Otra opción, es en vez de meter en los recursos los archivos uno por uno, crear un archivo comprimido .zip (o varios) y añádelo como recurso y luego descomprímelo en memoria como necesites, por ejemplo:
Código:

// Añadimos:  #include<memory>  #include<System.Zip.hpp>
void Descomprimir(String resname, String path, bool overwrite = false)
{
   auto res = std::make_unique<TResourceStream>(0, resname, RT_RCDATA);
   auto zip = std::make_unique<TZipFile>();
   zip->Open(res.get(), zmRead);

   if (overwrite) {
      zip->ExtractAll(path);
   }
   else {
      path = IncludeTrailingPathDelimiter(path);
      for (int i = 0; i < zip->FileCount; ++i) {
         if (!FileExists(path + zip->FileName[i]))
           zip->Extract(zip->FileName[i], path);
      }
   }
}

Y para usarlo:
Código:

Descomprimir("zip1", "f:\\prueba");
Descomprimir("zip2", "f:\\prueba", true /*<--si queremos que sobrescriba*/);
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Gracias Leo...
Como se tardó en darme una respuesta, ya busque y encontré algo parecido a lo que mencionas en la primera opción. Simplemente creé una función para no repetir constantemente la utilización de un PUNTERO.
Código:

void __fastcall TfV::ExtraerRecurso(String ResName, String FileName)
{//Extraer archivos del contenido en fichero de Recursos y guardarlo en disco
  TResourceStream *Res = new TResourceStream((int)HInstance, ResName, RT_RCDATA);
  __try
  {
    Res->SaveToFile(FileName);
  }
  __finally
   {
      delete Res;
   }
}


... Y su implementación se simplifica considerablemente.
Código:

   IMG = Ruta + "Imagenes\\Inicio_2.jpg";
   if(!FileExists(IMG.w_str()))
      ExtraerRecurso("IMG_1", IMG);

   IMG = Ruta + "Galeria\\imagen_jpg_error.jpg";
   if(!FileExists(IMG.w_str()))
      ExtraerRecurso("IMG_2", IMG);

   IMG = Ruta + "Galeria\\Ventas\\imagen_articulos.jpg";
   if(!FileExists(IMG.w_str()))
      ExtraerRecurso("IMG_4", IMG);

_________________
Muchos hombres no se equivocan jamás porque no se proponen nada razonable.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.