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

VFP 8: The non-visual aspects that we always dreamed of
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...

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 our end-users, but we really enjoy them: new classes, commands, functions, and any thing else that can make our life as developer easier, more productive, and that can give us several new ideas to work with.

In this article, I'll show you this type of new features in VFP 8 Beta. Of course, it's impossible to show you all of them on a single article. So I chose those I loved the most, and that I think you'll enjoy too. Let's go (are you ready to go?! )!

The New CursorAdapter class

The CursorAdapter new class gives us new opportunities to extend our data cursors, it helps us to work with local and remote data, from Native VFP data to ODBC, ADO and XML.

Its use is pretty straight-forward. Take a look at the next sample. We start by defining a new class, based on the CursorAdapter baseclass:

Define CLASS CustomersData as CursorAdapter 

     *-- Let´s define the DataSourceType as "Native" (VFP data)
     DataSourceType="Native"

     *-- Let´s define the name of the alias that should be created.
     Alias="curCustomers"

     *-- Let´s define the command that will generate the data to fill the cursor.
     SelectCmd = "select * from Customer"

     Procedure Init
          *-- Once the object is created, let´s fill the cursor.
          this.CursorFill()
     EndProc 
EndDefine 

The CursorFill() method is part of the PEMs of this new baseclass. Everytime it´s called, it will use the SelectCmd property to get the data and fill the cursor. We could use the class above like this:

oCustomersData = CreateObject("CustomersData")

Browse

Remember: once the object is created, there will be a curCustomers cursor opened at the browse.

Do you want a little more fun? Well, let´s take a look at this sample:

Define CLASS CustomersData as CursorAdapter

     *-- Now, we want to define the type of the data source as ODBC
     DataSourceType="ODBC"

     Alias="curCustomers"
     *-- We can define a "Cursor Schema"
     CursorSchema = ;
             "customerid c(5),companyname c(30),contactname c(30),"+;
             " contacttitle c(30), address c(30), city c(30), country"+;
             " c(30)"

     SelectCmd = ;
             "select customerid, companyname, contactname, "+;
             " contacttitle, address, city, country from Customers"

     *-- Remember the CursorSetProp() function?  :)
     Tables = "Customers"
     KeyFieldList = "customerid"
     UpdatableFieldList = "companyname"
     UpdateNameList = "companyname customers.companyname"

     Procedure Init
      
          *-- Add a property at run-time that holds a Connection Handle.
          This.AddProperty('Connection',;		
                       SQLSTRINGCONNECT(;
                         "Driver=SQL Server;Server=(local);"+;
                         "Description=Northwind, Int Security;"+;
                         "DATABASE=Northwind;uid=sa;pwd=;"))

          *-- The data source is our Connection Handle
          This.DataSource = This.Connection

          This.CursorFill()

     EndProc  	
EndDefine 

As I pointed out by a comment in the code above, we have some properties that will turn the cursor into an "updatable cursor", just as we are used to doing with the CursorSetProp() function.

Can you see the beauty of this? We have just created a class that, when we use it, it will bring us an updatable cursor filled with data. The "objectified" way to do this is really cool.

VFP ads advertise: "Can you feel the XML"? Take a look at this one:

Define CLASS WishListData as CursorAdapter

     *-- Time to set the source type to "XML"!
     DataSourceType="XML"

     Alias="curWishList"
    
     Procedure Init
          *-- Set the SelectCmd property to the method
          *-- that will return some XML data.
          This.SelectCmd = "this.GetXml()"

          *-- Fill the cursor.
          This.CursorFill()
     EndProc 
     Procedure GetXml
        *-- Access our beloved UT´s Web Service over ther Internet
        *-- and get some data, Sir!
        loUniversalThread=Createobject("mssoap.soapclient30")
        loUniversalThread.mssoapinit(;
            "http://www.universalthread.com/WebService/VisualFoxPro.wsdl")

        lcUsername='MyUser'
        lcPassword='MyPassword'

        loUniversalThread.Login(lcUsername,lcPassword)
        lcXML=loUniversalThread.GetWishList(DATE()-20)
		
        RETURN lcXML
     EndProc  
EndDefine 

Just think about it: We told to the CursorAdapter that we´ll work with "XML". We set the SelectCmd property to a Method on the class that will return a XML string. On this method, we just get the XML from any place we want, and the Adapter will take care of converting the data to a VFP cursor. Isn´t that pretty cool?

Do you remember wishing for a better integration with ADO? Well, now we have it. Take a look at this:

Define CLASS CustomersData as xCursor
     Procedure Init

          *-- Our Source Type now is "ADO"
          This.DataSourceType = "ADO"

          *-- We´ll add a property to store an ADO Connection object.
          This.AddProperty('oConn',;
                    NewObject("ADODB.Connection"))
		
          *-- And another property to store an ADO RecordSet object.
          This.AddProperty('oRS',;
                    NewObject("ADODB.Recordset"))
		
          *-- We´ll set the Connection String for the Connection object,
          *-- as we´re quite used to.
          This.oConn.ConnectionString = ;
                    "Provider=SQLOLEDB.1;"+;
                    "Initial Catalog=Northwind; Data Source=lassalanotebook;uid=sa;pwd=;"

          *-- ...and open the connection.
          This.oConn.Open()

          *-- Let´s set this newly created connection as the Active Connection
          *-- for our RecordSet object.
          This.oRS.ActiveConnection = This.oConn

          *-- ...and set the RecordSet as the data source for this Cursor Adapter.		
          This.DataSource = This.oRS
          *-- This is our command to bring our data.
          This.SelectCmd = ;
                   "select customerid, companyname, contactname, "+;
                   "contacttitle, address, city, country from customers"	

          *-- And fill up our Cursor with data, big boy!
          This.CursorFill()
     EndProc
EndDefine

Can you see how easy it is? Just by doing this we have a VFP Cursor filled with data that comes from an ADO RecordSet.

Well, I think you still want more fun. So, let´s keep talking? We always dreamed of an easy way to bind ADO RecordSets to our forms, and also keep using the RAD features not just with native tables, but with local and remote views.

What about using the IntelliDrop (drag from the DataEnvironment into a Form in the Form Designer) to bind controls to data that comes from RecordSets, XML, any ODBC data source, or something like that? Well, now we have this ability.

Let´s suppose I have this form, with a simple grid on it. Now, what I want is to access some data on my SQL Server using ADO, and show this data on my native VFP grid. Well, by right-clicking on the DataEnvironment, we have a new option, called "Add CursorAdapter". Taking a look on the properties of this thing, you´ll see some nice properties, like "KeyFieldList", "UpdatableFieldList", "SendUpdates", and that sort of thing.

A cool property that we must use in order to better benefit from the IntelliDrop feature is the CursorSchema property. On this property we must input the "schema" of the cursor (aka, the structure of the cursor). By defining this schema, the IntelliDrop will work just like when we drag a field from a table and drop it into the Form.

I´ll name this control as "CursorAdapterCustomers", and set the Alias property as "Customers".

Finally, I´ll fill the Init method of the form with the following code:

*-- Let´s point out a reference to our CursorAdapter.
With Thisform.DataEnvironment.CursorAdapterCustomers

     *-- The following lines you already know from some previous samples.
     .DataSourceType="ADO"

      .SelectCmd = ;
          "select customerid, companyname, contactname, "+;
          " contacttitle, address, city, country from Customers"

     .AddProperty('oConn',null)
     .AddProperty('oRS',null)
     .oRS = CreateObject("ADODB.RecordSet")
		
     .oConn = CreateObject("ADODB.Connection")
     .oConn.Open("Driver=SQL Server;Server=lassalanotebook;"+;
                 "Description=Northwind, Int Security;"+;
                 "DATABASE=Northwind;uid=sa;pwd=;")
	
     .oRS.ActiveConnection = .oConn
	
     .Datasource = .oRS

     .CursorFill()
Endwith

*-- And now, we can define our cursor as the source for our grid.
This.grdCustomers.RecordSource = "Customers"

When we run the form, we have our data on the grid.

The new AddProperty() and RemoveProperty() functions

Everybody who uses objects created with the SCATTER NAME command has always wished for some way to add properties on-the-fly to those objects. As a workaround, we ended up using either the AddProp5.fll founded on the web, or creating manually the object based on a "light" class (like Relation baseclass, for instance) and adding the properties based on the fields of the cursor.

We don't need to do that anymore: Now we have a new function called AddProperty, that we can use to add properties on-the-fly for "scattered" objects, or objects based on the new Empty Class (see more about that class in this same article), as those objects don't have a native AddProperty() method.

Take a look at the sample below:

*-- First, let's bring some data...
Select Company_Name, Contact_Name From (_samples+"\tastrade\data\customer") ;
    into Cursor curCustomer

*-- Then, let's created the "scattered" object.
Scatter name loCustomer
*-- And finally, let's add a new property called MyNewProp to the object, 
*-- initializing it with the value "MyValue".
AddProperty(loCustomer, "MyNewProp", "MyValue")

*-- We can query our brand new property
? loCustomer.MyNewProp

Likewise, we can now remove properties on-the-fly, using a new function called RemoveProperty, just like this:

RemoveProperty(loCustomer, "Contact_Name")

The new Empty class

Until VFP 7, everytime we needed a "light-weight" class (a class that's fast to initiate and destroy), we ended up using the Relation baseclass; that's kind of strange, as the main purpose of that baseclass is establish a relation between two tables on a DataEnvironment. In VFP 8 we have the Empty class.

The Empty class is a class with no PEMs (Properties, Events or Methods) that can't be subclassed nor defined in a PRG or VCX file. This class will be used when we need to create objects (like "scattered" objects) and add properties to them at runtime, or when we need to store any sort of data of an "objectified" fashion at runtime.

For example: unfortunately, there isn't a localized version of VFP in Portuguese. So, it's useful for us to have in our apps an object which stores Portuguese stuff for Months and Days-of-Week. Let's see how we could accomplish that by using the Empty class:

*-- First I'll define a "Utils" class, 
*-- based on "Session" baseclass, for example...
Define Class Utils As Session

     *-- Now the method that will "Bring" something useful for us.
     Procedure BringUtils
		
          *-- Let's create our "Empty" object.
          Local loFoo
          loFoo = Createobject("Empty")

          *-- Time to use the new AddProperty() function.

          *-- First we add a property to store the Months...
          AddProperty(loFoo, "Months(12)")

          *-- and second a property to store the days of the week.
          AddProperty(loFoo, "DaysOfWeek(7)")

          *-- Let's store the data.
 	  With loFoo
              *-- The Months in Portuguese
              .Months(1)  = "Janeiro"
              .Months(2)  = "Fevereiro"
              .Months(3)  = "Março"
              .Months(4)  = "Abril"
              .Months(5)  = "Maio"
              .Months(6)  = "Junho"
              .Months(7)  = "Julho"
              .Months(8)  = "Agosto"
              .Months(9)  = "Setembro"
              .Months(10) = "Outubro"
              .Months(11) = "Novembro"
              .Months(12) = "Dezembro"

              *-- The days of the week in Portuguese
              .DaysOfWeek(1) = "Domingo"
              .DaysOfWeek(2) = "Segunda-feira"
              .DaysOfWeek(3) = "Terça-feira"
              .DaysOfWeek(4) = "Quarta-feira"
              .DaysOfWeek(5) = "Quinta-feira"
              .DaysOfWeek(6) = "Sexta-feira"
              .DaysOfWeek(7) = "Sábado"
          Endwith

          *-- Finally, we return our useful object.
          Return loFoo
     EndProc 
EndDefine 

Ok. Now, we could use our Utils class like this:

*-- Instantiate our "Utils" class.
oUtils = Createobject("Utils")

*-- Invoke the BringUtils() method.
*-- Remember that it'll return that object created based on "Empty".
oUtils = oUtils.BringUtils()

*-- Now we can print the current Month's name in Portuguese...
? oUtils.Months(Month(Date()))

*-- ...or the current day of the week date in Portuguese.
? oUtils.DaysOfWeek(Dow(Date()))

The Scatter command was enhanced

Now we can update an existent object using the Additive keyword of the Scatter command. See how useful it is:

*-- Let's create a simple Business object for "Customer"
Define Class Customer As Session

     *-- Some properties...
     Company_Name = ""
     Contact_Name = ""

     *-- A simple method to play with the data.
     Procedure GiveMeInfo
          Return Alltrim(This.Company_Name) + " - " + This.Contact_Name
     Endproc

Enddefine

And now, take a look at this:

*-- We instantiate our Customer object.
oCustomer = CreateObject("Customer")
*-- We get some data... just for testing...
Select Company_Name, Contact_Name From (_samples+"\tastrade\data\customer") into cursor curCustomer

*-- We can now "scatter" data to the BizObject that´s already created.
Scatter Name oCustomer additive

*-- Invoke our GiveMeInfo() method.
MessageBox(oCustomer.GiveMeInfo())

I think that's quite useful, don't you think?

Another nice new thing related to "scattered" objects is the fact that the INSERT-SQL statement now accepts data from an object. Therefore we could do something like this:

*-- Let's create a simple Test cursor.
Create Cursor Foo (Company_Name C(30), Contact_Name C(30))

*-- Now, supposing that we have the object created on the last sample:
Insert into Foo from name oCustomer

This sort of cool new thing just let VFP be even more powerful to play with data, mixing the use of business objects with our always handy VFP cursors.

Event Binding for native VFP objects

With VFP 7, we were presented with the EventHandler() function, that we can use to bind COM Objects events to a VFP object. Now we can do the same but for binding native VFP object events, using a brand new function called BindEvent().

Let's think...: we have a business object which contains a Data object, and we want to have any changes to that object monitored by another object. Given this scenario, let's create the business class first:

*-- Our BizObj.
Define Class Customer As Session

     *-- A property for a Data object.
     oData = Null

     Procedure Init

          *-- Bring any data from the table.
          Select * From (_samples+"\tastrade\data\customer") into Cursor curCustomer

          *-- Create the data object.
          Scatter Name This.oData Memo

     EndProc 
EndDefine 

Now we'll create our "Event Handler" class.

*-- We define a class.
Define Class FooHandler As Session

     *-- We define a method that will handle 
     *-- the "event" of a change for the "Company_Name" field.
     *-- ...of course, on a real scenario we'd have a much more interesting thing here...
     Procedure CompanyNameHandling
         Messagebox("You´re changing the Company´s Name")
     EndProc 

EndDefine 

And finally, let's use those classes:

*-- First, let's create our BizObj.
oCustomer = CreateObject("Customer")

*-- Now, our Event Handle's Object
oFooHandler = CreateObject("FooHandler")

*-- Finally, let's use the function Bindevent, in order to actually bind things here...
Bindevent(oCustomer.oData, "Company_Name", oFooHandler, "CompanyNameHandling")

*-- ...and it's time to try to change the value of "Company_name"...
oCustomer.oData.Company_Name = "Anything..."

As you can see, the BindEvent() function receives as parameters the object that will fire the event (in this case the oCustomer.oData object), the property that will fire the event (in this case the Company_Name property), the object that will handle the event (in this case, our oFooHandler object), and finally, the method that will handle the event (in this case, the CompanyNameHandling() Method). Anytime that the Company_Name is changed, a messagebox will be displayed (as we have defined on the class).

Would you like to see a more "visual" example? If so, here it goes: let's say you have a form and you want it to always be resized when the _Screen is resized. We could do that like this:

*-- Let's create a simple form.
Public oFooForm
oFooForm = Createobject("FooForm")
oFooForm.Visible = .T.

*-- Let's bind things here...
Bindevent(_Screen, "Resize", oFooForm, "Resize")

*-- Take a look at our simple form.
Define Class FooForm As Form

     Procedure Resize
          This.Top    = _Screen.Top + 5
          This.Left   = _Screen.Left + 5
          This.Width  = _Screen.Width - 100
          This.Height = _Screen.Height - 100
     Endproc

Enddefine

In the code above, we have defined that whenever the Resize event of the _Screen object got fired, we want that the Resize method of the oFooForm object to also be fired. As you may have noticed, the _Screen object is passive here, as it will never know that there's something "following its steps".

I know you like plenty of samples, so here goes another one, that will make you understand this even better this BindEvent() function.

Do you remember everytime you have needed to run some code whenever a textbox on a grid was clicked, no matter on which column? Until now, you did that by typing the code on every textbox's Click() method (urgh!), or by defining a textbox class which contains the desired code and then switching the textboxes on the grid with this class (and you don't like this approach that much, because you'll never use this class again in any other place...). Well, with the BindEvent() function, you'll now do something like this:

Let's explain: in the Init() method of the form I did the event binding. It was just a matter of iterating through all the Columns of the grid, and binding the RightClick() event of each textbox (the Control(2) on the grid), to the BringSomeInfo() method defined on the form. Isn't that pretty cool? Repeat after me: VFP Rocks!

The new Collection class

You don't need to create your own Collection classes anymore: now we have a native Collection class! Do you want a pratical sample for it? Here it goes: let's suppose that I have the need on my app to cascade all the forms that are currently opened. See how simple is to implement such a thing using the Collection class:

*-- Define a simple "FormsManager" class.
Define Class FormsManager As Session

     *-- Define a property that will host a Collection.
     oFormsCollection = Null

     Procedure Init
          *-- Instantiate the Collection class.
          This.oFormsCollection = Createobject("Collection")
     Endproc
     *-- Define a method that will add references for the Forms to the Collection.
     Procedure AddForm(loForm)

          *-- We can use the Add() method of the Collection object,
          *-- in order to add items to the collection.
          *-- In this sample, we´re determining the Form´s Caption
          *-- as the Key for the Item on the Collection.
          This.oFormsCollection.Add(loForm, loForm.Caption)

          *-- Bind Event to the QueryUnload of the Form,
          *-- this way the reference to the form is cleared by the
          *-- ReleaseForm method of this class.
          Bindevent(loForm, "QueryUnload", This, "ReleaseForm", 2)
     Endproc

     *-- Method to release the reference to the form that's being destroyed.
     Procedure ReleaseForm
          This.oFormsCollection.Remove(_Screen.ActiveForm.Caption)
     EndProc 

     *-- A simple method to "cascade" the forms.
     Procedure CascadeForms

         Local lnTop, lnLeft
         lnTop  = 5
         lnLeft = 5

         *-- We can use a ForEach structure to iterate
         *-- through all the items in the collection.
         For Each loForm In This.oFormsCollection
            loForm.Top  = lnTop
            loForm.Left = lnLeft
            loForm.Visible = .T.

            lnTop  = lnTop + 20
            lnLeft = lnLeft + 20
            Next
         Endproc
Enddefine

The points that you should notice:

  1. We add items to the collection by the use of the Add() method of the Collection class, and the Remove() method to remove the item.
  2. The second parameter of the Add() method determines the "key" to access the item.
  3. We can iterate through all the items of a collection by using a For Each structure.

Now, we can use our "Form Manager" like this:

*-- Declare some variables...
Public oForm1, oForm2, oForm3, oFM

*-- Instantiate some forms, and give them captions...
oForm1 = Createobject("Form")
oForm1.Caption = "Customers"
oForm2 = Createobject("Form")
oForm2.Caption = "Orders"

oForm3 = Createobject("Form")
oForm3.Caption = "Products"

*-- Instantiate our "Forms Manager"
oFM = Createobject("FormsManager")

*-- Add the forms to our "Form Manager"
oFM.AddForm(oForm1)
oFM.AddForm(oForm2)
oFM.AddForm(oForm3)

*-- Ask the "Form Manager" to "Cascade" the Forms.
oFM.CascadeForms()

The code above must produce this result:

Think: doing it like this, you have total control over your forms, and have an easy way to get a reference to any of them. And the Collection class provide us with some other cool features, like the ones below:

*-- We can query the Count property of the Collection object,
*-- and discover how many items it contains.
? oFM.oFormsCollection.Count

*-- We can access a single item on the collection by its Index...
*-- ...for example, let's see the value of the Top property of the 
*-- form referenced as the second item within the collection.
? oFM.oFormsCollection.Item(2).Top

*-- ...or by its "key"
? oFM.oFormsCollection.Item("Orders").Top

Another cool enhancement for the Insert-SQL

Aside from the previously mentioned new feature of Inserting new records from an object, we are now able to insert from a Select-SQL result. Look:

*-- Let's create a simple cursor...
Create Cursor MyCustomers (cName C(30))

*-- ...and insert rows returned from a Select-SQL statement.
Insert into MyCustomers ;
     Select Company_Name ;
        from (_Samples+"\Tastrade\Data\Customer") ;
         where country = "Brazil"

Enhancements to Textmerge

I'm the one who always enjoy using Textmerge. And I love this new enhancement I am going to tell you about. Back in the July issue of UTMag/RapoZine, in the Shortcuts column, I told you about how we can use the Textemerge to build SQL statements in a cleaner way, instead of those awful string concatenations. Something like this:

Local lcSQL
Text to lcSQL TextMerge NoShow
   Select Field1, Field2, Field3, Field4 
     From Table 
     Inner Join AnotherTable 
       On Table.SomeField = AnotherTable.SomeField 
     Inner Join FooTable 
       On Table.Somefield = FooTable.SomeField 
     Where Field1 = << lcSomeVar >>
       And Field2 = << lcAnotherVar >>
     Group by Field3, Field2 
     Order by Field1 
EndText

With that we had one drawback: we needed to remove white spaces with something like this:

StrTran(lcSQL, Chr(13)+Chr(10), " ")

Well, we don't need that anymore. We can just change the Text instruction to something like this:

Text to lcSQL TEXTMERGE NOSHOW PRETEXT 1+2

With the new PRETEXT keyword we are able to remove white-spaces and tabs (flags 1+2) at the end of each line. This is not just useful for SQL statements, but for XML documents as well.

Conclusion

Ok, that´s it! As I told you at the begining of this article, VFP 8 brings to us a lot of cool new features, and with this article I just showed you some cool new "non-visual" features. I hope you liked it. Take a look on the other articles in this issue related to this exciting Beta of VFP 8!

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, 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, 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...
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...