Page 1 of 2

SAY

Posted: Thu Sep 25, 2008 7:38 am
by wmormar
Amigos,

Alguien podría comentar como hacerle para que el recuadro (control) del SAY (redefine) no se amplíe al modificar el texto, sino que el texto se trunque al tamaño del SAY o mejor dicho el control.

espero haberme explicado.

gracias de antemano

Posted: Thu Sep 25, 2008 9:09 am
by Antonio Linares
William,

Recientemente hemos modificado el método SetText() de la Clase TSay para que ajuste el tamaño del control al texto a mostrar, para que se vea en su totalidad.

Este cambio puede ser no deseable en algunas circunstancias. Posiblemente la solución sería añadir una nueva DATA lAdjust ó similar, que controle si ajustar ó no el tamaño del SAY.

Aqui tienes el código más reciente de este método por si quieres que lo revisemos juntos, y decidamos la forma más adecuada. Gracias!

Code: Select all

METHOD SetText( cText ) CLASS TSay

   local hDC, nWidth

   DEFAULT ::lTransparent := .f.

   ::cCaption := If( ::cPicture != nil, Transform( cText, ::cPicture ),;
                     cValToChar( cText ) )

   #ifndef __CLIPPER__
      if ! Empty( ::hWnd ) .and. ::oWnd:oBrush != nil .and. Empty( ::oWnd:oBrush:hBitmap ) .and. ( IsAppThemed() .or. ::lTransparent )
         DrawPBack( ::hWnd, hDC := GetDC( ::hWnd ) )
         ReleaseDC( ::hWnd, hDC )
      endif   
   #endif

   if ! Empty( ::hWnd )
      if ! lAnd( GetWindowLong( ::hWnd, GWL_STYLE ), nOr( SS_LEFT, SS_RIGHT, SS_CENTER ) )
         nWidth = GetTextWidth( 0, ::cCaption, If( ::oFont != nil, ::oFont:hFont,) ) + 20
         if nWidth > ::nWidth
            ::nWidth = nWidth
         endif   
      endif   
      SetWindowText( ::hWnd, ::cCaption )
   endif   

return nil

Posted: Thu Sep 25, 2008 9:29 am
by wmormar
Antonio,

eso ajustaria el control al tamaño del texto.

la idea es si el control (recurso) tiene un tamaño definido, al cambiar el texto, este no cambie (recurso) el tamaño.

gracias antonio

Posted: Thu Sep 25, 2008 9:45 am
by wmormar
Antonio,

creo que lo mas adecuado sería poder ajustar el control de forma opcional.

la DATA lAdjust, sería lo mejor; desde luego, sería igual de conveniente colocarlo en el preprocesado

Posted: Thu Sep 25, 2008 10:19 am
by wmormar
Antonio,

aquí la modificación al método

Code: Select all

METHOD SetText( cText ) CLASS TSay 

   local hDC, nWidth 

   DEFAULT ::lTransparent := .f. 

   ::cCaption := If( ::cPicture != nil, Transform( cText, ::cPicture ),; 
                     cValToChar( cText ) ) 

   #ifndef __CLIPPER__ 
      if ! Empty( ::hWnd ) .and. ::oWnd:oBrush != nil .and. Empty( ::oWnd:oBrush:hBitmap ) .and. ( IsAppThemed() .or. ::lTransparent ) 
         DrawPBack( ::hWnd, hDC := GetDC( ::hWnd ) ) 
         ReleaseDC( ::hWnd, hDC ) 
      endif    
   #endif 

   if ! Empty( ::hWnd )
      if ! lAnd( GetWindowLong( ::hWnd, GWL_STYLE ), nOr( SS_LEFT, SS_RIGHT, SS_CENTER ) ) .AND. ::lAdjust
         nWidth = GetTextWidth( 0, ::cCaption, If( ::oFont != nil, ::oFont:hFont,) ) + 20
         if nWidth > ::nWidth 
            ::nWidth = nWidth 
         endif    
      endif    
      SetWindowText( ::hWnd, ::cCaption ) 
   endif    

return nil
aquí el preprocesado

Code: Select all

#xcommand REDEFINE SAY [<oSay>] ;
             [ <label: PROMPT, VAR> <cText> ] ;
             [ <pict: PICT, PICTURE> <cPict> ] ;
             [ ID <nId> ] ;
             [ <dlg: OF,WINDOW,DIALOG > <oWnd> ] ;
             [ <color: COLOR,COLORS > <nClrText> [,<nClrBack> ] ] ;
             [ <update: UPDATE > ] ;
             [ FONT <oFont> ] ;
             [ <trans: TRANSPARENT> ] ;
             [ <adj: ADJUST> ] ;
       => ;
          [ <oSay> := ] TSay():ReDefine( <nId>, <{cText}>, <oWnd>, ;
                        <cPict>, <nClrText>, <nClrBack>, <.update.>, <oFont>, <.trans.>, <.adj.> )

#xcommand @ <nRow>, <nCol> SAY [ <oSay> <label: PROMPT,VAR > ] <cText> ;
             [ <pict: PICT, PICTURE> <cPict> ] ;
             [ <dlg: OF,WINDOW,DIALOG > <oWnd> ] ;
             [ FONT <oFont> ]  ;
             [ <lCenter: CENTERED, CENTER > ] ;
             [ <lRight:  RIGHT >    ] ;
             [ <lBorder: BORDER >   ] ;
             [ <lPixel: PIXEL, PIXELS > ] ;
             [ <color: COLOR,COLORS > <nClrText> [,<nClrBack> ] ] ;
             [ SIZE <nWidth>, <nHeight> ] ;
             [ <design: DESIGN >  ] ;
             [ <update: UPDATE >  ] ;
             [ <lShaded: SHADED, SHADOW > ] ;
             [ <lBox:    BOX   >  ] ;
             [ <lRaised: RAISED > ] ;
             [ <adj: ADJUST> ] ;
      => ;
          [ <oSay> := ] TSay():New( <nRow>, <nCol>, <{cText}>,;
             [<oWnd>], [<cPict>], <oFont>, <.lCenter.>, <.lRight.>, <.lBorder.>,;
             <.lPixel.>, <nClrText>, <nClrBack>, <nWidth>, <nHeight>,;
             <.design.>, <.update.>, <.lShaded.>, <.lBox.>, <.lRaised.>, <.adj.> )
espero sea lo correcto.

Posted: Thu Sep 25, 2008 10:29 am
by Antonio Linares
William,

Gracias! :-)

Una pregunta: Entonces le damos el valor .F. por defecto a lAdjust ?

No sería preferible lo contrario ?

Posted: Thu Sep 25, 2008 10:32 am
by wmormar
Antonio,

creo que sería mejor iniciar la Data con valor .f.
no todos tenemos la necesidad específica de ajustar el control al texto

Posted: Thu Sep 25, 2008 10:44 am
by wmormar
Antonio,

Aquí la clase completa.

Code: Select all

#include "FiveWin.ch"
#include "Constant.ch"

#define LTGRAY_BRUSH       1
#define TRANSPARENT        1

#define SS_CENTER          1
#define SS_RIGHT           2
#define SS_GRAYRECT        5 // BOXRECT

#define DLGC_BUTTON     8192   // 0x2000

#define COLOR_WINDOW       5
#define COLOR_WINDOWTEXT   8
#define COLOR_BTNFACE     15

#define WM_NCHITTEST     132  // 0x84

#define GWL_STYLE      (-16)

#ifdef __XPP__
   #define Super ::TControl
   #define New   _New
#endif

//----------------------------------------------------------------------------//

CLASS TSay FROM TControl

   DATA   l3D
   DATA   cPicture
   DATA   bGet
   DATA   lWantClick
   DATA   lAdjust

   METHOD New( nRow, nCol, bText, oWnd, cPicture, oFont,;
               lCentered, lRight, lBorder, lPixels, nClrText, nClrBack,;
               nWidth, nHeight, lDesign, lUpdate, lShaded, lBox, lRaised, lAdjust ) CONSTRUCTOR

   METHOD ReDefine( nId, bText, oWnd, cPicture, ;
                    nClrText, nClrBack, lUpdate, oFont, lTransparent, lAdjust )  CONSTRUCTOR

   METHOD cToChar() INLINE  Super:cToChar( "STATIC" )

   METHOD Default()

   METHOD cGenPrg()

   #ifndef __CLIPPER__
      METHOD EraseBkGnd( hDC )
   #endif

   METHOD HandleEvent( nMsg, nWParam, nLParam )

   METHOD Initiate( hDlg )

   METHOD Refresh() INLINE If( ::bGet != nil, ::SetText( Eval( ::bGet ) ),)

   METHOD SetText( cText )

   METHOD VarPut( cValue )

ENDCLASS

//----------------------------------------------------------------------------//

METHOD New( nRow, nCol, bText, oWnd, cPicture, oFont,;
            lCentered, lRight, lBorder, lPixels, nClrText, nClrBack,;
            nWidth, nHeight, lDesign, lUpdate, lShaded, lBox, lRaised, lAdjust ) CLASS TSay

   DEFAULT nRow     := 0, nCol := 0,;
           lBorder  := .f., lCentered := .f., lRight := .f., lPixels := .f.,;
           oWnd     := GetWndDefault(),;
           nClrText := oWnd:nClrText,;
           nClrBack := iif(Upper( oWnd:Classname() ) != "TWINDOW",;
                           GetSysColor( COLOR_BTNFACE ),;
                           oWnd:nClrPane),;
           nHeight  := If( oFont != nil, Abs( oFont:nHeight ), SAY_CHARPIX_H ),;
           lDesign  := .f., bText := { || "" },;
           lUpdate  := .f., lShaded := .f., lBox := .f., lRaised := .f., ;
           lAdjust  := .f.

   ::l3D       = lShaded .or. lBox .or. lRaised
   ::bGet      = bText
   ::bSetGet   = bText
   ::oFont     = oFont
   ::cPicture  = cPicture

   ::cCaption  = If( Empty( cPicture ), cValToChar( Eval( bText ) ),;
                     Transform( Eval( bText ), cPicture ) )

   // DEFAULT nWidth := SAY_CHARPIX_W * Len( ::cCaption ) - 4
   DEFAULT nWidth := GetTextWidth( 0, ::cCaption, If( oFont != nil, oFont:hFont,;
           If( oWnd:oFont != nil, oWnd:oFont:hFont,) ) )

   if ! lPixels
      ::nTop  = nRow * SAY_CHARPIX_H + 2
      ::nLeft = nCol * SAY_CHARPIX_W
   else
      ::nTop  = nRow
      ::nLeft = nCol
   endif

   ::nBottom   = ::nTop + nHeight - 1
   ::nRight    = ::nLeft + nWidth - 1

   ::oWnd      = oWnd
   ::nId       = ::GetNewId()
   ::nStyle    = nOR( WS_CHILD, WS_VISIBLE,;
                 If( lDesign, nOr( WS_CLIPSIBLINGS, WS_TABSTOP ), 0 ),;
                 If( lCentered, SS_CENTER, If( lRight, SS_RIGHT, SS_LEFT ) ),;
                 If( lBorder, WS_BORDER, 0 ),;
                 If( lShaded, SS_BLACKRECT, 0 ),;
                 If( lBox,    SS_GRAYRECT,  0 ),;
                 If( lRaised, SS_WHITERECT, 0 ) )
   ::lDrag     = lDesign
   ::lCaptured = .f.
   ::lUpdate   = lUpdate
   ::lWantClick = .f.
   ::lAdjust   = lAdjust

   ::SetColor( nClrText, nClrBack )

   if ! Empty( oWnd:hWnd )
      ::Create( "STATIC" )
      ::Default()
      if oFont != nil
         ::SetFont( oFont )
      endif
      if ::l3D
         ::Set3DLook()
      endif
      oWnd:AddControl( Self )
   else
      oWnd:DefControl( Self )
   endif

   if ::lDrag
      ::CheckDots()
   endif

return Self

//----------------------------------------------------------------------------//

METHOD ReDefine( nId, bText, oWnd, cPicture,;
                 nClrText, nClrBack, lUpdate, oFont, lTransparent, lAdjust ) CLASS TSay

   DEFAULT oWnd      := GetWndDefault(),;
           nClrText  := oWnd:nClrText,;
           nClrBack  := GetSysColor( COLOR_BTNFACE ),;
           lUpdate   := .f., lTransparent := .F., ;
           lAdjust   := .f.

   ::l3D          = .f.
   ::nId          = nId
   ::bGet         = bText
   ::bSetGet      = bText
   ::cPicture     = cPicture
   ::oFont        = oFont
   ::lTransparent = lTransparent

   if bText != nil
      ::cCaption = If( Empty( cPicture ), cValToChar( Eval( bText ) ),;
                       Transform( Eval( bText ), cPicture ) )
   endif

   ::oWnd      = oWnd
   ::hWnd      = 0
   ::lDrag     = .f.
   ::lCaptured = .f.
   ::lUpdate   = lUpdate
   ::lWantClick = .f.
   ::lAdjust   = lAdjust

   ::SetColor( nClrText, nClrBack )
   oWnd:DefControl( Self )

return Self

//----------------------------------------------------------------------------//

METHOD Initiate( hDlg ) CLASS TSay

   Super:Initiate( hDlg )

   if ! IsAppThemed()
      if ::lTransparent
         if ! Empty( ::oWnd:oBrush:hBitmap )
            ::SetBrush( ::oWnd:oBrush ) 
         endif
      endif
   endif            

   if ::cCaption != nil // don't use Empty() here or blank texts will not show
      SetWindowText( ::hWnd, ::cCaption )
   else
      ::cCaption = GetWindowText( ::hWnd )
   endif

return nil

//----------------------------------------------------------------------------//

METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS TSay

   if ( ( ::lDrag .or. ::lWantClick ) .and. nMsg == WM_NCHITTEST ) // To have a standard behavior on Clicks
      return DefWindowProc( ::hWnd, nMsg, nWParam, nLParam )
   endif

return Super:HandleEvent( nMsg, nWParam, nLParam )

//----------------------------------------------------------------------------//

METHOD Default() CLASS TSay

   if ::oFont != nil
      ::SetFont( ::oFont )
   else
      ::SetFont( ::oWnd:oFont )
   endif

return nil

//----------------------------------------------------------------------------//

METHOD cGenPrg() CLASS TSay

   local cCode := CRLF + "   @ " + Str( ::nTop, 3 ) + ", " + ;
                  Str( ::nLeft, 3 ) + ' SAY "' + ::cCaption + ;
                  '" SIZE ' + Str( ::nRight - ::nTop, 3 ) + ", " + ;
                  Str( ::nBottom - ::nTop, 3 ) + " PIXEL OF oWnd" + CRLF
return cCode

//----------------------------------------------------------------------------//

#ifndef __CLIPPER__

METHOD EraseBkGnd( hDC ) CLASS TSay

   DEFAULT ::lTransparent := .f.

   if IsAppThemed() .or. ::lTransparent
      return 1
   endif

return Super:EraseBkGnd( hDC )

#endif

//----------------------------------------------------------------------------//

METHOD SetText( cText ) CLASS TSay 

   local hDC, nWidth 

   DEFAULT ::lTransparent := .f. 

   ::cCaption := If( ::cPicture != nil, Transform( cText, ::cPicture ),; 
                     cValToChar( cText ) ) 

   #ifndef __CLIPPER__ 
      if ! Empty( ::hWnd ) .and. ::oWnd:oBrush != nil .and. Empty( ::oWnd:oBrush:hBitmap ) .and. ( IsAppThemed() .or. ::lTransparent ) 
         DrawPBack( ::hWnd, hDC := GetDC( ::hWnd ) ) 
         ReleaseDC( ::hWnd, hDC ) 
      endif    
   #endif 

   if ! Empty( ::hWnd )
      if ! lAnd( GetWindowLong( ::hWnd, GWL_STYLE ), nOr( SS_LEFT, SS_RIGHT, SS_CENTER ) ) .AND. ::lAdjust
         nWidth = GetTextWidth( 0, ::cCaption, If( ::oFont != nil, ::oFont:hFont,) ) + 20
         if nWidth > ::nWidth 
            ::nWidth = nWidth 
         endif    
      endif    
      SetWindowText( ::hWnd, ::cCaption ) 
   endif    

return nil 

//----------------------------------------------------------------------------//

METHOD VarPut( cValue ) CLASS TSay

   if ! Empty( ::cPicture )
      cValue = Transform( cValue, ::cPicture )
   else
      cValue = cValToChar( cValue )
   endif

   ::bGet = { || cValue }

return nil

//----------------------------------------------------------------------------//

Posted: Thu Sep 25, 2008 2:51 pm
by Antonio Linares
William,

ok, gracias! :-)

Posted: Thu Sep 25, 2008 8:33 pm
by wmormar
Antonio Linares wrote:William,

ok, gracias! :-)
Antonio,

de nada, es un gusto aportar aunque sea un grano de mostaza.

asi quedaría la clase?

y como quito el obj TSAY de fivexh?

Posted: Thu Sep 25, 2008 8:37 pm
by Antonio Linares
William,

> asi quedaría la clase?

Si, salvo que surjan más necesidades que no hayamos previsto :-)

> como quito el obj TSAY de fivexh?

tlib.exe FiveHX.lib -+ say.obj

Posted: Thu Sep 25, 2008 8:57 pm
by wmormar
Antonio Linares wrote:William,

> asi quedaría la clase?

Si, salvo que surgen más necesidades que no hayamos previsto :-)

> como quito el obj TSAY de fivexh?

tlib.exe FiveHX.lib -+ say.obj
gracias antonio, quedó listo

Posted: Fri Sep 26, 2008 9:35 pm
by Rossine
Olá Antonio / William,

Estou com problema no "Say" quando uso "TRANSPARENT" em dialog, o texto não é quebrado para a linha debaixo. Veja o exemplo:

Code: Select all


#include "fivewin.ch"

function main

local cMsg, oSay, oDlg, cSay, oFmsg

 cSay := "Aguarde...Verificando arquivos!"

 DEFINE FONT oFmsg NAME "Arial" SIZE 18, 28 BOLD ITALIC

 DEFINE DIALOG oDlg from 0, 0 to 400, 500 pixel              && Assim funciona corretamente
*DEFINE DIALOG oDlg from 0, 0 to 400, 500 pixel TRANSPARENT  && Assim nao funciona
 
 @10, 10 say oSay var cSay size 200, 60 font oFmsg color rgb(255,0,0), rgb(0,128,0) pixel

 ACTIVATE DIALOG oDlg NOWAIT centered

 SysWait(3)

 oSay:Refresh()

 SysWait(3)

return NIL

Gracias por qualquer ajuda :lol:

Saludos,

Rossine.

Posted: Fri Sep 26, 2008 11:03 pm
by Antonio Linares
Rossine,

En la Clase TSay Método SetText() tienes que modificar esta línea:

nWidth = GetTextWidth( 0, ::cCaption, If( ::oFont != nil, ::oFont:hFont,) ) + 20

Con ese +20 se ha solucionado el ancho para fonts BOLD. Tal vez tengas que variar ese valor.

Posted: Sat Sep 27, 2008 6:20 am
by wmormar
Antonio Linares wrote:Rossine,

En la Clase TSay Método SetText() tienes que modificar esta línea:

nWidth = GetTextWidth( 0, ::cCaption, If( ::oFont != nil, ::oFont:hFont,) ) + 20

Con ese +20 se ha solucionado el ancho para fonts BOLD. Tal vez tengas que variar ese valor.
Antonio,

crees que sería interesante crear una data con el valor "20" como default y se pueda modificar a la hora de desarrollar para no ir modificando la clase cada vez que se necesite?

por ejemplo

Code: Select all

...
DATA nWidthSpecial AS NUMERIC INIT 20
...
...

nWidth = GetTextWidth( 0, ::cCaption, If( ::oFont != nil, ::oFont:hFont,) ) + ::nWithSpecial

...