Share via


Visual FoxPro - Changing a Class in Data Grids and Forms

Visual FoxPro programmers can use the VFP delivered base classes to construct forms and data grids for user data entry, reporting and viewing. The functions and tasks performed by these base classes are rudimentary. VFP programmers are encouraged to use these base classes as the starting point from which to construct their own classes in a hierarchical manner. Their own classes can greatly extend the tasks and routines performed providing an enriched programming environment that can easily be applied in a consistent manner to deliver highly functional applications to end users.
None of this is new to VFP programmers. However, there is one limitation in the Visual programming environment in respect of data grids and the addition of columns to a grid.
Under Visual FoxPro when a grid is added to a form, the programmer defines the number of columns the grid is to have. Having set the number of columns, the background VFP code actively adds the columns to the grid using the base classes of ‘Column’, ‘Header’ and ‘Textbox’ for the respective Column, Header and Text attributes. To change these base classes to the programmer defined classes; in order to use the additional functionality; under the Visual Programming environment is no small task. Especially when an application may have hundreds of data grids.
What the programmer would like to be able to do is to have the ability to define the classes for the Column, Header and Text that the grid uses when adding these elements to its structure. Unfortunately, this is not possible.
Up until recently, I have reluctantly accepted this limitation. But no more!
I have come across a method/process to overcome this limitation. What is more I could kick myself for not thinking it through and coming to the answer before now.
Most experienced VFP programmers know that the file that defines a form is in fact a normal VFP table file in disguise. Table files have the extensions
.dbf - for data and structure
.fpt - for the content of memo fields defined in the .dbf
.cdx - for defined indexes

Whereas, form files have the extensions
.scx – for the form definitions
.sct – for the content of memo fields defined in the .scx
Using the command window a form can be opened as a table with the commands:
Use “form.scx” exclusive
Browse
This shows the form.scx file as a table. Looking at the table column headings and data, it does not take long to discover that the column/field “Class” holds the class name of each object held in the form. Whilst, the column/field “ClassLoc” holds the relative address of the class library; being empty when a base class is set under “Class”.
What is more, any changes made to the tables data and saved will be reflected next time the form is opened under the Visual FoxPro programming environment.
Putting this information together into a small programming routine has allowed me to change the “Class” of every grid column text attribute in an application of over a hundred forms (most with grids) from the base class of “textbox” to my own defined class of “_textbox” which has additional programming to consistently handle, double click and right click events. Thereby making redundant my prior manual efforts of defining these events in every grid and textbox attribute in all the forms. What a productivity saver this would have been, if I had come across the solution earlier.
So what’s the small routine to save all this manual effort:
LOCAL ls1, ls2, ln1, i, lspathtemp, lnfiles
* gcnetfldr is a global holding the default drive and path
* – C:\Program Files\.
lspathtemp = gcnetfldr + "\FORMS"
* set the folder holding the forms to be changed
SET DEFAULT TO (lspathtemp)

*Step 1a
*– get the names of all SCT files in the current folder
* and change their extensions to FPT – as for a table
lnfiles = ADIR(larrayFile1, "*.sct")
FOR i = 1 TO lnfiles
   ls1 = STRTRAN(larrayFile1[i,1], ".sct", ".fpt", 1, 1, 1)
   RENAME (larrayFile1[i,1]) to (ls1)
ENDFOR

*Step 1b
* – get the names of all SCX files in the current folder
* and change their extensions to DBF – as for a table
lnfiles = ADIR(larrayFile2, "*.scx")
FOR i = 1 TO lnfiles
   ls1 = STRTRAN(larrayFile2[i,1], ".scx", ".dbf", 1, 1, 1)
   RENAME (larrayFile2[i,1]) to (ls1)
ENDFOR
RELEASE larrayFile1, larrayFile2

* Step 2
*get all the .dbf files in the current folder into an array
lnfiles = ADIR(larrayFile3, "*.dbf")
*set the complete path to the form table files
* as they are not associated with an open database
ls1 = "C:\Program Files\Microsoft Visual FoxPro 9\Acceptum\FORMS\
* loop through the files
FOR i = 1 TO lnfiles
   ls2 = ls1 + ALLTRIM(larrayFile3[i,1])
   ln1 = 0
   USE (ls2) IN 0 exclusive ALIAS xxx
   SELECT "xxx"
* changing the Class textbox to _textbox
* and the Class Location to a relative folder path
   SCAN FOR LOWER(class) = "textbox"
      replace class WITH "_textbox", classloc WITH "..\.\ffc\base.vcx"
      ln1 = ln1 + 1
   ENDSCAN
   closetable("xxx")
   Messagebox("Done " + ALLTRIM(larrayFile3[i,1]) + STR(ln1),64,”Form Update”)
ENDFOR
RELEASE larrayFile3

*Step 3
* is to change the form tables back to form files
SET DEFAULT TO (lspathtemp)
lnfiles = ADIR(larrayFile4, "*.fpt")
FOR i = 1 TO lnfiles
   ls1 = STRTRAN(larrayFile4[i,1], ".fpt", ".sct", 1, 1, 1)
   RENAME (larrayFile4[i,1]) to (ls1)
ENDFOR
lnfiles = ADIR(larrayFile5, "*.dbf")
FOR i = 1 TO lnfiles
   ls1 = STRTRAN(larrayFile5[i,1], ".dbf", ".scx", 1, 1, 1)
   RENAME (larrayFile5[i,1]) to (ls1)
ENDFOR
RELEASE larrayFile4, larrayFile5

SET DEFAULT TO (gcnetfldr)
Messagebox("Complete ", 64,”Form Updated”)

As an aside it also reduced the size of the executable.
I now hold this code in a routine which I can run regularly after adding a new form/grid combination to my application.