consejos sobre archivo de configuracion

Iniciado por xkiz ™, 17 Junio 2011, 09:59 AM

0 Miembros y 1 Visitante están viendo este tema.

xkiz ™

me hice un programita muy basico, para escuchar la radio via internet, algo muy simple, SysTray, y 4 llamadas a mciSendString [ Open, Play, Pause, Stop], el string del url lo saco desde Recurso, StringTable.
ahora se me ocurrio ampliarlo un poco, y hacerlo mas dinamico, y agregar un par de cositas, como por ejemplo, listar la programacion de la radio, y un par de osas para las cuales, creo que seria mas adecuado apartar del .exe cierta info.

osea lo que planeo hacer es un archivo de configuracion /playlist, con datos que extrairia e implementaria en el programa, como la grilla de programacion de la radio en question, nombre para tooltip, icono para Systray, y etc...
ahora lo unico que se me ocurrio es meter toda esa info en un archivo .dll y la verdad que me estanke y necesito asecoramiento de uds, aca al final dejo un ej de una dll de prueba que estoy haciendo,

estoy en VC++ 6.0. en WinApi
aclaro que no tengo mucha experiencia o conocimientos en VC++6.0



attachment:  test.rar

BlackZeroX

#1
.
yo usaría los recursos por medio de la dll:

BeginUpdateResource
UpdateResource
EndUpdateResource
... etc.
Ejemplo

una vez abierto el recurso puedes usar:
LoadString
LoadBitmap
P.D.: ¿solo unos pocos usuarios pueden subir archivos así como tu o como esta la cosa?

Dulces Lunas!¡.
The Dark Shadow is my passion.

xkiz ™

ok, a lo que voy es que no se bien como armar el archivo.dll, osea.
STRINGTABLE:
101 nombre
102 nombre parte2
103 url Stream
y cree un recurso DATA -> 1 con un archivo ini:
Código (ini) [Seleccionar]

[mondayToFriday]
prog01=01:00|Trasnoche Rock & Pop|Conduce: Tapa Martín|http://trasnoche.fmrockandpop.com
prog02=05:00|Primera Data|Conduce: Marcos Menna\nDe las tribus urbanas, la más previsora.|
prog03=06:00|No Somos Nadie|Conduce: Juan Pablo Varsky\nDe las tribus urbanas, la única que lucha por la existencia humana.|http:// nosomosnadie.fmrockandpop.com
prog04=09:00|Cuál Es?|Conducen: Pergolini, de la Puente y Gantman\nCuál es la única tribu jamás dominada por nadie.http://:cuales.fm
prog05=13:00|Tarde Negra|Conduce: Elizabeth Vernaci\nTarde Negra, de las tribus urbanas, la más ardiente.|http://:tardenegra.fmrockandpop.com
prog06=16:00|Day Tripper|Conduce: Juan Di Natale\nUn poderoso tónico espiritual con el que pueden hacer viajar sin moverte un centímetro.|http://daytripper.fmrockandpop.com
prog07=19:00|Falso Impostor|Conduce: Gillespi\nUn monarca sube a su torre de Babel para tocar el cielo y arrebatar el tesoro de la música.|http://falsoimpostor.fmrockandpop.com
prog08=21:00|Apagá la Tele|Conduce: Gustavo Olmedo\n Toro Sentado Olmedo y su tropa de pieles rojas, te tomarán del cuero cabelludo hasta arrancarte del purgatorio televisivo. La única forma de evitar la cacería del zapping.|http://apagalatele.fmrockandpop.com
prog09=23:00|Último Bondi|Conduce: Daniel Jiménez|http://ultimobondi.fmrockandpop.com
[saturday]
prog01=00:00|La de Dios|Conduce: Santiago Palazzo\nDe las tribus urbanas, la que se comunica con señales de humo.|http://ladedios.fmrockandpop.com
prog02=03:00|Bonus Track|Conduce: Alejandro Lingenti|http://bonustrack.fmrockandpop.com
prog03=07:00|El Triángulo de las Bermudas|Conduce: Maxi Martina|http://triangulo.fmrockandpop.com
prog04=08:00|Cheque en Blanco|Conduce: Alfredo Zaiat\nDe las tribus urbanas, la que paga en especias.|http://chequeenblanco.fmrockandpop.com
prog05=11:00|El Aguante|Conducen: Martín Souto y Pablo Gonzalez|http://elaguante.fmrockandpop.com
prog06=13:00|Disco 2000|Conduce: Eduardo Ferrari|http://disco2000.fmrockandpop.comk
prog07=16:00|La Hora Señalada|Conduce: Guillermo Hernández\nDe las tribus urbanas, la mas cosmopolita.|
prog08=18:00|Ranking Rock & Pop|Conduce: Eduardo de la Puente|http://www.fmrockandpop.com/ranking
prog09=21:00|Somos Rock|Conduce: Alejandro Nagy|http://somosrock.fmrockandpop.com
[sunday]
prog01=00:00|Rock & Pop In Concert|Conduce: Dani Jimenez|http://inconcert.fmrockandpop.com
prog02=03:00|Rock & Pop Music||
prog03=07:00|No Hay Mañana Para Vos|Musicaliza: Ricky Achaval|http://nohay.fmrockandpop.comh
prog04=10:00|Jugala q' es Gratis|Conduce: Ramiro Quesada|http://jugala.fm
prog05=14:00|Clásico de Clásicos|Conduce: Diego Jalfen|http://clasico.fmrockandpop.com
prog06=18:00|La Casa del Rock Naciente|Conduce: Alfredo Rosso|http://lacasa.fmrockandpop.com
prog07=20:00|Bombardeo del Demo|Conduce: Marcelo Martinez|http://bombardeo.fmrockandpop.com
prog08=21:00|Tiempos Violentos|Conduce: Gustavo Olmedo.|http://tiemposviolentos.fmrockandpop.com


o crear recurso DATA -> 1 con la misma estructura de StringTable, me es == , no que no se bien como seria acceder a ese recurso DATA, o cual seria la mejor/facil  para hacerlo, la dll.

@BlackZeroX lo de tu PD, no tiene nada raro, solo es un [ hr ] y una img de un clip con texto attachment y un link, nada especial ni raro....

xkiz ™

bueno, perdon que re responda, pero con el trannscurso de la noche(Arg) logre agunos avances. Googlie y encontre LoadResource, FindResource, y etc, maso o menos ya tengo armado, abajo adjunto la dll para que vean y me digan que les parece o alguna sugerencia. el siguiente code uso para leer la data desde la dll:

Código (cpp) [Seleccionar]

#include "windows.h"
#define MONDATOFRIDAY MAKEINTRESOURCE(25)
#define SATURDAY MAKEINTRESOURCE(26)
#define SUNDAY MAKEINTRESOURCE(27)
//HGLOBAL global;

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
///////////////////////////////////////////////////////////////////////////////////////////////
//HGLOBAL global;
HINSTANCE module = LoadLibrary("C:\\Users\\xkiz\\Desktop\\test\\Release\\Rock&Pop.dll");

if(module){
OutputDebugString("LoadLibrary yes");
HRSRC rsrc = FindResource(module, MAKEINTRESOURCE(2),SATURDAY);
if(rsrc){
OutputDebugString("FindResource yes");
DWORD Size = SizeofResource(module, rsrc);
HGLOBAL MemoryHandle = LoadResource(module,rsrc);
if(MemoryHandle != NULL){
OutputDebugString((LPCTSTR)MemoryHandle);
}else{
OutputDebugString("MemoryHandle no");
}
}else{
OutputDebugString("FindResource no");
}
}else{
OutputDebugString("LoadLibrary no");
}

///////////////////////////////////////////////////////////////////////////////////////////////

return 0;
}



ahora me surge otra consulta, como habria que hacer para averifguar cuantos ID's hay en ese recurso?



attachment: test.rar (115.24 KB)

BlackZeroX

.
jeje no revisaste la liga al ejemplo de M$ que te puse, revisa el ejemplo de mi post anterior hay viene un código con la información respectiva para enumerar los recursos usa el api EnumResourceNames (Esta un ejemplo en la liga ejemplo de arriba).

pero por si las moscas:

Código (cpp) [Seleccionar]


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;
}



y para enumerar TODOS los recursos:

Código (cpp) [Seleccionar]


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;
}



Dulces Lunas!¡.
The Dark Shadow is my passion.

xkiz ™

BlackZeroX gracias por la ayuda, pero ya lo resolvi a mi manera, osea explico:

puse la lista de Programas en StringTable como cualkier String comun y en RCDATA puse 7 ID's (uno por cada dia de la semana) con un string formado con los id's de cada programa. asi me es mas facil de parsearlo.

Código (cpp) [Seleccionar]

STRINGTABLE DISCARDABLE
BEGIN
    201                     "01:00|05:00|Trasnoche Rock & Pop|Conduce: Tapa Martín|http://trasnoche.fmrockandpop.com"
    202                     "05:00|06:00|Primera Data|Conduce: Marcos Menna\nDe las tribus urbanas, la más previsora.|"
    203                     "06:00|09:00|No Somos Nadie|Conduce: Juan Pablo Varsky\nDe las tribus urbanas, la única que lucha por la existencia humana.|http:// nosomosnadie.fmrockandpop.com"
    204                     "09:00|13:00|Cuál Es?|Conducen: Pergolini, de la Puente y Gantman\nCuál es la única tribu jamás dominada por nadie.http://:cuales.fm"
// seguiria pero lo corto aca total es solo ilustrativo....
END

1 RCDATA DISCARDABLE // Sunday's
BEGIN
"401,402,403,404,405,406,407,408"
END

2 RCDATA DISCARDABLE //Monday's
BEGIN
"201,202,203,204,205,206,207,208,209"
END

3 RCDATA DISCARDABLE // Tuesday's
BEGIN
"201,202,203,204,205,206,207,208,209"
END

4 RCDATA DISCARDABLE // Wednesday's
BEGIN
"201,202,203,204,205,206,207,208,209"
END

5 RCDATA DISCARDABLE // Thursday's
BEGIN
"201,202,203,204,205,206,207,208,209"
END

6 RCDATA DISCARDABLE // Friday's
BEGIN
"201,202,203,204,205,206,207,208,209"
END

7 RCDATA DISCARDABLE // Saturdy's
BEGIN
"301,302,303,304,305,306,307,308"
END


asi que muchas gracias x todo....

xkiz ™

#6
perdon que vuelva con este tema, cuando ya habia dicho que lo solucione, pero es que me surguio una duda relacionao a este tema y crear un tema con lo mismo o la continuacion de esto me parecio mal y bue, ....
actualmente uso ese src para leer Resource:

Código (cpp) [Seleccionar]

HINSTANCE module = (HINSTANCE)LoadLibrary("RP.dll");
//HINSTANCE module = (HINSTANCE)LoadLibrary("RP.res");
if(module){
OutputDebugString("LoadLibrary yes");
HRSRC rsrc = FindResource(module, MAKEINTRESOURCE(2),RT_RCDATA);
if(rsrc){OutputDebugString("FindResource yes");
HGLOBAL MemoryHandle = LoadResource(module,rsrc);
if(MemoryHandle != NULL){OutputDebugString((LPCTSTR)MemoryHandle);
}else{OutputDebugString("MemoryHandle no");}
}else{OutputDebugString("FindResource no");}
}else{OutputDebugString("LoadLibrary no");}


hasta aca todoo funciona bien, pero estoy pensando que como archivo de configuracion o datos para mi programita, no me conviene usar archivo.dll, por que es medio complicado de crear una dll sin programas de programacion o o compiladores. estaba pensando que seria mas facil de crear un archivo .res. yo pensaba que me iba a ser facil leer este archivo.res desde C++, pero el codigo expuesto arriba no me sire para acdeder a los recursos del archivo res, tira error, aqui mi pregunta, se puede acceder a los recursos de un archivo res, asi facilito un poko las cosas???

BlackZeroX

has considerado usar un archivo .ini? son mas faciles, ademas pueden ser consultados en practicamente cualquier plataforma.

Dulces Lunas!¡.
The Dark Shadow is my passion.

xkiz ™

si, pero lo que pasa es que no solo strings voy a usar sino un par de cosas mas que no puedo meter en un archivo.ini, como un icono, bmp, y quiero un archivo solido, con un  *.ini tendria que tener el ini y el icono y el bp sueltos y eso es justamente lo que no quiero hacer, por eso de primera acudi a usar una dll como recurso, pero despues me tope con el inconveniente de que una dll no es tan facil de crear como si lo es un archivo.res, que de ultima lo puedo crear con resource Hacker, no se si se entiende la lo que voy....