/* * Xailer source code: * * WinControl.prg * Clase TWinControl() * * Copyright 2003, 2007 Jose F. Gimenez * Copyright 2003, 2007 Xailer.com * All rights reserved * */ #include "Xailer.ch" //-------------------------------------------------------------------------- CLASS XWinControl FROM TStdControl PUBLISHED: PROPERTY oBkgnd AS TPicture WRITE METHOD SetBkgnd EDITOR PE_Picture PROPERTY nBkgndMode INIT blCOPY WRITE METHOD SetBkgndMode VALUES blCOPY, blTOPLEFT, blTOPRIGHT, blBOTTOMLEFT, blBOTTOMRIGHT, blCENTER, blFIT, blFITSMOOTH, blTILED, blSTRETCH, blSTRETCHSMOOTH, blFILL, blFILLSMOOTH PROPERTY nBkgndMarginX INIT 0 PROPERTY nBkgndMarginY INIT 0 PROPERTY nGradient INIT grNONE VALUES grNONE, grHORIZONTAL, grVERTICAL PROPERTY nClrPaneEnd INIT clBtnFace EDITOR PE_Color PROTECTED: DATA nCtlStyle INIT nOr( WS_CHILD, WS_CLIPCHILDREN, WS_CLIPSIBLINGS ) DATA nExStyle INIT WS_EX_CONTROLPARENT DATA hBkgnd INIT 0 DATA lBkgndAlpha INIT .F. DATA lPopup INIT .F. PUBLIC: PROPERTY lTabStop INIT .F. PROPERTY oMenu WRITE METHOD SetMenu AS TMenu PROPERTY oActiveControl WRITE INLINE ::FoActiveControl := Value, ::oParent:oActiveControl := Self AS TControl DATA aControls READONLY INIT {} METHOD Enable() METHOD Disable() METHOD GoNextControl() // --> hCtl | Zero METHOD GoPrevControl() // --> hCtl | Zero METHOD GoFirstControl() // --> oCtl | Nil METHOD InsertControl( oControl ) // --> Nil METHOD RemoveControl( oControl ) // --> Nil METHOD Redraw() // --> Nil METHOD RequestState() // --> Nil RESERVED: METHOD Free() METHOD SetMenu( oMenu ) METHOD SetBkgnd( oBkgnd ) METHOD SetBkgndMode( nBkgndMode ) METHOD SetTabStop( lTabStop ) INLINE ::ChangeExStyle( WS_EX_CONTROLPARENT, !::Super:SetTabStop( ltabStop ) ), ::FlTabStop METHOD WMSetFocus( hCtl ) METHOD WMCommand( wParam, Handle ) METHOD WMNotify( nWParam, nLParam ) METHOD WMSize() INLINE ::AlignControls(), 0 METHOD WMEraseBkgnd( wParam, lParam ) METHOD WMPrintClient() EXTERN XWinControl_WMEraseBkgnd() METHOD WMDestroy() METHOD WMCtlColorStatic( nWParam, nLParam ) EXTERN XWinControl_CtlColor() //INLINE ::CtlColor( nWParam, nLParam ) METHOD WMCtlColorBtn( nWParam, nLParam ) EXTERN XWinControl_CtlColor() //INLINE ::CtlColor( nWParam, nLParam ) METHOD WMCtlColorEdit( nWParam, nLParam ) EXTERN XWinControl_CtlColor() //INLINE ::CtlColor( nWParam, nLParam ) METHOD WMCtlColorListBox( nWParam, nLParam ) EXTERN XWinControl_CtlColor() //INLINE ::CtlColor( nWParam, nLParam ) METHOD WMCtlColorScrollBar( nWParam, nLParam ) EXTERN XWinControl_CtlColor() //INLINE ::CtlColor( nWParam, nLParam ) METHOD WMExitMenuLoop( nWParam, nLParam ) INLINE ::lPopup := ( nWParam != 0 ) METHOD CtlColor( hDC, hControl ) METHOD AlignControls() ENDCLASS //-------------------------------------------------------------------------- METHOD Free() CLASS XWinControl IF ! Empty( ::FoBkGnd ) IF ::hBkgnd != ::FoBkGnd:Handle DeleteObject( ::hBkGnd ) ::hBkgnd := 0 ENDIF ::FoBkGnd:End() ELSEIF ! Empty( ::hBkgnd ) DeleteObject( ::hBkGnd ) ::hBkgnd := 0 ENDIF IF ! Empty( ::FoMenu ) ::FoMenu:Destroy() ENDIF RETURN ::Super:Free() //-------------------------------------------------------------------------- METHOD InsertControl( oControl ) CLASS XWinControl AAdd( ::aControls, oControl ) IF oControl:nAlign != alNONE ::AlignControls() ENDIF IF oControl:IsKindOf( "TStdControl" ) .AND. ! Empty( oControl:cMessage ) ::oForm:lMsgAuto := .T. ENDIF ::oForm:AddShortCut( oControl ) RETURN Nil //-------------------------------------------------------------------------- METHOD RemoveControl( oControl ) CLASS XWinControl LOCAL n IF ( n := AScan( ::aControls, {| Ctl | Ctl:Handle == oControl:Handle } ) ) > 0 ADel( ::aControls, n ) ASize( ::aControls, Len( ::aControls ) - 1 ) ::oForm:DelShortCut( oControl ) ENDIF RETURN Nil //-------------------------------------------------------------------------- METHOD SetMenu( oMenu ) CLASS XWinControl // IOZ: .And. ... aņadido para evitar efecto visual horroroso IF ! Empty( ::FoMenu ) .and. ( Empty( oMenu ) .or. Empty( oMenu:aItems ) ) SetMenu( ::Handle, 0 ) ENDIF IF ! Empty( oMenu ) oMenu:oParent := Self IF ! Empty( oMenu:aItems ) // NOTA: Si no hay items es porque se esta creando desde el .xfm y el componente // se llama ::oMenu. En este caso no hay que asignarlo porque da problemas. Ya se // encargara de asignarlo el metodo :SetMenu() - [JFG] ::FoMenu := oMenu SetMenu( ::Handle, ::FoMenu:Handle ) ENDIF Endif RETURN oMenu //-------------------------------------------------------------------------- METHOD SetBkgnd( oBkgnd ) CLASS XWinControl IF ::FoBkgnd != Nil IF ::hBkgnd != ::FoBkgnd:Handle DeleteObject( ::hBkgnd ) ENDIF ::FoBkgnd:Destroy() ::FoBkgnd := Nil ::hBkgnd := 0 ENDIF IF oBkgnd != Nil IF ValType( oBkgnd ) != "O" oBkgnd := TPicture():Create( oBkgnd ) ENDIF ::FoBkgnd := oBkgnd ::hBkgnd := oBkgnd:Handle ::lBkgndAlpha := oBkgnd:lTransparent ENDIF ::Refresh( .T. ) RETURN Nil //-------------------------------------------------------------------------- METHOD SetBkgndMode( nBkgndMode ) CLASS XWinControl ::FnBkgndMode := nBkgndMode IF ::oBkgnd != Nil ::hBkgnd := ::oBkgnd:Handle ENDIF RETURN Nil //-------------------------------------------------------------------------- METHOD Enable() CLASS XWinControl AEval( ::aControls, {|oCtl| IIF( oCtl:lEnabled, EnableWindow( oCtl:Handle, .T. ), ) } ) ::Super:Enable() ::Redraw() RETURN .T. //-------------------------------------------------------------------------- METHOD Disable() CLASS XWinControl AEval( ::aControls, {|oCtl| EnableWindow( oCtl:Handle, .F. ) } ) ::Super:Disable() ::Redraw() RETURN .F. //-------------------------------------------------------------------------- METHOD GoFirstControl() CLASS XWinControl LOCAL n, oCtl IF ::lVisible .AND. IsWindowEnabled( ::Handle ) FOR n := 1 TO Len( ::aControls ) oCtl := ::aControls[n] IF oCtl:lVisible .AND. oCtl:lEnabled .AND. oCtl:lTabStop .AND. ( ! oCtl:IsKindOf( "XRadio" ) .OR. oCtl:lChecked ) oCtl:SetFocus() RETURN octl ELSEIF oCtl:IsKindOf( "XWinControl" ) IF ( oCtl := oCtl:GoFirstControl() ) != Nil RETURN oCtl ENDIF ENDIF NEXT ELSE ::GoNextControl( ::Handle ) ENDIF RETURN Nil //-------------------------------------------------------------------------- METHOD WMSetFocus( hCtl ) CLASS XWinControl IF ::lTabStop RETURN ::Super:WMSetFocus( hCtl ) ENDIF ::oForm:OnChangeFocus( GetControlFromHandle( hCtl ), Self ) ::oForm:RequestState() If Empty( ::oActiveControl ) ::oActiveControl := ::GoFirstControl() Else ::oActiveControl:SetFocus() Endif RETURN 0 //-------------------------------------------------------------------------- METHOD WMCommand( wParam, Handle ) CLASS XWinControl LOCAL nNotifyCode := HiWord( wParam ) LOCAL nId := LoWord( wParam ) LOCAL oCtl IF Handle == 0 IF nNotifyCode == 0 // Menu IF ::lPopup .AND. ! Empty( ::oForm:oPopup ) ::oForm:oPopup:DoAction( nId ) ELSEIF ! Empty( ::oMenu ) ::oMenu:DoAction( nId ) ENDIF ELSEIF nNotifyCode == 1 // Accelerator ENDIF ELSEIF Handle != ::Handle // Control IF ! Empty( oCtl := GetControlFromHandle( Handle ) ) RETURN oCtl:Command( nNotifyCode, nId ) ENDIF ENDIF RETURN Nil //-------------------------------------------------------------------------- METHOD CtlColor( hDC, hControl ) CLASS XWinControl LOCAL oControl := GetControlFromHandle( hControl ) IF oControl != Nil RETURN oControl:GetCtlColor( hDC ) ELSEIF GetParent( hControl ) == ::Handle .AND. ::oBrush != Nil RETURN ::oBrush:Handle ENDIF RETURN Nil //-------------------------------------------------------------------------- METHOD Redraw() CLASS XWinControl IF ! Empty( ::Handle ) RedrawWindow( ::Handle,,, nOr( RDW_FRAME, RDW_INVALIDATE, RDW_UPDATENOW, RDW_ALLCHILDREN ) ) ENDIF RETURN Nil //-------------------------------------------------------------------------- METHOD RequestState() CLASS XWinControl LOCAL nFor, nLen nLen := Len( ::aControls ) ::Super:RequestState() FOR nFor := nLen TO 1 STEP -1 WITH OBJECT ::aControls[ nFor ] IF :IsDerivedFrom( "TStdControl" ) :RequestState() ENDIF END WITH NEXT RETURN Nil //-------------------------------------------------------------------------- METHOD WMDestroy() CLASS XWinControl ::Super:WMDestroy() ::aControls := {} RETURN Nil //--------------------------------------------------------------------------