[C con Clase] problema con el WM PAINT

Steven Davidson steven en conclase.net
Mie Mar 21 18:12:34 CET 2007


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


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