Redimensionando un Scroll

Post Reply
antolin
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Redimensionando un Scroll

Post by antolin »

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.
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
User avatar
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

Post by Antonio Linares »

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 )
regards, saludos

Antonio Linares
www.fivetechsoft.com
antolin
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Re: Redimensionando un Scroll

Post by antolin »

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
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
User avatar
cnavarro
Posts: 6557
Joined: Wed Feb 15, 2012 8:25 pm
Location: España
Been thanked: 3 times

Re: Redimensionando un Scroll

Post by cnavarro »

Antolin
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
antolin
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Re: Redimensionando un Scroll

Post by antolin »

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
User avatar
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

Post by Antonio Linares »

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:

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  
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
antolin
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Re: Redimensionando un Scroll

Post by antolin »

Ok Antonio, muchas Gracias.
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
antolin
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Re: Redimensionando un Scroll

Post by antolin »

Por cierto Antonio, RETURN 1 ¿es por algo en concreto? Muchas Clases retornan NIL.

Un saludo
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
User avatar
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

Post by Antonio Linares »

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)
regards, saludos

Antonio Linares
www.fivetechsoft.com
antolin
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Re: Redimensionando un Scroll

Post by antolin »

Todos los días aprendemos cosas nuevas. Muchas gracias.
Peaaaaaso de foro...
FWH 2007 - xHarbour - BCC55
antolin
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Re: Redimensionando un Scroll

Post by antolin »

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()

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
antolin
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Re: Redimensionando un Scroll

Post by antolin »

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++:

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
Post Reply