Page 1 of 1
Transparencia en controles definidos por el usuario
Posted: Thu Aug 09, 2007 12:27 pm
by Marcelo Via Giglio
Holas,
estoy definiendo algunos controles, y no se como puedo hacerlos transparentes, por ejemplo he probado que el control sea una simple linea, pero igual el area del control no que da transparente, el :ltransparent := .T. no tiene efecto, o tengo que hacerlo de otra manera.
El control lo estoy derivando de la clase Tcontrol
alguna idea?
saludos
Marcelo
Posted: Thu Aug 09, 2007 1:29 pm
by Antonio Linares
Marcelo,
Estas usando temas de XP ?
Posted: Thu Aug 09, 2007 2:05 pm
by Marcelo Via Giglio
Antonio,
no, no estoy utilizando temas de XP
saludos
Marcelo
Posted: Thu Aug 09, 2007 3:46 pm
by Antonio Linares
Prueba a asignarle un brush "NULL" al control:
<oControl>:SetBrush( TBrush():New( "NULL" ) )
Eso hará que se dibuje transparente
Posted: Thu Aug 09, 2007 4:11 pm
by Marcelo Via Giglio
Gracias Antonio,
pero aun no funciono, te dejo el codigo es super sencillo
Code: Select all
#include "fivewin.ch"
FUNCTION main()
LOCAL oDlg, ofig1, ofig2, s1
DEFINE WINDOW oDlg FROM 10,10 TO 40,60
SetGridSize( 5, 5 )
@ 15,15 say s1 PROMPT "HOLA" of odlg COLOR CLR_RED SIZE 100,20 DESIGN
s1:lTransparent := .T.
ofig1 := tfig():new(1,1,25,25, oDlg )
ofig1:setBrush( tbrush():new("NULL"))
ofig2 := tfig():new(25,25,45,55, oDlg )
ofig2:setBrush( tbrush():new("NULL"))
ACTIVATE WINDOW oDLg
RETURN( NIL )
//----------------------------------------------------------------------------//
CLASS Tfig FROM TControl
CLASSDATA lRegistered AS LOGICAL
METHOD New( nRow, nCol, nHeight, nWidth, oWnd ) CONSTRUCTOR
METHOD Display() INLINE ::BeginPaint(), ::Paint(), ::EndPaint(), 0
METHOD Initiate( hDlg ) INLINE Super:Initiate( hDlg )
METHOD Paint()
ENDCLASS
//----------------------------------------------------------------------------//
METHOD New( nRow, nCol, nHeight, nWidth, oWnd ) CLASS tfig
::nTop := nRow
::nLeft := nCol
::nBottom := ::nTop + nHeight
::nRight := ::nLeft + nWidth
::oWnd := oWnd
::nStyle = nOr( WS_CHILD, WS_VISIBLE, WS_TABSTOP, WS_CLIPSIBLINGS )
::lCaptured := .F.
::lDrag := .T.
::lDesign := .T.
::lUpdate := .T.
::lRegistered := .f.
::ltransparent := .T.
::Register()
::Create()
::oWnd:AddControl( Self )
::CheckDots()
return SELF
//----------------------------------------------------------------------------//
METHOD Paint() CLASS tfig
LOCAL hBrush, hOldBrush
moveTo( ::hDC, 1, 1 )
LineTo( ::hDC, ::nWidth, ::nHeight )
return Super:Paint()
Posted: Thu Aug 09, 2007 8:03 pm
by Antonio Linares
Marcelo,
Tu ejemplo parece funcionar correctamente en Vista:
Posted: Thu Aug 09, 2007 10:12 pm
by Marcelo Via Giglio
Antonio,
no me queda claro la idea de transparencia, si te das cuenta, el SAY no permite que se vea parte de la linea, asi mismo, cuando sobrepones las lineas, en funcion del orden de creacion claro esta, el area del control (linea) se sobrepone a la otra, en ese sentido no podria formar una cruz (+) con dos de estos controles, salvo que sus diemsiones sean de 1 pixel, habra la forma de hacerlo?, no se si esta clara mi pregunta.
Desde ya muchas gracias por tu tiempo
saludos
Marcelo
Posted: Fri Aug 10, 2007 12:24 am
by Antonio Linares
Marcelo,
Lo que quieres hacer al algo más complicado de lo que parece.
Cada control es responsable de dibujar su propia imagen. El brush se utiliza para borrar la superficie del control antes de dibujar en él lo que sea.
Cuando queremos que sea transparente, se trata de que el fondo no se borre y en su lugar se copie la imagen que haya debajo del control. Pero, si existe otro control debajo (para formar una X por ejemplo) hay que combinar las imágenes de ambos.
El método EraseBkGnd() (Erase background) lo podemos declarar virtual, para que no se borre nada:
METHOD EraseBkGnd() VIRTUAL
Y en el método Paint() copiaríamos la imagen que hay debajo:
Code: Select all
METHOD Paint() CLASS tfig
... copiar la imagen que hay debajo del control al hDC de este control...
moveTo( ::hDC, 1, 1 )
LineTo( ::hDC, ::nWidth, ::nHeight )
return nil
La función para copiar desde un hDC a otro hDC es BitBlt(). Sigo...
Posted: Fri Aug 10, 2007 11:32 am
by Antonio Linares
Marcelo,
Aqui te pongo un ejemplo que debería funcionar bien, pero no lo hace. De todas formas debemos estar muy cerca:
Code: Select all
#include "fivewin.ch"
FUNCTION main()
LOCAL oDlg, ofig1, ofig2, s1
DEFINE WINDOW oDlg FROM 10,10 TO 40,60 COLOR "W/G"
SetGridSize( 5, 5 )
@ 15,15 say s1 PROMPT "HOLA" of odlg COLOR CLR_RED SIZE 100,20 DESIGN
s1:lTransparent := .T.
ofig1 := tfig():new(1,1,25,25, oDlg )
ofig2 := tfig():new(25,25,45,55, oDlg )
ACTIVATE WINDOW oDLg
RETURN( NIL )
//----------------------------------------------------------------------------//
CLASS Tfig FROM TControl
CLASSDATA lRegistered AS LOGICAL
METHOD New( nRow, nCol, nHeight, nWidth, oWnd ) CONSTRUCTOR
METHOD Display() INLINE ::BeginPaint(), ::Paint(), ::EndPaint(), 0
METHOD Initiate( hDlg ) INLINE Super:Initiate( hDlg )
METHOD Paint()
METHOD EraseBkGnd() VIRTUAL
ENDCLASS
//----------------------------------------------------------------------------//
METHOD New( nRow, nCol, nHeight, nWidth, oWnd ) CLASS tfig
::nTop := nRow
::nLeft := nCol
::nBottom := ::nTop + nHeight
::nRight := ::nLeft + nWidth
::oWnd := oWnd
::nStyle = nOr( WS_CHILD, WS_VISIBLE, WS_TABSTOP, WS_CLIPSIBLINGS )
::lCaptured := .F.
::lDrag := .T.
::lDesign := .T.
::lUpdate := .T.
::lRegistered := .f.
// ::ltransparent := .T.
::Register()
::Create()
::oWnd:AddControl( Self )
::CheckDots()
return SELF
//----------------------------------------------------------------------------//
METHOD Paint() CLASS tfig
ParentImage( ::hWnd, ::hDC )
moveTo( ::hDC, 1, 1 )
LineTo( ::hDC, ::nWidth, ::nHeight )
return nil
//----------------------------------------------------------------------------//
#pragma BEGINDUMP
#include <hbapi.h>
#include <windows.h>
HB_FUNC( PARENTIMAGE ) // hControl, hDC
{
HWND hWnd = ( HWND ) hb_parnl( 1 );
HDC hDC = ( HDC ) hb_parnl( 2 );
HDC hDcParent = GetDCEx( GetParent( hWnd ), NULL, DCX_PARENTCLIP );
RECT rct;
POINT pt;
GetWindowRect( hWnd, &rct );
pt.y = rct.top;
pt.x = rct.left;
ScreenToClient( GetParent( hWnd ), &pt );
BitBlt( hDC, 0, 0, rct.right - rct.left, rct.bottom - rct.top, hDcParent,
pt.x, pt.y, SRCCOPY );
ReleaseDC( GetParent( hWnd ), hDcParent );
}
#pragma ENDDUMP
Posted: Fri Aug 10, 2007 12:46 pm
by Marcelo Via Giglio
Antonio,
gracias, por lo visto es mas complicado de lo que pense, mas aun cuando hay may de dos controles sobrepuestos, la solucion para este caso particular de figuras geometricas seria utilizar algo como hizo Paco Garcia tiempo atras, buscare el fuente que es para 16 bits
Muchas gracias por tu tiempo, sin embargo, le echo mano a tu ejemplo y veo que sale
un abrazo
Marcelo
Posted: Sat Aug 11, 2007 4:59 pm
by R.F.
Marcelo y Antonio:
¿ Y no seria mas facil hacerlo por el BKMode ?
En el proceso de pintado de controles, bastaría con cambiar el SetBkMode del contexto de dispositivo, por ejemplo:
hDc := oDlg:GetDC()
SetBkMode(hDc, 1) // no recuerdo si la transparencia es 0 o 1
Y a continuación pintar, con un TextOut() por ejemplo, se pintaría transparentado con el fondo
El caso es que creo que Marcelo quiere pintar DEPUES de hacer control, lo cual si que está complicado con el SAY de FiveWin, porque ese hereda del LABEL API de Windows, ignoro si el LABEL internamente cambia el BKMode, sería mas facil que se hiciera su propio SAY mandando llamar al BKmode haciendolo transparente y luego pintando el texto.
Posted: Sat Aug 11, 2007 5:23 pm
by Antonio Linares
René,
Gracias por la sugerencia, pero no cambia la situación. El problema no es al pintar la línea sino que el fondo que hay debajo del control (no de la línea) sea visible.
Usando temas se consigue copiando el fondo del padre, que es lo mismo que hace la función en C que le he mostrado, pero por alguna causa, no lo está haciendo bien
Posted: Mon Aug 13, 2007 12:15 pm
by Marcelo Via Giglio
Rene,
gracias por contestar, ya probe antes con el SetBkMode(hDc, 1) y todo lo demas que pude averiguar y por eso pregunte en el foro.
Actualmente tengo corriendo en 32 bits un paint que creo lo hizo Paco Garcia, ya que estoy con tiempito, lo que deseo hacer es un generador de codigo para la clase tprint, veremos que sale, aun falta mucho
saludos
Marcelo