FWH - Nueva Clase TOutLook2003
-
- Posts: 988
- Joined: Thu Nov 24, 2005 3:01 pm
- Location: Madrid, España
Moises,
Gracias por tu interés. Deduzco que tu no debes tener ese problema, dado que preguntas por mi configuración. Que configuración has usado?
Tal como respondí ayer, creo que un chipset nVidia de una tarjeta nueva de 256 Mb de RAM dedicada no da lugar a muchas dudas, motherboard ASUS, Athlon, 1 Gb de RAM, con esa tarjeta de video ejecuta juegos de manera impecable, fue construido para eso. Y no creo que un control de FiveWin sea más exigente en cuestiones gráficas que un juego.
Y ayer a la tarde hablando con un colega de la lista me confirmó los mismos problemas con el demo.exe descargado del enlace de este hilo, pero no me dio (no le pregunté) su configuración. Espero que si lee este mensaje pueda dar ese detalle.
Y lo he probado con 3 equipos, ademas del nvidia, lo probé en mi portatil que es un acer 1410 WLMI con 768 Mb RAM y chipset gráfico Intel® 855GME integrated 3D AGP graphics / Intel® Extreme Graphics 2 technology 64 MB of video memory Dual independent display support
Aca en la oficina es un VIA/S3G Unichrome PRO IGP con 64 Mb de RAM, en un Pentium IV de 3.0 Ghz y 512 Mb de RAM, la especificaciones las puedes ver en la imagen posteada, ya que use la ventana de propiedades para hacer fallar el pintado.
Sería interesante saber si alguien más tiene ese problema, sobre todo si el equipo es de recursos limitados, ya que un banco de pruebas debe presentar las condiciones desfavorables.
Un saludo,
Carlos.
Gracias por tu interés. Deduzco que tu no debes tener ese problema, dado que preguntas por mi configuración. Que configuración has usado?
Tal como respondí ayer, creo que un chipset nVidia de una tarjeta nueva de 256 Mb de RAM dedicada no da lugar a muchas dudas, motherboard ASUS, Athlon, 1 Gb de RAM, con esa tarjeta de video ejecuta juegos de manera impecable, fue construido para eso. Y no creo que un control de FiveWin sea más exigente en cuestiones gráficas que un juego.
Y ayer a la tarde hablando con un colega de la lista me confirmó los mismos problemas con el demo.exe descargado del enlace de este hilo, pero no me dio (no le pregunté) su configuración. Espero que si lee este mensaje pueda dar ese detalle.
Y lo he probado con 3 equipos, ademas del nvidia, lo probé en mi portatil que es un acer 1410 WLMI con 768 Mb RAM y chipset gráfico Intel® 855GME integrated 3D AGP graphics / Intel® Extreme Graphics 2 technology 64 MB of video memory Dual independent display support
Aca en la oficina es un VIA/S3G Unichrome PRO IGP con 64 Mb de RAM, en un Pentium IV de 3.0 Ghz y 512 Mb de RAM, la especificaciones las puedes ver en la imagen posteada, ya que use la ventana de propiedades para hacer fallar el pintado.
Sería interesante saber si alguien más tiene ese problema, sobre todo si el equipo es de recursos limitados, ya que un banco de pruebas debe presentar las condiciones desfavorables.
Un saludo,
Carlos.
Carlos,
Muchas gracias por responder. A mi todavía no me ha dado tu error, si he notado una vez que no pintaba bien una esquina pero al seleccionar otro Folder de la barra se repintó bien.
Voy a hacer pruebas en un equipo antiguo con Windows ME y con un equipo Pentium 2.8 2 gb RAM que tiene la nvidia a ver qué sucede.
A ver si damos con el bug, porque la nueva clase de Antonio es excelente y tengo muchas ganas de integrarla en mis aplicaciones.
Un saludo
Muchas gracias por responder. A mi todavía no me ha dado tu error, si he notado una vez que no pintaba bien una esquina pero al seleccionar otro Folder de la barra se repintó bien.
Voy a hacer pruebas en un equipo antiguo con Windows ME y con un equipo Pentium 2.8 2 gb RAM que tiene la nvidia a ver qué sucede.
A ver si damos con el bug, porque la nueva clase de Antonio es excelente y tengo muchas ganas de integrarla en mis aplicaciones.
Un saludo
-
- Posts: 988
- Joined: Thu Nov 24, 2005 3:01 pm
- Location: Madrid, España
Moises,
el error se produce cuando tu aplicacion no es la activa, es decir el foco esta en una ventana que no es tu exe. Y como tu dices, al retomar el foco comienza a pintar sin problemas. Es el mismo comportamiento.
Seguir buscando en el hardware problemas que solo tenemos con controles de FW me parece que no tiene mucho sentido. Notaras que si las clases son nativas de windows el problema no aparece, solo es en las que pintamos nosotros. Es decir que al pintar hacemos algo diferente. El problema lo tengo con XP, con Milenium... es que ni siquiera tiene soporte de temas...
Un saludo
Carlos.
el error se produce cuando tu aplicacion no es la activa, es decir el foco esta en una ventana que no es tu exe. Y como tu dices, al retomar el foco comienza a pintar sin problemas. Es el mismo comportamiento.
Seguir buscando en el hardware problemas que solo tenemos con controles de FW me parece que no tiene mucho sentido. Notaras que si las clases son nativas de windows el problema no aparece, solo es en las que pintamos nosotros. Es decir que al pintar hacemos algo diferente. El problema lo tengo con XP, con Milenium... es que ni siquiera tiene soporte de temas...
Un saludo
Carlos.
Carlos,
efectivamente solo es con fivewin,
con otros lenguajes de programacion o IDE (s) no he tenido ese
problema,
Es muy raro no en todas las pcs pasa
pero en definitivo es un problema de la libreria de fivewin
ojala se encuentre arreglo ya que los programas se ven feos,,
saludos.
efectivamente solo es con fivewin,
con otros lenguajes de programacion o IDE (s) no he tenido ese
problema,
Es muy raro no en todas las pcs pasa
pero en definitivo es un problema de la libreria de fivewin
ojala se encuentre arreglo ya que los programas se ven feos,,
saludos.
Cesar Cortes Cruz
SysCtrl Software
Mexico
' Sin +- FWH es mejor "
SysCtrl Software
Mexico
' Sin +- FWH es mejor "
-
- Posts: 845
- Joined: Sun Oct 09, 2005 5:36 pm
- Location: la laguna, mexico.
probando desde el demo en un p4 3ghz, 1gb ram, video 128mb,
y pinta mal
http://img63.imageshack.us/img63/1741/ol2003ti0.jpg
http://img63.imageshack.us/my.php?image=ol2003ti0.jpg
salu2
paco
y pinta mal
http://img63.imageshack.us/img63/1741/ol2003ti0.jpg
http://img63.imageshack.us/my.php?image=ol2003ti0.jpg
salu2
paco
-
- Posts: 988
- Joined: Thu Nov 24, 2005 3:01 pm
- Location: Madrid, España
Antonio,Antonio Linares wrote:Carlos,
Otra posible pista: Si BeginPaint() falla (según la documentación del API de Windows) entonces el hDC devuelto no es válido, por lo que al intentar usarlo más adelante no funcionaría. Una posible prueba sería este cambio:Code: Select all
METHOD _BeginPaint() CLASS TWindow local cPS if ::nPaintCount == nil ::nPaintCount = 1 else ::nPaintCount++ endif ::hDC = BeginPaint( ::hWnd, @cPS ) ::cPS = cPS if ::hDC == 0 MsgBeep() // tenemos un hDC no válido ! endif return nil
agregué el método a mi clase tanto _beginpaint como Colors. Colors no es invocado nunca, y dentro de BeginPaint el hDC obtenido es siempre distinto de 0
Code: Select all
METHOD _BeginPaint() CLASS TOutLook2
local cPS
if ::nPaintCount == nil
::nPaintCount = 1
else
::nPaintCount++
endif
::hDC = BeginPaint( ::hWnd, @cPS )
::cPS = cPS
Debug ::hDC
return nil
METHOD Colors( hDC ) CLASS TOutLook2
Debug hDC
Return NIL
Un ejemplo de lo obtenido es:
Code: Select all
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1359024382
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): -385806109
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 939593962
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1543573760
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1359024382
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1543573760
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): -1124003575
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1476464714
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1359024382
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 922816754
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 889262400
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 788599041
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): -385806109
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): -167702589
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): -1124003575
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1543573760
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1040256830
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1359024382
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 788599041
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 939593962
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1359024382
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 788599041
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): -2097082404
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 788599041
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 922816754
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1359024382
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 788599041
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 922816754
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 922816754
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 922816754
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): -167702589
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1929449739
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): -385806109
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1543573760
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): -2097082404
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1359024382
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 184619263
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1744900316
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1744900316
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): -385806109
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1040256830
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 184619263
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 922816754
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): -1912534408
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1812008841
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 889262400
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): -1912534408
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 2063667294
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1040256830
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 2063667294
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): -167702589
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 184619263
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1929449739
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 889262400
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 788599041
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1744900316
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): -1124003575
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 1812008841
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): -385806109
TOUTLOOK2:BEGINPAINT(146) - ::hDC (N): 922816754
Si ves algo más que pueda probar por favor avísame. Tambien estoy por el messenger. Un saludo,
Carlos.
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
-
- Posts: 988
- Joined: Thu Nov 24, 2005 3:01 pm
- Location: Madrid, España
Antonio,
efectivamente me sucede con los controles de FiveWin que pintamos, pero no con los que usan las clases predefinidas, por ejemplo en el control los botones los dibujo yo para hacer el degradado y tal, pero si pongo un boton normal de windows como en la clase outlook original, se pinta perfectamente y no logro fallar. El fallo tambien es evidente en los msgitems de la statusbar.
Cualquier cosa que veas que se puede probar me avisas.
Un saludo,
Carlos.
efectivamente me sucede con los controles de FiveWin que pintamos, pero no con los que usan las clases predefinidas, por ejemplo en el control los botones los dibujo yo para hacer el degradado y tal, pero si pongo un boton normal de windows como en la clase outlook original, se pinta perfectamente y no logro fallar. El fallo tambien es evidente en los msgitems de la statusbar.
Cualquier cosa que veas que se puede probar me avisas.
Un saludo,
Carlos.
-
- Posts: 988
- Joined: Thu Nov 24, 2005 3:01 pm
- Location: Madrid, España
Antonio,
creo que ya tengo parte del origen del problema.
He puesto un 'chivato' en el handle event que me diga que eventos recibe. Durante un ciclo normal de pintado se reciben los siguientes eventos
pero cuando trasteo con una ventana por encima y falla el pintado, la secuencia de eventos se altera,
Creo que está la punta del ovillo. pero es tarde y mañana hay que trabajar. Dime lo que se te ocurra que pueda probar.
Un saludo,
Carlos.
creo que ya tengo parte del origen del problema.
He puesto un 'chivato' en el handle event que me diga que eventos recibe. Durante un ciclo normal de pintado se reciben los siguientes eventos
Code: Select all
TOUTLOOK2:HANDLEEVENT(178) - "WM_PAINT "
TOUTLOOK2:HANDLEEVENT(177) - "WM_NCPAINT "
TOUTLOOK2:HANDLEEVENT(173) - "WM_ERASEBKGND "
TOUTLOOK2:HANDLEEVENT(188) - "WM_CTLCOLORSTATIC"
TOUTLOOK2:HANDLEEVENT(188) - "WM_CTLCOLORSTATIC"
TOUTLOOK2:HANDLEEVENT(188) - "WM_CTLCOLORSTATIC"
TOUTLOOK2:HANDLEEVENT(188) - "WM_CTLCOLORSTATIC"
TOUTLOOK2:HANDLEEVENT(188) - "WM_CTLCOLORSTATIC"
Code: Select all
TOUTLOOK2:HANDLEEVENT(178) - "WM_PAINT "
TOUTLOOK2:HANDLEEVENT(177) - "WM_NCPAINT "
TOUTLOOK2:HANDLEEVENT(173) - "WM_ERASEBKGND "
TOUTLOOK2:HANDLEEVENT(177) - "WM_NCPAINT "
TOUTLOOK2:HANDLEEVENT(173) - "WM_ERASEBKGND "
TOUTLOOK2:HANDLEEVENT(188) - "WM_CTLCOLORSTATIC"
TOUTLOOK2:HANDLEEVENT(178) - "WM_PAINT "
TOUTLOOK2:HANDLEEVENT(177) - "WM_NCPAINT "
TOUTLOOK2:HANDLEEVENT(173) - "WM_ERASEBKGND "
TOUTLOOK2:HANDLEEVENT(173) - "WM_ERASEBKGND "
TOUTLOOK2:HANDLEEVENT(188) - "WM_CTLCOLORSTATIC"
TOUTLOOK2:HANDLEEVENT(188) - "WM_CTLCOLORSTATIC"
TOUTLOOK2:HANDLEEVENT(188) - "WM_CTLCOLORSTATIC"
TOUTLOOK2:HANDLEEVENT(188) - "WM_CTLCOLORSTATIC"
TOUTLOOK2:HANDLEEVENT(188) - "WM_CTLCOLORSTATIC"
Creo que está la punta del ovillo. pero es tarde y mañana hay que trabajar. Dime lo que se te ocurra que pueda probar.
Un saludo,
Carlos.
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
colegas alguien me puede explicar esto q esta hecho en C y forma parte de FWH,, el archivo se llama dc.c esta en winapi
//----------------------------------------------------------------------------//
#ifdef __HARBOUR__
CLIPPER FWDISPBEGIN( PARAMS ) // ( hWnd, hDC ) --> aInfo
#else
CLIPPER FWDISPBEGI( PARAMS ) // ( hWnd, hDC ) -->aInfo
#endif
{
HWND hWnd = ( HWND ) _parnl( 1 );
HDC hDC = ( HDC ) _parnl( 2 );
HDC hDC2;
HBITMAP hBmp, hBmpOld;
RECT rct;
GetClientRect( hWnd, &rct );
hDC2 = CreateCompatibleDC( hDC );
hBmp = CreateCompatibleBitmap( hDC, rct.right - rct.left,
rct.bottom - rct.top );
hBmpOld = ( HBITMAP ) SelectObject( hDC2, hBmp );
// we comment it out to improve painting speed
// BitBlt( hDC2, 0, 0, rct.right, rct.bottom, hDC, 0, 0, SRCCOPY );
#ifdef __XPP__
#define _stornl( x, y, z ) STORNL( x, params, y, z )
#endif
_reta( 5 );
_stornl( ( LONG ) hWnd , -1, 1 );
_stornl( ( LONG ) hDC , -1, 2 );
_stornl( ( LONG ) hDC2 , -1, 3 );
_stornl( ( LONG ) hBmp , -1, 4 );
_stornl( ( LONG ) hBmpOld, -1, 5 );
}
//----------------------------------------------------------------------------//
he notado q si de la clase twindow suprimo la coneccion a esta rutina en C el problema del mal pintado se corrige,, pero no se pq.. quizas alguien u antonio q es el master me lo pueda explicar.. o quizas hay algo mal en esto codigo,, quizas entre en conflicto con algo
bueno ahi les dejo la inquietud
//----------------------------------------------------------------------------//
#ifdef __HARBOUR__
CLIPPER FWDISPBEGIN( PARAMS ) // ( hWnd, hDC ) --> aInfo
#else
CLIPPER FWDISPBEGI( PARAMS ) // ( hWnd, hDC ) -->aInfo
#endif
{
HWND hWnd = ( HWND ) _parnl( 1 );
HDC hDC = ( HDC ) _parnl( 2 );
HDC hDC2;
HBITMAP hBmp, hBmpOld;
RECT rct;
GetClientRect( hWnd, &rct );
hDC2 = CreateCompatibleDC( hDC );
hBmp = CreateCompatibleBitmap( hDC, rct.right - rct.left,
rct.bottom - rct.top );
hBmpOld = ( HBITMAP ) SelectObject( hDC2, hBmp );
// we comment it out to improve painting speed
// BitBlt( hDC2, 0, 0, rct.right, rct.bottom, hDC, 0, 0, SRCCOPY );
#ifdef __XPP__
#define _stornl( x, y, z ) STORNL( x, params, y, z )
#endif
_reta( 5 );
_stornl( ( LONG ) hWnd , -1, 1 );
_stornl( ( LONG ) hDC , -1, 2 );
_stornl( ( LONG ) hDC2 , -1, 3 );
_stornl( ( LONG ) hBmp , -1, 4 );
_stornl( ( LONG ) hBmpOld, -1, 5 );
}
//----------------------------------------------------------------------------//
he notado q si de la clase twindow suprimo la coneccion a esta rutina en C el problema del mal pintado se corrige,, pero no se pq.. quizas alguien u antonio q es el master me lo pueda explicar.. o quizas hay algo mal en esto codigo,, quizas entre en conflicto con algo
bueno ahi les dejo la inquietud
Mi segundo amor es Programar
-
- Posts: 988
- Joined: Thu Nov 24, 2005 3:01 pm
- Location: Madrid, España
Cesar y Paco, gracias a ambos por confirmar el dato.
Horacio: para suprimir la rutina es suficiente con volver virtuales los métodos DispBegin y DispEnd de la clase twindow. Puedes ver el post de Antonio al respecto, no recuerdo si fue en este hilo o en otro de 'problemas de pintado'
A&C
En general el pintado de un objeto (ventana/control) en windows se hace en varios pasos: Se pinta el fondo (borrando la imagen actual) y luego pintando texto y/o bitmaps. Eso se percibe como un parpadeo, como que el control desaparece y aparece inmediatamente.
Para evitar este efecto se crea un buffer en la memoria, se pinta en el buffer y cuando está todo listo se copia el buffer a la pantalla, todo de un solo golpe evitando los parpadeos.
FWDispBegin crea ese buffer de pintado en la memoria, y pone el hDC de pintado apuntando a ese buffer. Como uno pinta usando DCs, loc comandos graficos se direccionan automágicamente a ese buffer.
Cuando has terminado de pintar llamas a FWDispEnd() que hace el último paso: trasladar el dibujo del buffer al DC original.
El método asi implementado es muy práctico, ya que no hay que tener muchos cuidados al usarlo, salvo llamar a las dos funciones antes y despues de pintar.
Respecto de que se mejora el pintado: el método del doble buffer tiene el problema de que requiere que el pintado sea sincronizado, es decir que el objeto no reciba los mensajes de forma desordenada tal como los esta recibiendo cuando no tiene el foco.
Como habras leido en el hilo todavía yo no lo tengo muy claro, pero segun lo que he posteado respecto a los mensajes que recibe el objeto hay algunas cosas que se pueden ir confirmando y que paso a explicar en mi respuesta a Antonio.
Un saludo y gracias por el interés,
Carlos
Horacio: para suprimir la rutina es suficiente con volver virtuales los métodos DispBegin y DispEnd de la clase twindow. Puedes ver el post de Antonio al respecto, no recuerdo si fue en este hilo o en otro de 'problemas de pintado'
A&C
Esas funciones son las que hacen el doble buffering para hacer pintados y evitar el parpadeo mientras se pintan los controles.A&C wrote:colegas alguien me puede explicar esto q esta hecho en C y forma parte de FWH,, el archivo se llama dc.c esta en winapi
.....
he notado q si de la clase twindow suprimo la coneccion a esta rutina en C el problema del mal pintado se corrige,, pero no se pq.. quizas alguien u antonio q es el master me lo pueda explicar.. o quizas hay algo mal en esto codigo,, quizas entre en conflicto con algo
En general el pintado de un objeto (ventana/control) en windows se hace en varios pasos: Se pinta el fondo (borrando la imagen actual) y luego pintando texto y/o bitmaps. Eso se percibe como un parpadeo, como que el control desaparece y aparece inmediatamente.
Para evitar este efecto se crea un buffer en la memoria, se pinta en el buffer y cuando está todo listo se copia el buffer a la pantalla, todo de un solo golpe evitando los parpadeos.
FWDispBegin crea ese buffer de pintado en la memoria, y pone el hDC de pintado apuntando a ese buffer. Como uno pinta usando DCs, loc comandos graficos se direccionan automágicamente a ese buffer.
Cuando has terminado de pintar llamas a FWDispEnd() que hace el último paso: trasladar el dibujo del buffer al DC original.
El método asi implementado es muy práctico, ya que no hay que tener muchos cuidados al usarlo, salvo llamar a las dos funciones antes y despues de pintar.
Respecto de que se mejora el pintado: el método del doble buffer tiene el problema de que requiere que el pintado sea sincronizado, es decir que el objeto no reciba los mensajes de forma desordenada tal como los esta recibiendo cuando no tiene el foco.
Como habras leido en el hilo todavía yo no lo tengo muy claro, pero segun lo que he posteado respecto a los mensajes que recibe el objeto hay algunas cosas que se pueden ir confirmando y que paso a explicar en mi respuesta a Antonio.
Un saludo y gracias por el interés,
Carlos
-
- Posts: 988
- Joined: Thu Nov 24, 2005 3:01 pm
- Location: Madrid, España
Antonio,
El control que estoy usando para probar no es de ninguna clase específica de Windows, por lo que al crear la clase del control se llama a Create sin parámetros para crear una nueva clase de ventana, TOutLook2. El estilo de las ventanas de esta clase es WS_CHILD, WS_VISIBLE, WS_CLIPSIBLINGS
Cuando mi control se pinta normalmente, y es mi aplicación la ventana activa, la secuencia de mensajes que se recibe es la siguiente, coincidiendo con la primera parte del post.:
1) WM_PAINT -> que se procesa a:
::BeginPaint()
::Paint()
::EndPaint()
2) la invocación de BeginPaint para obtener el DC produce que Windows envíe dos mensajes:
WM_NCPAINT // Pintado del área no cliente de la ventana o control
WM_ERASEBKGND // Borrar el fondo
que resulta en el segundo caso en la llamada a EraseBackgnd que si lo ponemos a 1 hacemos que se valide el fondo como pintado, o bien si retornamos 0 se llama a la funcion normal de pintado de windows. Como en nuestro método PAINT pintamos todo incluyendo el fondo, es preferible retornar 1. Ademas mejora el tema del parpadeo.
3) Como mi control tiene otros controles hijos que son subclases de la clase Static de windows, se reciben luego una sucesion de WM_CTLCOLORSTATIC para que la ventaan padre defina los colores del hijo. Esto ya esta definido en la clase windows.
4) por ultimo llamamos a EndPaint para liberar el DC.
Al recibir el WM_ERASEBKGND, se adjunta un DC con el cual pintar, que además tiene clipeada la region a actualizar.
pero.... que sale mal?
Un detalle importante a recordar es que cuando una ventana está parcialmente invisible (como en nuestro caso) al recibir el mensaje de pintado y su correspondiente DC, este viene 'clipeado', es decir, se ha bloqueado parte de la pantalla para que no podamos pintar en algunos sitios, por ejemplo, el area ocupada por las ventanas superpuestas. Es por eso que en los fallos de pintado vemos esas formas extrañas de rayas, que son las áreas que no se han pintado correctamente, el resto estaba 'clipeado' cuando se recibió el mensaje WM_PAINT para que no lo dibujásemos, porque o bien esa area corresponde a otra ventana o bien porque no es necesario repintarlo. Dicho esto...
En el segundo bloque de mensajes se vé algo más complejo de interpretar pero para quien interactua con las ventanas para producir la secuencia de mensajes es un poco más sencillo de entender. Siempre estoy tratando de producir el error, entíendase entonces que muevo la ventana superpuesta de forma lenta para que la ventana inferior tenga que trabajar mucho pintando trocito a trocito.
entonces empieza con
1: WM_PAINT
que luego pasa como es de esperarse de acuerdo con la secuencia 'correcta'
2: WM_NCPAINT
3: WM_ERASEBKGND
cuando se reciben estos mensajes no se debe olvidar que la region a actualizar esta clipeada, es decir que cuando pintamos solo se actualiza en una parte de la pantalla y no toda el area de nuestro control.
peeero, luego me repite
4: WM_NCPAINT
5: WM_ERASEBKGND
6: WM_CTLCOLORSTATIC
... esto no es lo esperado! Como se explica? Sencillo: mientras estaba procesándose WM_ERASEBKGND en el punto (3), algun usuario cabroncete movio algo en la pantalla que requiere que se actualice otro trocito de la pantalla, digamos otra region, entonces nos manda nuevamente a borrar el fondo de ese trozo nuevo, clipeado, tarea que debiera cumplirse en 4 y 5. Luego aparentemente sigue el pintado normal ya que llega hasta 6, es decir ya está pintando uno de los controles hijos, pero cuando aun no ha llegado al final... el usuario vuelve a mover las ventanas y genera una nueva necesidad de pintado. Y comienza un nuevo ciclo de pintado, ya que al recibir:
7: WM_PAINT
todavía no se habían terminado de pintar los controles hijos.
Este ciclo de pintado SI se cumple de manera completa, pero, claro, la region clipeada es la que corresponde al nuevo movimiento, y la region antigua quedo a medio camino, sin pintarse de manera completa.
sefiní.
Perdón por la larga charla, pero es que es lo que he podido lograr discernir despues de horas de debuguear.
Ahora mi duda es... como evitarlo? Ya le quite el doblebuffer, he probado todas las combinaciones de EraseBkgnd... no sé. Cualquier sugerencia es bienvenida.
Hasta mañana,
Carlos.
He estado probando bastante el control y observando los mensajes que se reciben en cada ocacion. He controlado los hDC para asegurarme que no son nulos.Antonio Linares wrote:Carlos,
gracias por tu ayuda. La verdad es que no veo nada extraño salvo que hay dos erasebkgnd seguidos
El control que estoy usando para probar no es de ninguna clase específica de Windows, por lo que al crear la clase del control se llama a Create sin parámetros para crear una nueva clase de ventana, TOutLook2. El estilo de las ventanas de esta clase es WS_CHILD, WS_VISIBLE, WS_CLIPSIBLINGS
Cuando mi control se pinta normalmente, y es mi aplicación la ventana activa, la secuencia de mensajes que se recibe es la siguiente, coincidiendo con la primera parte del post.:
1) WM_PAINT -> que se procesa a:
::BeginPaint()
::Paint()
::EndPaint()
2) la invocación de BeginPaint para obtener el DC produce que Windows envíe dos mensajes:
WM_NCPAINT // Pintado del área no cliente de la ventana o control
WM_ERASEBKGND // Borrar el fondo
que resulta en el segundo caso en la llamada a EraseBackgnd que si lo ponemos a 1 hacemos que se valide el fondo como pintado, o bien si retornamos 0 se llama a la funcion normal de pintado de windows. Como en nuestro método PAINT pintamos todo incluyendo el fondo, es preferible retornar 1. Ademas mejora el tema del parpadeo.
3) Como mi control tiene otros controles hijos que son subclases de la clase Static de windows, se reciben luego una sucesion de WM_CTLCOLORSTATIC para que la ventaan padre defina los colores del hijo. Esto ya esta definido en la clase windows.
4) por ultimo llamamos a EndPaint para liberar el DC.
Al recibir el WM_ERASEBKGND, se adjunta un DC con el cual pintar, que además tiene clipeada la region a actualizar.
pero.... que sale mal?
Un detalle importante a recordar es que cuando una ventana está parcialmente invisible (como en nuestro caso) al recibir el mensaje de pintado y su correspondiente DC, este viene 'clipeado', es decir, se ha bloqueado parte de la pantalla para que no podamos pintar en algunos sitios, por ejemplo, el area ocupada por las ventanas superpuestas. Es por eso que en los fallos de pintado vemos esas formas extrañas de rayas, que son las áreas que no se han pintado correctamente, el resto estaba 'clipeado' cuando se recibió el mensaje WM_PAINT para que no lo dibujásemos, porque o bien esa area corresponde a otra ventana o bien porque no es necesario repintarlo. Dicho esto...
En el segundo bloque de mensajes se vé algo más complejo de interpretar pero para quien interactua con las ventanas para producir la secuencia de mensajes es un poco más sencillo de entender. Siempre estoy tratando de producir el error, entíendase entonces que muevo la ventana superpuesta de forma lenta para que la ventana inferior tenga que trabajar mucho pintando trocito a trocito.
entonces empieza con
1: WM_PAINT
que luego pasa como es de esperarse de acuerdo con la secuencia 'correcta'
2: WM_NCPAINT
3: WM_ERASEBKGND
cuando se reciben estos mensajes no se debe olvidar que la region a actualizar esta clipeada, es decir que cuando pintamos solo se actualiza en una parte de la pantalla y no toda el area de nuestro control.
peeero, luego me repite
4: WM_NCPAINT
5: WM_ERASEBKGND
6: WM_CTLCOLORSTATIC
... esto no es lo esperado! Como se explica? Sencillo: mientras estaba procesándose WM_ERASEBKGND en el punto (3), algun usuario cabroncete movio algo en la pantalla que requiere que se actualice otro trocito de la pantalla, digamos otra region, entonces nos manda nuevamente a borrar el fondo de ese trozo nuevo, clipeado, tarea que debiera cumplirse en 4 y 5. Luego aparentemente sigue el pintado normal ya que llega hasta 6, es decir ya está pintando uno de los controles hijos, pero cuando aun no ha llegado al final... el usuario vuelve a mover las ventanas y genera una nueva necesidad de pintado. Y comienza un nuevo ciclo de pintado, ya que al recibir:
7: WM_PAINT
todavía no se habían terminado de pintar los controles hijos.
Este ciclo de pintado SI se cumple de manera completa, pero, claro, la region clipeada es la que corresponde al nuevo movimiento, y la region antigua quedo a medio camino, sin pintarse de manera completa.
sefiní.
Perdón por la larga charla, pero es que es lo que he podido lograr discernir despues de horas de debuguear.
Ahora mi duda es... como evitarlo? Ya le quite el doblebuffer, he probado todas las combinaciones de EraseBkgnd... no sé. Cualquier sugerencia es bienvenida.
Hasta mañana,
Carlos.