[C con Clase] problema con el WM PAINT

AntonioFrancisco Gimenez antoniof.gimenez en gmail.com
Jue Mar 22 11:57:01 CET 2007


Steven, los errores que lanza el compilador es:

llmain.o(.text+0x304):C:/prueba/dllmain.cpp:115: undefined reference to
`SelectObject en 8'
dllmain.o(.text+0x32c):C:/prueba/dllmain.cpp:116: undefined reference to
`FloodFill en 16'
dllmain.o(.text+0x33c):C:/prueba/dllmain.cpp:117: undefined reference to
`DeleteObject en 4'

Saludos, espero tu respuesta

El día 21/03/07, Steven Davidson <steven en conclase.net> escribió:
>
> Hola Antonio,
>
> El pasado 2007-03-21 16:11:55, Antonio escribió:
>
> A> Vereis me he creado una clase con una funcion miembro publica que es la
> siguiente:
>
> [CORTE]
>
> A> // a continuación pongo el procedimiento de ventana
> A> LRESULT CALLBACK procdlg (HWND hwnd, UINT msg, WPARAM wparam, LPARAM
> lparam){
> A>          static HINSTANCE instancia;
> A>     switch (msg)                  /* handle the messages */
> A>     {
> A>          case WM_PAINT:
> A>                 HDC dc;
> A>                 dc=GetDC(hwnd);
> A>                 HBRUSH brocha;
> A>                 brocha=CreateSolidBrush(0xff0000);
> A>                 SelectObject(dc,brocha);
> A>                 FloodFill(dc,1,1,0xffffff);
> A>                 break;
> A>            case WM_CREATE:
> A>                 instancia= ((LPCREATESTRUCT)lparam)->hInstance;
> A>
> A>                 break;
> A>            case WM_SHOWWINDOW:
> A>                 /*HDC dc;
> A>                 dc=GetDC(hwnd);
> A>                 HBRUSH brocha;
> A>                 brocha=CreateSolidBrush(0xff0000);
> A>                 SelectObject(dc,brocha);
> A>                 FloodFill(dc,1,1,0xffffff);*/
> A>                 break;
> A>         case WM_DESTROY:
> A>             PostQuitMessage (0);       /* send a WM_QUIT to the message
> queue */
> A>             break;
> A>         default:                      /* for messages that we don't
> deal with */
> A>             return DefWindowProc (hwnd, msg, wparam, lparam);
> A>     }
> A>     return 0;
> A>
> A> }
> A> Mi pregunta consiste en ¿porque cuando capturo el mensaje WM_PAINT y
> creo el DC al ejecutar CreateSolidBrush me dice que la funcion no esta
> definida a pesar de haber incluido el windows.h y el stdio.h. Lo mismo me
> dice al llamar a
>
> Sin saber exactamente el mensaje, no estoy del todo seguro. De todas
> maneras, tienes un error en el 'switch'. No puedes hacer declaraciones en un
> 'switch'. Lo que sí puedes hacer es crear un bloque de sentencias y hacer
> las declaraciones en tal bloque. Esto es,
>
> switch( msg )
> {
> case WM_PAINT:
> {
>    HDC dc;
>    dc=GetDC(hwnd);
>    HBRUSH brocha;
>    brocha=CreateSolidBrush(0xff0000);
>    SelectObject(dc,brocha);
>    FloodFill(dc,1,1,0xffffff);
> }
> break;
> ...
> }
>
> Ahora las variables 'dc' y 'brocha' serán locales a este bloque. Es
> posible que los errores hacían alusión a esto.
>
> A> SelectObject y a FloodFill? Que diferencia existe al ejecutarlo en el
> bucle de mensajes del main de un proyecto .exe y en un cpp de una dll sin
> ser miembro de ninguna clase?
>
> No preveo ninguna diferencia. Supongo que tienes escrito algo así:
>
> INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hNada, LPSTR lpszLinea, int
> nMostrar )
> {
> HWND hVentana;
> ...
> DllClass obj;
> obj.creadlg( hVentana, hInst );
> ...
> }
>
>
> Viendo tu código, tengo que hacer unas cuantas correcciones:
>
> 1. Al ejecutar 'GetDC()', debes invocar 'ReleaseDC()', ya que debemos
> "soltar" el DC que caputarmos al invocar 'GetDC()'.
>
> 2. Al procesar el mensaje WM_PAINT, debemos invocar 'BeginPaint()' y
> 'EndPaint()' para obtener el manipulador del DC de la ventana. Estas
> funciones realizan otras tareas que 'GetDC()' no hace.
>
> 3. Sugiero usar la macro 'RGB()' en lugar de escribir explícitamente el
> valor. En tu caso, sería,
>
> brocha = CreateSolidBrush( RGB(0,0,255) );  // Azul
>
> 4. Al crear una brocha propia, o sea, que no sea del sistema, debemos
> destruirla invocando la función 'DestroyObject()'. Por ejemplo,
>
> brocha = CreateSolidBrush(0xff0000);
> SelectObject( dc, brocha );
> DestroyObject( brocha );
>
> Ten en cuenta que 'SelectObject()' copia la información al DC y por tanto,
> 'brocha' deja de sernos útil posteriormente.
>
> Aconsejo crear la brocha al comienzo, especialmente si no vas a cambiar su
> color. Por ejemplo,
>
> static HBRUSH brocha;
>
> switch( msg )
> {
> case WM_CREATE:
>    brocha = CreateSolidBrush( RGB(0,0,255) );
>    ...
> break;
>
> case WM_PAINT:
>    ...
>    SelectObject( dc, brocha );
>    ...
> break;
>
> case WM_DESTROY:
>    DestroyObject( brocha );
>    PostQuitMessage( 0 );
> break;
> ...
> }
>
>
> Espero haber aclarado el asunto.
>
> Steven
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20070322/dc5a2d49/attachment.html>


Más información sobre la lista de distribución Cconclase