Page 1 of 1

Sugerencias GET's

Posted: Tue Mar 14, 2006 8:25 pm
by manuramos
Me complace exponer algunos Datas que utilizo en mi clase GET que creo pueden interesar a más de una persona:

1º) Evaluar bValid sólo si hubo cambios en el Get. Esto es interesante cuando el valid supone habrir una base de datos para comprobar ciertas cosas. ¿Para qué abrirla si no hubo cambios?

Supone añadir tres Datas y cambiar un par de métodos.

::OldDat -> para guardar el contenido del Get cuando toma el foco
::lCambio -> para saber si hubo cambios
::lValidate -> por si queremos obligar a que se procese bValid. (para mi gusto, por defecto .F.)

METHOD GotFocus( hCtlLost ) CLASS MIGET
...
::OldDat := ::VarGet()
...


METHOD lValid() CLASS MIGET
LOCAL xGet := ::VarGet()
LOCAL lRet := .T.
*
::lCambio := !(::OldDat==xGet) .OR. ::lCambio // el .OR. lCambio es necesario para ciertas situaciones en que el foco abandona el Dialogo del Get haciendo caso omiso de la validación, y después vuelve al Get. (alguna vez me ha ocurrido)
*
IF ::oGet:BadDate
MsgBeep()
RETURN .F.
ELSEIF ValType( ::bValid ) == "B" .AND. ( ::lCambio .OR. ::lValidate ) // evaluar sólo si hubo cambios o si forzamos con lValidate
lRet := Eval( ::bValid, Self )
::lCambio := .F.
ENDIF
RETURN lRet

2º) La siguiente sugerencia es muy sencilla y práctica. Un sólo DATA

::lBlank -> Nos dice si el contenido del Get está vacio o es NIL. Parece una tontería, pero ahorra tiempo a la hora de programar. Sobre todo cuando el Empty() dá problemas porque el Get, por cualquier razón se ha hecho igual a NIL

METHOD Initiate( hDlg ) CLASS MIGET
...
::lBlank := Empty(::cCaption)
...

METHOD lValid() CLASS MIGET
LOCAL xGet := ::VarGet()
...
::lBlank := (xGet = NIL .OR. Empty(xGet))
...

Así de sencillo

Tengo más sugerencias, pero basta por hoy, pues a lo mejor esto os parece una necedad.

Un saludo

Posted: Wed Mar 15, 2006 5:22 pm
by Marco A. Delgado
Hola manuramos

hace poco vi una clase que desarrollaste donde pones una sombra a unos dialogos, me pregunto seria posible me orientaras a como hacerlo.


Saludos

Marco A. Delgado.

Posted: Wed Mar 15, 2006 6:27 pm
by manuramos
Cierto Marco, hace poco puibliqué una clase TDIAG, que como la he cambiado ligeramente, te la vuelvo a pegar a continuación:

#Include "FiveWin.ch"

#define GWL_STYLE -16
#define GWL_EXSTYLE -20
#define WS_EX_TRANSPARENT 32

CLASS TDIAG OF TDIALOG

CLASSDATA lRegistered AS LOGICAL

DATA lSomb AS LOGICAL INIT .F.
DATA hFond,hPen,nDif

METHOD Activate( bClicked, bMoved, bPainted, lCentered, bValid, lModal, bInit, bRClicked, bWhen, nClrShadow )
METHOD Initiate( hWndFocus, hWnd )
METHOD Paint()
METHOD StartPaint()
METHOD PintSombra()
METHOD Destroy()

ENDCLASS


METHOD Activate( bClicked, bMoved, bPainted, lCentered, bValid, lModal, bInit, bRClicked, bWhen, nClrShadow ) CLASS TDIAG
IF nClrShadow # NIL
::lSomb := .T.
::hPen := CreatePen( 0,1,nClrShadow )
ENDIF
DEFINE BRUSH ::oBrush NULL
RETURN Super:Activate( bClicked, bMoved, bPainted, lCentered, bValid, lModal, bInit, bRClicked, bWhen )

METHOD Initiate( hWndFocus, hWnd ) CLASS TDIAG
LOCAL lFocus := Super:Initiate( hWndFocus, hWnd )
*
::nDif := IF(lAnd(GetWindowLong(::hWnd,GWL_STYLE),WS_BORDER),1,0)
::bStart := { || ::StartPaint() }
* SetWindowLong( ::hWnd, GWL_EXSTYLE, nOr( GetWindowLong( ::hWnd, GWL_EXSTYLE ), WS_EX_TRANSPARENT ) )
RETURN lFocus

METHOD Paint() CLASS TDIAG
DrawBitmap( ::hDc, ::hFond, -::nDif, -::nDif )
IF ::bPainted # NIL
EVAL(::bPainted,::hDc)
ENDIF
RETURN NIL
*
METHOD StartPaint() CLASS TDIAG
IF ::lSomb
::GetDc()
::PintSombra(::hDc)
::ReleaseDc()
ENDIF
IF ::bPainted # NIL
EVAL(::bPainted,::hDc)
ENDIF
::hFond := WndBitmap(::hWnd)
RETURN NIL
*
METHOD PintSombra(hDc) CLASS TDIAG
LOCAL hOldP := SelectObject( hDc,::hPen )
LOCAL nCont1,nCont2 := 0
LOCAL nDesde := 2
LOCAL nHasta := ::nWidth+::nHeight-2
*
FOR nCont1 = nDesde TO nHasta STEP 2
nCont2 := nCont1 - ::nHeight
MoveTo(hDc,nCont1,0)
LineTo(hDc,nCont2,::nHeight)
MoveTo(hDc,nCont2,0)
LineTo(hDc,nCont1,::nHeight)
NEXT
SelectObject( hDc,hOldP )
RETURN NIL

METHOD Destroy() CLASS TDIAG
DeleteObject(::hFond)
DeleteObject(::hPen)
RETURN NIL

No tienes más que copiar y pegar.

En el fichero de cabecera añade:

#xcommand DEFINE TRANSPDIAG <oDlg> ;
[ <resource: NAME, RESNAME, RESOURCE> <cResName> ] ;
[ TITLE <cTitle> ] ;
[ FROM <nTop>, <nLeft> TO <nBottom>, <nRight> ] ;
[ SIZE <nWidth>, <nHeight> ] ;
[ <lib: LIBRARY, DLL> <hResources> ] ;
[ <vbx: VBX> ] ;
[ STYLE <nStyle> ] ;
[ <color: COLOR, COLORS> <nClrText> [,<nClrBack> ] ] ;
[ BRUSH <oBrush> ] ;
[ <of: WINDOW, DIALOG, OF> <oWnd> ] ;
[ <pixel: PIXEL> ] ;
[ ICON <oIco> ] ;
[ FONT <oFont> ] ;
[ <help: HELP, HELPID> <nHelpId> ] ;
=> ;
<oDlg> = TDIAG():New( <nTop>, <nLeft>, <nBottom>, <nRight>,;
<cTitle>, <cResName>, <hResources>, <.vbx.>, <nStyle>,;
<nClrText>, <nClrBack>, <oBrush>, <oWnd>, <.pixel.>,;
<oIco>, <oFont>, <nHelpId>, <nWidth>, <nHeight> )

#xcommand ACTIVATE TRANSPDIAG <oDlg> ;
[ <center: CENTER, CENTERED> ] ;
[ <NonModal: NOWAIT, NOMODAL> ] ;
[ WHEN <uWhen> ] ;
[ VALID <uValid> ] ;
[ ON [ LEFT ] CLICK <uClick> ] ;
[ ON INIT <uInit> ] ;
[ ON MOVE <uMoved> ] ;
[ ON PAINT <uPaint> ] ;
[ ON RIGHT CLICK <uRClicked> ] ;
[ <color: COLORSOMBRA> <nClrShadow>] ;
=> ;
<oDlg>:Activate( <oDlg>:bLClicked [ := {|nRow,nCol,nFlags|<uClick>}], ;
<oDlg>:bMoved [ := <{uMoved}> ], ;
<oDlg>:bPainted [ := {|hDC,cPS|<uPaint>}],;
<.center.>, [{|Self|<uValid>}],;
[ ! <.NonModal.> ], [{|Self|<uInit>}],;
<oDlg>:bRClicked [ := {|nRow,nCol,nFlags|<uRClicked>}],;
[{|Self|<uWhen>}],<nClrShadow> )

Como verás es muy similar a DIALOG.CH

¿Cómo la empleo yo?, muy fácil:

1) creo la funcion que va a pintar la sombra:

FUNCTION SombWin(oWin,nDesp,nClr)
LOCAL oDls,aPt1[2],aPt2[2] // nDesp ES EL DESPLAZAMIENTO RESPECTO DEL DIALOGO
LOCAL hSom,hWin // nClr ES EL COLOR DE LA SOMBRA
LOCAL lTop := .F.

DEFAULT nDesp := 10 , ;
nClr := RGB(80,80,80)
*
oWin:CoorsUpdate()
hWin := GetWindow( oWin:hWnd,4 )
SysRefresh()
aPt1[1] := oWin:nTop + ( nDesp * 1.33 )
aPt2[1] := oWin:nBottom+ nDesp
aPt1[2] := oWin:nLeft + ( nDesp * 1.33 )
aPt2[2] := oWin:nRight + nDesp
IF hWin = 0
aPt1[1] := -2
aPt1[2] := -1
aPt2[1] := -2
aPt2[2] := -1
ELSE
SetActiveWindow(hWin)
ENDIF
ClientToScreen( hWin, aPt1)
ClientToScreen( hWin, aPt2)
nDesp:= nDesp * 9
DEFINE TRANSPDIAG oDls FROM aPt1[1],aPt1[2] TO aPt2[1],aPt2[2] PIXEL STYLE nOR(WS_POPUP,WS_VISIBLE,WS_CHILD )
ACTIVATE TRANSPDIAG oDls NOWAIT COLORSOMBRA nClr
SysRefresh()
ShowWindow(oWin:hWnd, 8 )
RETURN oDlS

2) Llamada a la función:

LOCAL oDlg,oSbr
*
...
DEFINE DIALOG oDlg ....
...
...
ACTIVATE DIALOG oDlg ON INI oSbr := SombWin(oDlg) VALID (oSbr:End(),.T.)

Como verás, es un Dialogo debajo de otro Dialogo.

Posted: Wed Mar 15, 2006 9:42 pm
by Marco A. Delgado
Muchas Gracias.

Lo voy a probar


Saludos

Marco A. Delgado

Diálogo con sombra.

Posted: Fri Apr 21, 2006 3:32 pm
by Fernando Morales
Hola, he estado probando el código que publicabas en el mensaje pero no logro ver la sombra, si bien estoy siguiendo tus indicaciones. ¿Tiene que ver la versión de Fivewin que se utilice?

Un saludo,
Fernando

Posted: Tue Jul 04, 2006 12:34 pm
by manuramos
Perdona Fernando, el día que leí tu solicitud no pude contestar y después se me olvidó. Ahora repasando algunas cosas he vuelto a leer este Topic.
Algo debes estar haciendo mal, pués no depende de ninguna versión de FW, e incluso, debería funcionar en (x)Habour.

A lo mejor no declaraste la variable en la que vas a guardar la sombra.
O a lo mejor el dialogo al que quieres poner sombra devuelve un ::hWnd = 0

El caso es que si no te da error al compilar, no aparece un GDF durante la ejecución de tu aplicación, y la sombra no aparece es que algo está haciendo mal.

Un saludo

Solucionado.

Posted: Fri Jul 07, 2006 4:34 pm
by Fernando Morales
Funciona. No creaba una ventana previa al diálogo, por lo que me devolvía hWnd == 0. El efecto que logras está muy bien.

Gracias y un saludo,
Fernando