Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Articles
Search: 

VFP for Beginners: Part VI
Claudio Lassala, May 1, 2002
In the previous chapter of our course for beginners, we saw how it is possible to create forms in Visual FoxPro. In this chapter, we will learn how to create classes, converting our recently created database into a class that can be reused in all of our applications. Classes Very often ou...
In the previous chapter of our course for beginners, we saw how it is possible to create forms in Visual FoxPro. In this chapter, we will learn how to create classes, converting our recently created database into a class that can be reused in all of our applications.

Classes

Very often our clients ask us to change something in the appearance of our applications. Imagine, for example, if the client has asked us to change the color of the Textbox fonts of applications; the client does not like black, preferring that we use blue in these fonts. Whit the lessons learned so far, we will open each one of the screens and change the ForeColor property in each Textbox. Doing this on one simple screen with a dozen Textboxes would be an easy task, but what about changing all Textboxes, in all the screens of the application? Without doubt, this would be a very time-consuming task. And worse: what if the client does not like the tone of blue you chose, and asks you to change it into another color? Wouldn’t this be terrible?

Fortunately, Visual FoxPro gives us the possibility to work with Classes. Let us regard a class as a model to create objects. When we want to bake a chocolate cake, we will look for an appropriate chocolate cake recipe. Well, so let’s consider the chocolate cake recipe as a class, and let’s regard each chocolate cake that was baked with this recipe as an object.

Still, this is not yet the right time to learn some concepts in depth, because everything is still rather new for us. So, let us perform a practical task, because this will lead to our understanding of other aspects of our matter.

Creating a Textbox Class

Classes can be created in various ways. Let us examine one of them: on the File menu, choose New, th en Class and New File. A “New Class” dialogue box will open.

On the Class Name field, enter TextboxPadrao. On the Based On field select TextBox (this will be the base-class in VPF, through which we will be based on to create our new class). Now, in Store In enter the name of the file where the new class will be stored in – click on the button with ellipsis (…) and select the Lib\Class directory that is below our project’s directory (if we don’t choose a specific directory, the program will use the current directory). For the moment, all you have to know is that each class must be stored in a class library. Because we will create the class visually, we will store it in a visual class library whose file has a VCX extension. In this present example, the name you will give this file is MinhaBiblioteca.

Finally, click on the OK button.

The Class Designer will appear with a new Textbox, on which we will apply our changes. To keep the e xample as simple as possible, select the ForeColor property in the property box, click on the ellips is button and select the blue color. You will notice that the text inside the Textbox will appear in the blue color. Click save and close the Class Designer (clicking on the X that is on the title bar , or on the File | Close menu).

Well done. Now the Textbox class that will be used in the applications is done. Before we effectively use it, let’s learn something about IntelliDrop.

IntelliDrop

In the previous chapter your learned that when we drag fields from a Form DataEnvironment table into a Form, some controls are created, and these controls are permanently linked to the fields on that table. This is what we call IntelliDrop. We can configure IntelliDrop so that instead of using base-classes in VFP, we use our customized classes. This done, let’s now configure IntelliDrop to make it use our class in Textbox that has just been created.

Field Mapping

To configure IntelliDrop, select on the Tools | Options... menu and select the Field Mapping page. You will see that there is a mapping for each different field. As you will notice, most fields have been mapped for the Textbox class; other fields – the logic field types – were mapped for the Checkbox, and so on. It is also possible to configure the mode how the properties defined in the database (DBC) can be brought to the Form.

Now, select the Character type and click on the Modify button. As you will see, you will be able to select the type of field to be mapped. There is also a Browse button (to select the visual class lib rary select the just created MinhaBiblioteca.VCX), and a combo box to select which class will be use d for the mapping of that specific type of field. So far, all we have is the TextboxBasico class, so , select this class and click OK.

Please follow the same steps to map the other types that point to the Textbox class. Notice that, as soon as you create more specific classes, you will be able to map numeric fields for some types of classes, Data fields for other types, and so on.

To make these changes permanent, click on the Set As Default button and, finally, click OK.

Now that we have configured the File Mapping in our IntelliDrop, let’s rebuild the form that was created in the previous chapter (CadCliens.SCX). All you have to do is open it, remove all the controls that are linked to fields in tables (and its created labels) dragging again the fields of the table to the Form.

As you can see, all Textboxes show their text in blue; if you take a look at the Class and ClassLibrary properties, you will notice that they carry references to our class.

To find out more about how fun it is to create objects based on the created classes, close the Form in the editing mode and open again our class. One way to do it is by using the MODIFY CLASS command; however, an easier way to do it is by adding our class library to our project. On the Project Manag er select the Classes guide and click in Add. Select MinhaBiblioteca.vcx on the libs\class directory and click OK.

You could simply expand the class library (clicking on the plus sign), selecting the TextboxBasico class and clicking on the Modify button. The class will be opened on the Class Designer, and you can change it as you wish. For example, try to change the ForeColor to red: save and close the class, and finally, run Form CadClientes again. You will see that all Textboxes will show the text in red. Cool, isn’t it? All we did was change the class, but everywhere this class was used, it reflected the changes.

Creating a class for a Basic Database

The vast majority of applications that are created use Client Databases, similar to the ones that ar e present in our previous chapter. The code to add a registry, save, edit, etc., is always the same. The only thing that changes is the table that is being used. So, let’s just check how easy it is to create these forms on a daily basis, using a class.

Since we already have the CadClientes.SCX, and providing it works as we expect a form like this to perform, let’s use it in creating our class. Open this form in the editing mode.

Obviously, for each database form that we build, it will have different data editing controls, because each database will have different fields. So, it is necessary to delete all controls that are linked to the data that are on the Form. Another different thing in all forms is the Caption of the title bar. So, it is also necessary to change the caption into something more generic, like “Base” (we will certainly change this caption in each form that we will build afterwards).

Next step is to select File | Save as Class on the menu. With this option we will guide VFP to save the Form and generate a new class. As you will notice, the Save as Class screen is very similar to the screen used to create a new class. The only difference is that there is an option selected as Current Form (we will learn more about other options at the right moment); this option informs VFP that we will save the current form as a new class. For the name of the class, enter CadastroBasico. To file it, select the lib\class directory and name the file as Forms. In the future, we will always have to store our Form classes in this library. Finally, on the description, enter something like “Form for the Basic Database”. Press OK and close the CadClientes Form without saving it.

As we did with the class library MinhaBiblioteca.VCX – adding it to the Project Manager – the same m ust be done with the library we just created (Forms.VCX). Open the class CadastroBasico in the editi ng mode, select and click on the Modify button.

The first thing we have to do is to delete all the references of the CadClientes.SCX controls from t he code. Do you remember that on the Init() and Click() of some of the buttons we could enable and d isable some controls? Well, this must be corrected.

First, we have to make some changes in the Textbox class (TextboxBasico): open the class and add a property (menu Class | Add Property...) lCoordenar. Attribute a value like .T. to the properties window. With this property, we can programmatically control if this control must or must not be enabled. Use this opportunity also to create a checkbox class, under the CheckboxBasico name, and store it in MinhaBiblioteca.vcx, which must also have a ICoordenar property that can be started with the value .T.

Now we can start changing our Form class to make it a generic class, helping us to build any basic database screen from it.

First change will be made in the Init() method that had code that referred to the client table field. Remove this code and add the following content to this method:

With This
   .nStatus = 0

   .cmdPrimeiro.Enabled = .F.
   .cmdAnterior.Enabled = .F.
   .cmdProximo.Enabled  = not Eof()
   .cmdUltimo.Enabled   = not Eof()
EndWith

In the Click() method of the cmdNovoSalvar button, let us remove a great amount of code, that will end up like this:

With Thisform
   If .nStatus = 0
      .nStatus = 1
   Else
      .nStatus = 3
   Endif
Endwith

Question:

But all we did was to change the nStatus value of the Form, nothing else... I don’t understand.

Answer:

Don’t panic. Later on this document you will be able to understand this better.

The Click() method of the cmdEditarCancelar button will be very similar to the cmdNovoSalvar.Click(), except for the nStatus values. Check this:

With Thisform
   If .nStatus = 0
      .nStatus = 2
   Else
      .nStatus = 4
   Endif
Endwith

OK, now we have changed the major methods that referred to the fields in the Client table, in order to make the code generic enough for any situation. Let me explain why the Click() of the cmdNovoSalvar and cmdEditarCancelar buttons were so condensed: basically, when we click one of these buttons, the following actions synchronize the toolbar button, coordinate the fields that enable or disable them and do the tasks of adding a registry on the table, saving this registry or canceling changes. All this happens because the status of the Form has been changed. For the entire object property, we can create an Access method and an Assign method.

If, for example, we define that we want to use the Access and Assign method in the nStatus property, every time we will try to access the property value (i.e., when it is on the right side of the equal sign), the Access method will run:

lcVar = Thisform.nStatus

This means that we can always run the code every time the property value is submitted to a reading attempt.

Likewise, when we try to attribute a value to a property (i.e., when the property is on the left side of the sign of equal) the Assign method will run.

Thisform.nStatus = lcVar

Again, we can run the code when some process tries to attribute a value to the property.

This is like having the power to create events in our applications. For the time being, just try to understand what we said so far; later on in our series of articles we will try to give you more exam ples of the use of the Access and Assign methods that will enable your greater understanding of this issue.

For the nStatus property, we will only use the Assign method; this means that, every time some process tries to attribute a value to a property, the Assign method will run.

To create the assign Method, with the open class, select Class | Edit Property/Method, and then search the nStatus property on the list. Once found, click on checkbox Assign Method and press OK.

Now you can open the nStatus_Assign() method in its own class, filling it with the code below: With the exception of the value 0 (zero), that at this point has no specific action, for all the oth er values we will have to invoke customized methods that will be created for the Form. Each one of t hese methods will run a specific attributed functionality. We could, of course, put the entire code here, but this would pollute the method in an excessive way. Doing it like this, we make the code ea sier to read and to maintain.

Going on, we invoked the CoordenarNavegacao() method that will be responsible for coordinating the buttons on the task bar. Finally, we invoke the CoordenarCampos() method that will coordinate the Enabled/Disabled status of the controls that are in the Form. The two latter ones will be created below :

Now, create the AdicionarRegistro() method, to add registries, and that must look like this:

With This
   .nReg = Recno()
   Append Blank
   .Refresh()
Endwith

Easy, isn’t it? I bet you already knew this code; all we did was change its place. The same can be d one with the EditarRegistro() method. Create this method with the code below:

This.nReg = Recno()

No problem either. Now, create the SalvarRegistro() method:

=Tableupdate()
Thisform.Refresh
thisform.nStatus = 0
Messagebox("Registro salvo!")

You probably also knew this code. As you can notice, we are only moving some available code to more appropriate locations, in order to make the reading and maintaining process of the code easier. Now, let’s create the DesfazerAlteracoes() method:

=Tablerevert()
Go Thisform.nReg

Thisform.nStatus = 0
Thisform.Refresh

Messagebox("Edição Cancelada!")

Create the CoordenarNavegacao() method and fill it with the following code:

With This
   Do Case
      Case .nStatus = 0 or .nStatus = 4
         .cmdNovoSalvar.Picture='..\..\LIBS\GRAPH\BMP\NOVO.BMP'
         .cmdEditarCancelar.Picture='..\..\LIBS\GRAPH\BMP\EDITAR.BMP'
         .Closable = .T.

         .cmdFechar.Enabled   = .T.
         .cmdAnterior.Enabled = .T.
         .cmdProximo.Enabled  = .T.
         .cmdPrimeiro.Enabled = .T.
         .cmdUltimo.Enabled   = .T.
         .cmdExcluir.Enabled  = .T.

      Case .nStatus = 1 or .nStatus = 2
         .cmdNovoSalvar.Picture='..\..\LIBS\GRAPH\BMP\SALVAR.BMP'
         .cmdEditarCancelar.Picture='..\..\LIBS\GRAPH\BMP\DESFAZER.BMP'

         .cmdFechar.Enabled   = .F.
         .cmdAnterior.Enabled = .F.
         .cmdProximo.Enabled  = .F.
         .cmdPrimeiro.Enabled = .F.
         .cmdUltimo.Enabled   = .F.
         .cmdExcluir.Enabled  = .F.

         .Closable = .F.
   Endcase

Endwith

As you can see, this is also a known code, in which we only enabled or disabled some buttons on the toolbar, changing some images in the buttons so that they can explain the according tasks.

Now, let’s go to the method that has a code that is still unknown for us at this point. This is the method that makes sure our code to be generic. Create a method with the name EditarRegistro(). See its content:

Local lnControle, loControle, lnProp
For lnControle = 1 To Thisform.ControlCount
   loControle = Thisform.Controls(lnControle)

   lnProp = Amembers(laProp, loControle, 1)
   If Ascan(laProp,"LCOORDENAR") <> 0
      If loControle.lCoordenar
         loControle.Enabled = Iif(This.nStatus=0, .F., .T.)
      Endif
   Endif
Next

To understand what we just did:

  • First, we created some local variables that will be used in the method.

  • Then, we started a For … Not block, that will iterate through all controls of the Form. Using the ControlCount property of the Form, we obtained the whole number that identifies the number of controls in the Form.

  • In the For… Next, in the IoControle variable, we stored a control reference of the Form, which can be accessed through the Controls collection (consider a collection as an array-property); with this collection, we can access all the controls that are in the Form.

  • In the next step, we used the AMembers() function. This function creates an array of information about some object. In the first parameter we informed the name of the array that must be created (in this example, laProp). In the second parameter we informed which is the control through which we want to get information. In the third parameter, we informed what kind of information we are looking for (in this example, value 1 determined that we want to know the PEMs – Properties, Methods and Events – of the object).

  • With the Ascan() function, we searched this newly generated array, trying to search for the "lCoordenar" value, which is the property that was created for our textobasico and checkboxbasico classes, and that we must create for any other class we want to manage in our forms.

  • Should the object have the ICoordenar property, we have to check if the property is true (if its value is .T.) If yes, we can enable or disable the control, according to the value of the nStatus property in the Form.

  • Finally, with this code, we assured that any control that is included in the Form would be managed according to the Form status.

Creating Forms based on our class

As you can see, little changes were mane in our first Form to make it generic, enabling it to be reu sed. Now it is time to see how it can be used.

As a standard, every time we create a new Form in VFP, the program will create the Form that is base d on the base-class form of VFP. When you start creating your own classes, you will probably quit th is procedure (or do it more rarely). To let VFP know that you want to create new forms that are base d on another class, access the Tools | Options menu and go to Forms. When you reed Template classes, click on the checkbox Form and select our CadastroBasico class that is located on the Forms.VCX cla ss library. Close the window by clicking OK (if you want this change to be permanent – i.e., for all VFP sessions – click in Set as Default before clicking OK.

Note: Alternatively you could use the CREATE FORM command directly. For example:

Create Form MeuForm as CadastroBasico from ..\..\libs\class\Forms.vcx

In the New | File... Form menu select New File or enter the command window CREATE FORM to create a new Form. You will notice that the form will look like a basic database, exhibiting the traditional toolbar.

Now comes the fun:

  • Open the DataEnvironment in the Form
  • Add the Fornece table
  • On this table, click on the word Fields, drag it and drop it on Form.
  • Run the Form

If you performed all steps correctly, the Form will be working with all its functionalities and oper ations (add, edit, delete, browse registries, etc.). Did you notice how powerful this tool is? As so on as you create and test your class, you will be able to create Forms, without writing a single line of program.

While running this new Form, you will notice a not so interesting behavior. When we add or edit a registry, the field containing the (ID) code of this registry will open, allowing the user to change it. This is not a recommended procedure, because new registries generate this code automatically (by the Stored Procedure SP_NovaID that was created on our database some lessons ago). Once it is created, we don’t want this code to be changed. But at this point, just for teaching reasons, we chose that the user can “see” this code.

To protect this code from being changed by the user, open an editing form and make the necessary changes in the txt_ID_Fornece object:

  • On the lCoordenar property include .F. – this will prevent this control from being managed when the Form status is changed.
  • On the Enabled property include .T. – this will make sure that this control is disabled from the very beginning and remains that way.

Run the form again and try to include or to edit a registry. You will notice that, although you can see the code of this registry, you will not be able to change it.

Summary

At this point of our course, you learned how to create classes. First you learned how to create textbox and checkbox classes, and then you learned how to create a Form class for a basic database – the kind of Forms we create most frequently in most of our applications.

But this is only the first step in this great world of Object Oriented programming. Over time you wi ll learn many other tools and resources, and you will be amazed with this environment and with the empowerment Visual FoxPro provides in building applications. See you soon!

Claudio Lassala, Improving
Claudio Lassala is an independent Software Developer who currently works mostly building Ruby on Rails applications. Previously, he has worked for several years developing .NET applications, presented several lectures at Microsoft events such as PDC Brazil, TechEd Europe, and various other Microsoft seminars, as well as several conferences and user groups across North America, Europe and Brazil. He is a multiple winner of the Microsoft MVP Award since 2001 (for Visual FoxPro in 2001-2002, and for C# ever since). He has articles published on several magazines, such as MSDN Brazil Magazine and CoDe Magazine. He started the Virtual Brown Bag meetings (www.virtualbrownbag.com) in 2009 and have been hosting it weekly since then. When not writing code, Claudio is probably rocking out with his band, Descent Into Madness (http://www.descentintomadness.com). In a previous life, Claudio authored and presented several training videos that can be found on the Universal Thread.
More articles from this author
Claudio Lassala, October 1, 2004
Claudio Lassala is a well-known member of the Visual FoxPro and .NET communities, has been involved with Brazilian and American user groups, and has been part of the Universal Thread Magazine in the past, when the publication merged with his RapoZine magazine, until the moment in which he reallocate...
Claudio Lassala, December 1, 2002
West Wind Technologies has presented a one of a kind 3 day conference on WWC prior to the GLGDW conference in Milwaukee. This conference was geared towards existing WWC and general VFP Web developers with specialized topics presented by several speakers in this session style conference. Speakers inc...
Claudio Lassala, June 1, 2002
PDC 2002 - Brazil - On the vision of Claudio Lassala For the first time, Brazil hosted the Personal Developers’ Conference (PDC), the major Microsoft technologies developers’ conference. The event took place on May 6th and 7th, at the Meliá Hotel in São Paulo. Over 700 professionals attended ...
Claudio Lassala, October 1, 2002
Author: Fábio Vazquez Publisher: Axcel Books ISBN: 8573231777 Retail Price: R$ 54,00 Publication Date: 2002 Pages: 268 Fonte: http://www.axcel.com.br It has b...
Claudio Lassala, April 1, 2002
UTMag/RapoZine team Editors Michel Fournier Claudio Lassala Translation coordinators Claudio Lassala Martín Salías Translators Eduardo Vidigal Rodolfo Duarte Fábio Vazquez Claudio Rola José Cavalcanti Moacyr Zalcman Ricardo Soares Fábio Vieira ...
Claudio Lassala, July 1, 2002
UTMag/RapoZine team Editors Michel Fournier Claudio Lassala Co-editor Martín Salías Translation coordinators Claudio Lassala Martín Salías Translators Eduardo Vidigal Rodolfo Duarte Fábio Vazquez José Cavalcanti Moacyr Zalcman Fábio Vieira M...
Claudio Lassala, August 1, 2002
UTMag/RapoZine team Editors Michel Fournier Claudio Lassala Co-editor Martín Salías Translation coordinators Claudio Lassala Martín Salías Translators Eduardo Vidigal Rodolfo Duarte Fábio Vazquez José Cavalcanti Moacyr Zalcman Fábio Vieira M...
Claudio Lassala, June 1, 2002
UTMag/RapoZine team Editors Michel Fournier Claudio Lassala Co-editor Martín Salías Translation coordinators Claudio Lassala Martín Salías Translators Eduardo Vidigal Rodolfo Duarte Fábio Vazquez José Cavalcanti Moacyr Zalcman Fábio Vieira M...
Claudio Lassala, January 1, 2002
The Universal Thread Magazine has the honor to include in this month's issue two interviews which appeared in the RapoZine magazine recently. Those interviews have been conducted by Claudio Lassala. We would like to thank the RapoZine team and Claudio Lassala for allowing us to include those in th...
Claudio Lassala, September 1, 2002
UTMag/RapoZine team Editors Michel Fournier Claudio Lassala Co-editor Martín Salías Translation coordinators Claudio Lassala Martín Salías Translators Eduardo Vidigal Rodolfo Duarte Fábio Vazquez José Cavalcanti Moacyr Zalcman Fábio Vieira M...
Claudio Lassala, August 1, 2002
In an appreciation to Microsoft for the 10th year anniversary since the purchase of "Fox Software", Hugh Winters initiated, in June 2002, a 10th year anniversary event which involved the participation of one of the greatest, if not the greatest, developers community - the Visual FoxPro developers c...
Claudio Lassala, May 1, 2002
UTMag/RapoZine team Editors Michel Fournier Claudio Lassala Translation coordinators Claudio Lassala Martín Salías Translators Eduardo Vidigal Rodolfo Duarte Fábio Vazquez José Cavalcanti Moacyr Zalcman Fábio Vieira Martín Salías Antonio Castañ...
Claudio Lassala, January 1, 2002
The Universal Thread Magazine has the honor to include in this month's issue two interviews which appeared in the RapoZine magazine recently. Those interviews have been conducted by Claudio Lassala. We would like to thank the RapoZine team and Claudio Lassala for allowing us to include those in th...
Claudio Lassala, October 1, 2002
Introduction - by Claudio Lassala The life for those who work with Visual FoxPro in Brazil is not that easy. There is a lack of content in Portuguese, just a few courses, books, just the UTMag/RapoZine magazine in Portuguese, and there is no localized version of VFP in Portuguese. ...
Claudio Lassala, February 1, 2002
On January 15th, 2002, an important joint took place for our magazine. The Universal Thread Magazine and RapoZine magazine, an online magazine available for the Portuguese developers community, joined to create UTMag/RapoZine. Effective from this issue, both magazines will offer the same technical c...
Claudio Lassala, October 1, 2002
My users can't see this stuff, but I can, and I love it As usually happens with every new version of Visual FoxPro, we have plenty of new "non-visual" enhancements. These enhancements are not noticed by o...
Claudio Lassala, July 1, 2002
Enhancing the Data-entry form class a little bit In the previous articles of this series, we learned how we could create a simple Data-entry form class, which we can re-use very easily in all of our data-entry forms. Now, in this article, we'll enhance a little bit our class. The "Salv...
Claudio Lassala, March 1, 2002
Following our course (which began on the 8th Issue of RapoZine), we will learn to create Forms. Visual FoxPro give us tools that make Form creation very simple. Let's start. Creating an "About..." Form. A very common Form, and also one of the simplest to create, is an "Abo...
Claudio Lassala, February 1, 2002
FoxPro Report Designer has always been a great tool, very easy and efficient. However, developers must very often design reports in a format that can be easily viewed by third parties, specially the ones that must be visualized from a non-VFP application. The only native format the rep...
Claudio Lassala, March 1, 2002
In the last month, we received dozens of emails from satisfied persons in regards for our initiative of opening the magazine and the Universal Thread in general for additional communities such as the Portuguese and Spanish communities. Regulars members of the Universal Thread, new members, Microsoft...