To Antonio: ReadVar()

To Antonio: ReadVar()

Postby Colin Wisbey » Sat Jan 24, 2009 6:48 am

I suggest a better approach to determing READVAR() is by using :oGet:Name by making the following simple changes to FHW source:

1. In FIVEWIN.CH:

#xcommand REDEFINE GET [ <oGet> VAR ] <uVar> ;
[ ID <nId> ] ;
[ <dlg: OF, WINDOW, DIALOG> <oDlg> ] ;
[ <help:HELPID, HELP ID> <nHelpId> ] ;
[ VALID <ValidFunc> ] ;
[ <pict: PICT, PICTURE> <cPict> ] ;
[ <color:COLOR,COLORS> <nClrFore> [,<nClrBack>] ] ;
[ FONT <oFont> ] ;
[ CURSOR <oCursor> ] ;
[ MESSAGE <cMsg> ] ;
[ <update: UPDATE> ] ;
[ WHEN <uWhen> ] ;
[ ON CHANGE <uChange> ] ;
[ <readonly: READONLY, NO MODIFY> ] ;
[ <spin: SPINNER> [ON UP <SpnUp>] [ON DOWN <SpnDn>] [MIN <Min>] [MAX <Max>] ] ;
=> ;
[ <oGet> := ] TGet():ReDefine( <nId>, bSETGET(<uVar>), <oDlg>,;
<nHelpId>, <cPict>, <{ValidFunc}>, <nClrFore>, <nClrBack>,;
<oFont>, <oCursor>, <cMsg>, <.update.>, <{uWhen}>,;
[ \{|nKey,nFlags,Self| <uChange> \}], <.readonly.>,;
<.spin.>, <{SpnUp}>, <{SpnDn}>, <{Min}>, <{Max}>, <"uVar">) // added <"uVar"> to this line


// Do same for @ ... SAY ... GET ...
-------------------

2. In TGET.PRG:

(i)
METHOD ReDefine( nId, bSetGet, oWnd, nHelpId, cPict, bValid,;
nClrFore, nClrBack, oFont, oCursor, cMsg,;
lUpdate, bWhen, bChanged, lReadOnly,;
lSpinner, bUp, bDown, bMin, bMax, uVarNam) CONSTRUCTOR // added uVarNam

(ii)
METHOD ReDefine( nId, bSetGet, oWnd, nHelpId, cPict, bValid, nClrFore,;
nClrBack, oFont, oCursor, cMsg, lUpdate, bWhen, bChanged,;
lReadOnly, lSpinner, bUp, bDown, bMin, bMax,;
uVarNam ) CLASS TGet // added uVarNam

....
....
DEFAULT oWnd := GetWndDefault(),;
nClrFore := GetSysColor( COLOR_WINDOWTEXT ),;
nClrBack := GetSysColor( COLOR_WINDOW ),;
lUpdate := .f., lReadOnly := .f., lSpinner := .f.,;
uVarNam := SPAC(4) //added uVarNam
...
...
::oGet = GetNew( 20, 20, bSetGet, uVarNam, cPict ) // inserted uVarNam (which is how Clipper did it anyway)
...

// Do same for METHOD NEW
--------------------------

With these simple changes to FWH source, the app can get the equivalent of READVAR() by

oMyGetObj:oGet: Name

I made the above changes to my own copies of FWH source when I first switched from DOS Clipper to FW many years ago and it's always seemed to work fine.

Colin
Colin Wisbey
 
Posts: 56
Joined: Mon Jul 03, 2006 2:34 am

Re: To Antonio: ReadVar()

Postby Colin Wisbey » Sat Jan 24, 2009 8:11 am

Here's a template example of possible usage:
------------------
...
...
REDEFINE GET oMYGet1 VAR CustNo ID 101 OF oDlg UPDATE VALID {|oGet|GENERALUDF(oGet)}
REDEFINE GET oMyGet2 VAR PostCode ID 102 OF oDlg UPDATE VALID {|oGet|GENERALUDF(oGet)}
REDEFINE GET oMyGet3 VAR ProductNo ID 103 OF oDlg UPDATE VALID {|oGet|GENERALUDF(oGet)}
...
...
------------------------

FUNCTION GENERALUDF(oGet)

LOCAL cVarNam := UPPER(oGet:oGet:Name)

IF "CUSTNO" $ cVarNam
<do something specific to CUSTNO>
ELSEIF "POSTCODE" $ cVarNam
<do something specific to POSTCODE >
ELSEIF "PRODUCTNO" $ cVarNam
<do something specific to PRODUCTNO>
ENDI

<do some additional stuff common to all cases>

RETU .T.
--------------------------------------
Colin Wisbey
 
Posts: 56
Joined: Mon Jul 03, 2006 2:34 am

Re: To Antonio: ReadVar()

Postby anserkk » Sat Jan 24, 2009 8:43 am

Dear Mr.Colin
Are you talking about the substitute of oGet:VarGet(). Correct me if I am wrong. I could not understand the advantage

Regards

Anser
User avatar
anserkk
 
Posts: 1332
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: To Antonio: ReadVar()

Postby Colin Wisbey » Sat Jan 24, 2009 9:02 am

Hi Anser

No. oGet:VarGet returns the contents of the get. (e.g. "Smith")
oGet:Name returns the name of the GET's variable (e.g. "Surname").

My suggested changes to FWH code are no big deal and there are usually other approaches that can be used. It's just that I've recently read some posts discussing READVAR() / oGet:Name and, for some types of needs of some people, my approach might be a bit simpler than others I've seen (depending on why such person might want to know the name of the current GET variable and/or what they intend to do with the result).

Colin
Colin Wisbey
 
Posts: 56
Joined: Mon Jul 03, 2006 2:34 am

Re: To Antonio: ReadVar()

Postby anserkk » Sat Jan 24, 2009 9:43 am

Dear Mr.Colin,

Thankyou for the information. Now I got it.

Regards

Anser
User avatar
anserkk
 
Posts: 1332
Joined: Fri Jun 13, 2008 11:04 am
Location: Kochi, India

Re: To Antonio: ReadVar()

Postby Antonio Linares » Mon Jan 26, 2009 12:01 am

Colin,

A very good, simple and effective solution. Many thanks! :-)

We have already implemented it for FWH 9.01, with some modifications:

1. Please notice that since ... GET ... ACTION ... implementation, the preprocessor adds these two extra params:

... , [\{|self| <uAction> \}], <cBmpName>, <"uVar"> )

so we have added <"uVar"> after them. The same applies for supplied params to Method New() and Redefine()

2. We have named the new param as cVarName

3. We don't default initialize it to Space( 4 ). We see no reason for it, as we were using nil before with no problems. We appreciate your comments about this. thanks
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42080
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: To Antonio: ReadVar()

Postby arpipeline » Sat May 02, 2009 8:06 pm

Antonio,

I have run across this issue in my code way back in the day using Clipper and migrating to FiveWin. I solved it the exact same way, except I took it a step further. In every control that can "touch" a database field directly, CHECKBOX, RADIO, RADMENU, MGET, TGET, COMBO, I've implemented the same thing -- <"uVar"> -- in the #command statements. This also means that I have to watch for changes in each new FW release and modify one or more souce files.

I use ReadVar to direct calculation rountines inside our application. We have many forms that "GET" the same field name over and over, some are radio buttons, checkboxes, comboboxes and memo fields. It's a document based system and many of the documents repeat the same fields. Rather than code an ON CHANGE clause or VALID with hard coded calculation routine specific to each field, I trap the uVar name via ReadVar in a central calculation and route control to the appropriate calculation function. This allows me to make code changes more efficiently, and in one location, and it works for all appropriate controls, not just a TGet.

I would hope that you see merit in modifying fivewin.ch and the 6 or so classes to expose <"uVar"> to all controls that may accept a DB field or a mem field of the same type. Maybe I am wrong, but there must some other way to get the "name" of the variable in focus and not just it's value. If so, let me know that that method is.

Thanks
User avatar
arpipeline
 
Posts: 36
Joined: Thu Oct 26, 2006 5:23 pm
Location: United States

Re: To Antonio: ReadVar()

Postby Antonio Linares » Sun May 03, 2009 12:09 am

ARoss,

> I've implemented the same thing -- <"uVar"> -- in the #command statements

If you are so kind to publish here your changes, then we can implement them for next FWH build so there is no further need for you to modify those files in every FWH build, thanks :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42080
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: To Antonio: ReadVar()

Postby arpipeline » Sun May 03, 2009 8:45 am

Antonio,

For TGet, TCheckBox, TRadMenu, TCheckBox, TMultiGet, I modified each control's #command statement (both New and Redefine statements) in FiveWin.ch like so:

Code: Select all  Expand view

// This is for Radio Buttons

#xcommand @ <nRow>, <nCol> RADIO [ <oRadMenu> VAR ] <nVar> ;
             [ <prm: PROMPT, ITEMS> <cItems,...> ] ;
             [ <of: OF, WINDOW, DIALOG> <oWnd> ] ;
             [ <help:HELPID, HELP ID> <nHelpId,...> ] ;
             [ <change: ON CLICK, ON CHANGE> <uChange> ] ;
             [ COLOR <nClrFore> [,<nClrBack>] ] ;
             [ MESSAGE <cMsg> ] ;
             [ <update: UPDATE> ] ;
             [ WHEN <uWhen> ] ;
             [ SIZE <nWidth>, <nHeight> ] ;
             [ VALID <uValid> ] ;
             [ <lDesign: DESIGN> ] ;
             [ <lLook3d: 3D, _3D> ] ;
             [ <lPixel: PIXEL> ] ;
       => ;
          [ <oRadMenu> := ] TRadMenu():New( <nRow>, <nCol>, {<cItems>},;
             bSETGET(<nVar>), <oWnd>, [{<nHelpId>}], <{uChange}>,;
             <nClrFore>, <nClrBack>, <cMsg>, <.update.>, <{uWhen}>,;
             <nWidth>, <nHeight>, <{uValid}>, <.lDesign.>, <.lLook3d.>,;
             <.lPixel.>, [color=#FF0000]<"nVar"> )  // <-nVar Passed to TRadio[/color]


In each Class, I modify the new and redfine Methods to accept the "Name" variable like so:

Code: Select all  Expand view

   METHOD New( nRow, nCol, acItems, bSetGet, oWnd, aHelpIds, bChange,;
               nClrText, nClrPane, cMsg, lUpdate, bWhen, nWidth, nHeight,;
               bValid, lDesign, l3D, lPixel, [color=#FF0000]cVarName[/color] ) CONSTRUCTOR

METHOD New( nRow, nCol, acItems, bSetGet, oWnd, aHelpIds, bChange,;
            nClrText, nClrPane, cMsg, lUpdate, bWhen, nWidth, nHeight,;
            bValid, lDesign, l3D, lPixel, [color=#FF0000]cVarName[/color] ) CLASS TRadMenu

   METHOD Redefine( bSetGet, oWnd, aHelpIds, aRadioIDs, bChange,;
                    nClrText, nClrPane, cMsg, lUpdate, bWhen,;
                    bValid, [color=#FF0000]cVarName[/color] ) CONSTRUCTOR

METHOD Redefine( bSetGet, oWnd, aHelpIds, anItemsIDs, bChange, nClrText,;
                 nClrPane, cMsg, lUpdate, bWhen, bValid, [color=#FF0000]cVarName[/color] )  CLASS TRadMenu
 


This is the same way you modified TGet.

I then assign the cVarName data element (inherited from TControl) in the New and Redefine Methods of each control type:

Code: Select all  Expand view

// Somewhere in both the New and Redefine Method of each control class add:
::cVarName  = cVarName
 


The TRadMenu class is a bit different because you have to pass along the "Name" to TRadio like so:

Code: Select all  Expand view

   // TRadMenu New Method
   for n = 1 to Len( acItems )
      #ifndef __XPP__
      AAdd( ::aItems, TRadio():New( nRow + ( ( n - 1) * nStep ) , nCol, acItems[ n ],;
            n == 1,;                // First element is group
            n == Eval( bSetGet ),;  // Is Checked ?
            n, oWnd, Self, aHelpIds[ n ], nClrText, nClrPane, cMsg, lUpdate, bWhen,;
            nWidth, nHeight, bValid, lDesign, lPixel, [color=#FF0000]cVarName[/color] ) )
      #else
      AAdd( ::aItems, TRadio():New():_New( nRow + ( (n - 1 ) * nStep ), nCol, acItems[ n ],;
            n == 1,;                // First element is group
            n == Eval( bSetGet ),;  // Is Checked ?
            n, oWnd, Self, aHelpIds[ n ], nClrText, nClrPane, cMsg, lUpdate, bWhen,;
            nWidth, nHeight, bValid, lDesign, lPixel, [color=#FF0000]cVarName[/color] ) )
      #endif
   next
   
   // from TRadMenu Redefine Method
   for n = 1 to Len( anItemsIDs )
       AAdd( ::aItems, TRadio():ReDefine( anItemsIDs[ n ], ;
                               n == Eval( bSetGet ),;  // Is Checked ?
                               n,;
                               oWnd, Self, aHelpIds[ n ], nClrText, nClrPane,;
                               cMsg, lUpdate, bWhen, bValid, [color=#FF0000]cVarName[/color] ) )

 


Finally, in TControl's GotFocus Method I modify like so:

Code: Select all  Expand view
METHOD GotFocus( hCtlLost ) CLASS TControl

   ::lFocused       = .t.
   ::oWnd:nResult   = Self  // old code pending to be oCtlFocus
   ::oWnd:oCtlFocus = Self
   ::oWnd:hCtlFocus = ::hWnd
   ::SetMsg( ::cMsg )

   [color=#FF0000]ReadVar( ::cVarName )[/color]

   if ::lDrag
      ::ShowDots()
   endif

   if ::bGotFocus != nil
      return Eval( ::bGotFocus, Self, hCtlLost )
   endif

return nil


The cool thing you can do is expose the field names in your program using ::bGotFocus in TControl to show the field name in the main window's Message Bar or wherever you want. I do this to help our integrators know what DB field names are where in the application. That way, they don't always have to refer to a data dictionary or documentation if the are writing custom reports or other add ons.

Thanks
User avatar
arpipeline
 
Posts: 36
Joined: Thu Oct 26, 2006 5:23 pm
Location: United States

Re: To Antonio: ReadVar()

Postby Horizon » Fri May 20, 2011 2:43 pm

Hi,

There is a cVarName in TGet. But I could not show it. I use unchanged fwh classes and fivewin.ch.

How Can I show variable name of TGet, TCombobox, Tcheckbox (all input controls)?

Thanks,
Regards,

Hakan ONEMLI

Harbour & MSVC 2022 & FWH 23.04
Horizon
 
Posts: 1322
Joined: Fri May 23, 2008 1:33 pm

Re: To Antonio: ReadVar()

Postby Horizon » Sat May 21, 2011 11:09 am

Hi,

I can show variables name in TGet as described at first message. using oGet:oGet:Name. But I could not get other controls.

What does the cVarName for?

Thanks,
Regards,

Hakan ONEMLI

Harbour & MSVC 2022 & FWH 23.04
Horizon
 
Posts: 1322
Joined: Fri May 23, 2008 1:33 pm


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot], Rick Lipkin and 53 guests