Redimensionando un Scroll
Redimensionando un Scroll
Buenas a todos.
Tengo un control que posee un Scroll vertical. He implementado una función que lo redimensiona al mismo tiempo que el Dialogo en el que se encuentra, y todo perfecto. La pega está en el Scroll, parpadea mucho, porque a cada vez que cambiao el valor de ::oVScroll:nWidth el Scroll se borra y se redibuja creando un parpadeo muy feo. He optado por incluir la clausula:
::oVScroll:bEraseBkGnd := { || NIL }
Y, el cuerpo del Scroll ya no parpadea, pero si sus botones. Algo es algo. ¿Hay alguna forma de acceder a los objetos BUTTON del Scroll? ¿Conocéis otro forma de redimensionar un Scroll que no sea cambiar los valores de su nWidth? ¿O hay alguna manera de dibujar el Scroll en un DC Compatible??
Gracias
Un saludo.
Tengo un control que posee un Scroll vertical. He implementado una función que lo redimensiona al mismo tiempo que el Dialogo en el que se encuentra, y todo perfecto. La pega está en el Scroll, parpadea mucho, porque a cada vez que cambiao el valor de ::oVScroll:nWidth el Scroll se borra y se redibuja creando un parpadeo muy feo. He optado por incluir la clausula:
::oVScroll:bEraseBkGnd := { || NIL }
Y, el cuerpo del Scroll ya no parpadea, pero si sus botones. Algo es algo. ¿Hay alguna forma de acceder a los objetos BUTTON del Scroll? ¿Conocéis otro forma de redimensionar un Scroll que no sea cambiar los valores de su nWidth? ¿O hay alguna manera de dibujar el Scroll en un DC Compatible??
Gracias
Un saludo.
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
FWH 2007 - xHarbour - BCC55
- Antonio Linares
- Site Admin
- Posts: 42521
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Has thanked: 31 times
- Been thanked: 75 times
- Contact:
Re: Redimensionando un Scroll
Antolin,
Tendrias que plantearte el implementarle el pintado a "doble buffer" que es la única manera de evitar los parpadeos.
Tienes muchos ejemplos en las clases de FWH. Busca por:
local aInfo := ::DispBegin()
... pintado estandard ...
::DispEnd( aInfo )
Tendrias que plantearte el implementarle el pintado a "doble buffer" que es la única manera de evitar los parpadeos.
Tienes muchos ejemplos en las clases de FWH. Busca por:
local aInfo := ::DispBegin()
... pintado estandard ...
::DispEnd( aInfo )
Re: Redimensionando un Scroll
Ya Antonio, había pensado algo así, el problema es que la clase TScrollBar no tiene mucho donde trabajar. Por ejemplo, no tiene un Método Paint(), y no sé como se pinta. Con eso ya estaría solucionado.
Gracias por la respuesta
Gracias por la respuesta
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
FWH 2007 - xHarbour - BCC55
Re: Redimensionando un Scroll
Antolin
Puedes poner un pequeño ejemplo para probarlo?
Puedes poner un pequeño ejemplo para probarlo?
Cristobal Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
Re: Redimensionando un Scroll
Por cierto, ¿alguien sabe donde se dibuja el Scroll? Porque lo único cierto es que en el Create() se crea su Window pero ¿dónde se dibuja?
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
FWH 2007 - xHarbour - BCC55
- Antonio Linares
- Site Admin
- Posts: 42521
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Has thanked: 31 times
- Been thanked: 75 times
- Contact:
Re: Redimensionando un Scroll
Antolin,
Lo pinta el propio Windows es por esto que tienes que definir el método Paint() para tomar el control tu, generando el doble buffer, llamando al procedimiento original de pintado y restaurando el doble buffer.
Tienes un ejemplo aqui:
Lo pinta el propio Windows es por esto que tienes que definir el método Paint() para tomar el control tu, generando el doble buffer, llamando al procedimiento original de pintado y restaurando el doble buffer.
Tienes un ejemplo aqui:
Code: Select all | Expand
METHOD Paint() CLASS TButtonBmp
local aInfo := ::DispBegin() // creamos el doble buffer
CallWindowProc( ::nOldProc, ::hWnd, WM_PAINT, ::hDC, 0 ) // llamada al procedimiento original de Windows
::DispEnd( aInfo )
return 1
Re: Redimensionando un Scroll
Ok Antonio, muchas Gracias.
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
FWH 2007 - xHarbour - BCC55
Re: Redimensionando un Scroll
Por cierto Antonio, RETURN 1 ¿es por algo en concreto? Muchas Clases retornan NIL.
Un saludo
Un saludo
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
FWH 2007 - xHarbour - BCC55
- Antonio Linares
- Site Admin
- Posts: 42521
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Has thanked: 31 times
- Been thanked: 75 times
- Contact:
Re: Redimensionando un Scroll
Si, el 1 significa que nosotros ya hicimos lo que habia que hacer y que no hay nada mas que hacer.
Es decir, el trabajo esta hecho y terminado, y por lo tanto no hay que llamar al procedimiento por defecto de Windows (que añadiría más trabajo a lo hecho)
Es decir, el trabajo esta hecho y terminado, y por lo tanto no hay que llamar al procedimiento por defecto de Windows (que añadiría más trabajo a lo hecho)
Re: Redimensionando un Scroll
Todos los días aprendemos cosas nuevas. Muchas gracias.
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
FWH 2007 - xHarbour - BCC55
Re: Redimensionando un Scroll
Bueno, pues creo que lo he conseguido. Ya no parpadea el Scroll cuado redimensiono mi control. Lo he hecho de esta manera:
1. HE modificado la clase TScrollBar añadiendo el data: hCDC y el siguiente metodo Paint()
2. Al definir el Scroll hay que poner: oVScroll:bEraseBkGnd := { || NIL }
3. Cuando se redimensiona el control, hay que pintarlo en un DC compatible:
Si analizais este código vereis que hay que tomar una serie de precauciones:
1. Al definir el Scroll hay que hacer: oVScroll:bEraseBkGnd := { || NIL } para evitar que este se borre a la vista cada vez que desplazamos o modificamos el Scroll.
2. Para desplazar o redimensionar el Scroll hay que utilizar el métofo Scroll:Move( ...,.F. ). Con el último parámetro en .F. para que no se redibuje por su cuenta. Atención, cuando hacemos oVScroll:nTop o oVScroll:nWidth, el Scroll también se desplaza o redimensiona, pero parpadea porque seguramente el sistema utiliza el ::hDc del Scroll para repintarlo por su cuenta.
3. Si vamos a cambiar el range del Scroll tenemos que poner oVScroll:lRedraw := .F. para que el SetRange() no repinte el Scroll por su cuenta.
4. Hay que reponer oVScroll:hCDC := NIL y oVScroll:lRedraw := .T. para que el Scroll pueda redibujarse cuando se repinta el control de forma normal, por ejemplo al abrir y cerrar algún dialogo por encima.
Aun así, de vez en cuando el Scroll parpadea, pero muy levemente. Pero ya no es el continuo borrado y repintado que ocurría antes. La mejora es patente.
Espero os sea útil
Un saludo.
1. HE modificado la clase TScrollBar añadiendo el data: hCDC y el siguiente metodo Paint()
Code: Select all | Expand
METHOD Paint() CLASS TScrollBar
IF ::hCDC = NIL
CallWindowProc( ::nOldProc, ::hWnd, WM_PAINT, ::hDc, 0 )
ELSE
CallWindowProc( ::nOldProc, ::hWnd, WM_PAINT, ::hCDC,0 )
ENDIF
RETURN 1
2. Al definir el Scroll hay que poner: oVScroll:bEraseBkGnd := { || NIL }
3. Cuando se redimensiona el control, hay que pintarlo en un DC compatible:
Code: Select all | Expand
FUNCTION ResizeCtrl( PARAMETROS... )
...
...
oDlg:GetDc()
PaintInCDC(oDlg,oDlg:hDc)
oDlg:ReleaseDc()
...
...
RETURN NIL
FUNCTION PaintInCDC(oDlg,hDc)
LOCAL hCC := CreateCompatibleDc(hDc)
LOCAL hBmp := CreateCompBmp(hDc,oDlg:nWidth,oDlg:nHeight)
...
SelectObject(hCC,hBmp)
oDlg:EraseBkGnd(hCC)
...
// AQUI PINTAMOS EL CONTROL
...
IF ::oVSCroll # NIL
...
... // AQUI definir/calcular nTop, nLeft, nWidth, nHeight, nMin y nMax
... // O TRAERLOS COMO PARAMETROS CON ESTA FUNCION
... // TAMBIEN PODRIAN VENIR EN UNA ARRAY DENTRO DE oDlg:Cargo
...
oVScroll:lRedraw := .F.
oVScroll:hCDC := hCC
oVScroll:Move(nTop,nLeft,nWidth,nHeight,.F.)
oVScroll:SetRange(nMin,nMax)
oVScroll:Refresh()
oVScroll:hCDC := NIL
oVScroll:lRedraw := .T.
...
ENDIF
...
BitBlt(hDc,0,0,oDlg:nWidth,oDlg:nHeight,hCC,0,0,SRCCOPY)
*
DeleteDc(hCC)
DeleteObject(hBmp)
RETURN NIL
Si analizais este código vereis que hay que tomar una serie de precauciones:
1. Al definir el Scroll hay que hacer: oVScroll:bEraseBkGnd := { || NIL } para evitar que este se borre a la vista cada vez que desplazamos o modificamos el Scroll.
2. Para desplazar o redimensionar el Scroll hay que utilizar el métofo Scroll:Move( ...,.F. ). Con el último parámetro en .F. para que no se redibuje por su cuenta. Atención, cuando hacemos oVScroll:nTop o oVScroll:nWidth, el Scroll también se desplaza o redimensiona, pero parpadea porque seguramente el sistema utiliza el ::hDc del Scroll para repintarlo por su cuenta.
3. Si vamos a cambiar el range del Scroll tenemos que poner oVScroll:lRedraw := .F. para que el SetRange() no repinte el Scroll por su cuenta.
4. Hay que reponer oVScroll:hCDC := NIL y oVScroll:lRedraw := .T. para que el Scroll pueda redibujarse cuando se repinta el control de forma normal, por ejemplo al abrir y cerrar algún dialogo por encima.
Aun así, de vez en cuando el Scroll parpadea, pero muy levemente. Pero ya no es el continuo borrado y repintado que ocurría antes. La mejora es patente.
Espero os sea útil
Un saludo.
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
FWH 2007 - xHarbour - BCC55
Re: Redimensionando un Scroll
Perdón no me he dado cuenta.
En algunas versiones de FWH CreateCompatibleDc() viene como CraeteCDC() y CreateCompBmp es invento mio porque no tengo el CreateCompatibleBitmap(), que a lo mejor si lo teneis, o no, en cuyo caso así se implementa en Borland C++:
Un saludo
En algunas versiones de FWH CreateCompatibleDc() viene como CraeteCDC() y CreateCompBmp es invento mio porque no tengo el CreateCompatibleBitmap(), que a lo mejor si lo teneis, o no, en cuyo caso así se implementa en Borland C++:
Code: Select all | Expand
HB_FUNC( CREATECOMPBMP ) // CreateCompBmp( HDC hDc, int nWidth, int nHight )
{
hb_retnl( ( LONG ) CreateCompatibleBitmap( ( HDC ) hb_parnl( 1 ), ( LONG ) hb_parnl( 2 ), ( LONG ) hb_parnl( 3 ) ) ) ;
}
Un saludo
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
FWH 2007 - xHarbour - BCC55