FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Redimensionando un Scroll
Posts: 498
Joined: Thu May 10, 2007 08:30 PM
Redimensionando un Scroll
Posted: Wed Aug 13, 2014 07:44 PM

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
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: Redimensionando un Scroll
Posted: Thu Aug 14, 2014 03:30 PM

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
Posts: 498
Joined: Thu May 10, 2007 08:30 PM
Re: Redimensionando un Scroll
Posted: Thu Aug 14, 2014 05:13 PM

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
Posts: 6755
Joined: Wed Feb 15, 2012 08:25 PM
Re: Redimensionando un Scroll
Posted: Thu Aug 14, 2014 05:14 PM

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
Posts: 498
Joined: Thu May 10, 2007 08:30 PM
Re: Redimensionando un Scroll
Posted: Thu Aug 14, 2014 07:15 PM

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
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: Redimensionando un Scroll
Posted: Thu Aug 14, 2014 10:20 PM
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 (fw): Select all Collapse
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
Posts: 498
Joined: Thu May 10, 2007 08:30 PM
Re: Redimensionando un Scroll
Posted: Fri Aug 15, 2014 09:17 AM

Ok Antonio, muchas Gracias.

Peaaaaaso de foro...

FWH 2007 - xHarbour - BCC55
Posts: 498
Joined: Thu May 10, 2007 08:30 PM
Re: Redimensionando un Scroll
Posted: Fri Aug 15, 2014 09:29 AM

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

Un saludo

Peaaaaaso de foro...

FWH 2007 - xHarbour - BCC55
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: Redimensionando un Scroll
Posted: Fri Aug 15, 2014 09:37 AM

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
Posts: 498
Joined: Thu May 10, 2007 08:30 PM
Re: Redimensionando un Scroll
Posted: Fri Aug 15, 2014 10:12 AM

Todos los días aprendemos cosas nuevas. Muchas gracias.

Peaaaaaso de foro...

FWH 2007 - xHarbour - BCC55
Posts: 498
Joined: Thu May 10, 2007 08:30 PM
Re: Redimensionando un Scroll
Posted: Fri Sep 12, 2014 04:36 PM
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 (fw): Select all Collapse
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 (fw): Select all Collapse
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
Posts: 498
Joined: Thu May 10, 2007 08:30 PM
Re: Redimensionando un Scroll
Posted: Sun Sep 14, 2014 07:02 PM
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 (fw): Select all Collapse
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

Continue the discussion