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