Redimensionando un Scroll

Redimensionando un Scroll

Postby antolin » Wed Aug 13, 2014 7: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
antolin
 
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Re: Redimensionando un Scroll

Postby Antonio Linares » Thu Aug 14, 2014 3: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
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Redimensionando un Scroll

Postby antolin » Thu Aug 14, 2014 5: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
antolin
 
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Re: Redimensionando un Scroll

Postby cnavarro » Thu Aug 14, 2014 5: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
User avatar
cnavarro
 
Posts: 6549
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Redimensionando un Scroll

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

Re: Redimensionando un Scroll

Postby Antonio Linares » 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: Select all  Expand view  RUN

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
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Redimensionando un Scroll

Postby antolin » Fri Aug 15, 2014 9:17 am

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

Postby antolin » Fri Aug 15, 2014 9: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
antolin
 
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Re: Redimensionando un Scroll

Postby Antonio Linares » Fri Aug 15, 2014 9: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
User avatar
Antonio Linares
Site Admin
 
Posts: 42118
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Redimensionando un Scroll

Postby antolin » Fri Aug 15, 2014 10:12 am

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

Postby antolin » Fri Sep 12, 2014 4: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: Select all  Expand view  RUN
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 view  RUN
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

Postby antolin » Sun Sep 14, 2014 7: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: Select all  Expand view  RUN
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
antolin
 
Posts: 498
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 90 guests