[C con Clase] Problema al cargar un recurso en una dll
Steven Davidson
steven en conclase.net
Mie Jun 27 19:53:22 CEST 2007
Hola Man,
El pasado 2007-06-27 16:20:13, Man Alvarez escribió:
MA> Hola Steven
MA> Steven podrías mandarme la prueba que mencionas que hiciste? Quisiera
MA> examinarla y quizás así descubra en que estoy fallando al crear la mía.
Sí. Expongo los contenidos de los ficheros más abajo.
MA> Mandé mi código a la lista te llegó? Estaba pensando que quizá sea por las
Me temo que no llegó el fichero.
MA> opciones que elegí cuando cree el proyecto, voy a probar creándola eligiendo
MA> otras opciones.
Es posible. Ten presente que tienes que crear dos proyectos: uno donde crear la DLL y otro para usar y probar la DLL. A la hora de usar la DLL, el enlazador típicamente crea una biblioteca de importación; por ejemplo, "dialogo_dll.lib" aparte de la DLL en sí: "dialogo_dll.dll". Deberías agregar esta biblioteca de importación al enlazador en tu proyecto.
También observa que cualquier programa que vaya a usar tu DLL seguirá una búsqueda establecida por MS-Windows. La búsqueda comienza en el mismo directorio del fichero ejecutado. Por lo tanto, recuerda copiar tu DLL a tal directorio para que tu programa automáticamente encuentre y cargue la DLL.
Espero que los programas posteriores te sirvan. Ten en cuenta que usé Dev-C++ para estas pruebas, pero no he tenido problema alguno a la hora de hacerlo mismo bajo VS.
Steven
---------------------------------
// Programa de prueba
// "dialogo_win_winmain.cpp"
#include <windows.h>
#include "dll_dialogo.h"
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char szClassName[ ] = "WindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"Windows App", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
544, /* The programs width */
375, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hBoton;
switch (message) /* handle the messages */
{
case WM_CREATE:
hBoton = CreateWindowEx( 0L, "BUTTON", "Crear Diálogo",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
20,20, 150,30,
hwnd, (HMENU)IDOK, NULL, NULL );
break;
case WM_COMMAND:
if( HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK )
{
if( !Dialog( NULL ) ) //GetModuleHandle("dll_dialogo.dll") ) )
MessageBox( hwnd, "Dialog() == FALSE", "ERROR", MB_OK );
}
break;
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
---------------------------------
// "dll_dialogo.h"
#ifndef _DLL_H_
#define _DLL_H_
#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else
# define DLLIMPORT __declspec (dllimport)
#endif
// Función a exportar
DLLIMPORT HWND Dialog( HINSTANCE hInst );
#endif
---------------------------------
// "dll_dialogo_main.cpp"
#include <windows.h>
// Queremos crear la DLL: #definir BUILDING_DLL
#define BUILDING_DLL 1
#include "dll_dialogo.h"
// Función "privada" a la DLL => no exportable
BOOL CALLBACK DialogoProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch( uMsg )
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
EndDialog( hDlg, FALSE );
return TRUE;
}
return FALSE;
}
// Función "pública" de la DLL
DLLIMPORT HWND Dialog( HINSTANCE hInst )
{
return CreateDialog( hInst, "Dialogo", NULL, DialogoProc );
}
// Función homólogo a 'WinMain()' pero para DLL's
BOOL APIENTRY DllMain( HINSTANCE hInst, DWORD reason, LPVOID reserved )
{
switch( reason )
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
---------------------------------
// "dll_dialogo.rc"
#include <windows.h>
Dialogo DIALOG 0, 0, 118, 48
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION
CAPTION "Diálogo de prueba"
FONT 8, "Helv"
BEGIN
CONTROL "Mensaje de prueba", -1, "static",
SS_LEFT | WS_CHILD | WS_VISIBLE,
8, 9, 84, 8
CONTROL "Aceptar", IDOK, "button",
BS_PUSHBUTTON | BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
56, 26, 50, 14
END
Más información sobre la lista de distribución Cconclase