4.3.16 System utilities

System utilities

Until recently, Visual FoxPro programmers pretty much lived in their own little world. But this is changing. Systems become more integrated and applications must communicate with the operating system and other applications. Typically this isn't trivial, which is why most Visual FoxPro developers tried to stay away from this kind of programming. Using the classes introduced in this category, this is no longer a valid statement. System programming just became very easy. Try it out one day!

Application Registry

Class

Filereg

Base class

Custom

Class library

Registry.vcx

Parent class

Registry

Sample

...\Samples\Vfp98\Solution\winapi\regfile.scx

Dependencies

Registry.h

The Application Registry object provides easy access to application-specific settings in the Windows registry. This class has three important methods: GetAppPath(), GetApplication(), and GetLatestVersion().

First of all, we have the GetAppPath() method. It retrieves the path of an application associated with a certain file extension. An example would be Microsoft Word as the application associated to the DOC extension. The GetAppPath() method requires four parameters. Two of them are passed by reference to be populated with the return values. Here's an example:

LOCAL loReg, lcKey, lcApplication, lnErrorCode
loReg = NewObject("filereg","registry.vcx")
lnErrorCode = loReg.GetAppPath("DOC",@lcKey,@lcAppliaction,.F.)
IF lnErrorCode = 0
? lcKey
? lcApplication
ENDIF

This example retrieves the registry key and the application path for the application associated with the DOC extension. The return value of the GetAppPath() method is an error code. If it is 0, everything went fine. Otherwise, the returned error code is a Windows API error code.

The example above prints the following two lines when I run it on my computer with the current configuration:

Word.Document.8

"C:\Program Files\Microsoft Office\Office\Winword.exe" /n

The first line is the registry key value. One could use this value to instantiate the application as a server. The second line tells how to start the server as a regular application. As you can see, I pass .F. as the fourth parameter. This specifies that I don't want to see the application path as the COM server uses it. In other words, this is the path to the stand-alone executable. If I wanted to see the path to the EXE used by the server version, I could pass a .T. as the fourth parameter, which would return the following path:

C:\PROGRA~1\MICROS~1\OFFICE\Winword.exe

As you can see, the result is very similar (and possibly even confusing in this example), but I can assure you that the object actually reads two entirely different registration keys. On some occasions, the two values can be totally different, especially in scenarios where the server features are provided by a different application than the stand-alone features.

The second interesting method of the Application Registry object is GetApplication(). In fact, we've already seen how this method works, because it is utilized by the GetAppPath() method. It retrieves the application path according to a registry key. Here's an example:

LOCAL loReg, lcApplication, lnErrorCode
loReg = NewObject("filereg","registry.vcx")
lnErrorCode = loReg.GetApplication("Word.Document.8",@lcAppliaction,.F.)
IF lnErrorCode = 0
? lcApplication
ENDIF

Again, the return value is placed in a parameter we pass by reference. This time, parameter 3 is used to specify whether we want the stand-alone or the server path. As for the GetAppPath() method, the return value is a Windows API error code.

The third method of interest is GetLatestVersion(). It is very handy when you need to figure out which version of an application is installed on your system. For instance, if I know I want to use a server class called "Word.Document" I can figure out the current version of it like so:

LOCAL loReg, lcKey, lcApplication, lnErrorCode
loReg = NewObject("filereg","registry.vcx")
lnErrorCode = loReg.GetLatestVersion("Word.Document",@lcKey,@lcAppliaction,.F.)
IF lnErrorCode = 0
? lcKey
? lcApplication
ENDIF

This example would produce the following output:

Word.Document.8

"C:\Program Files\Microsoft Office\Office\Winword.exe" /n

This is very similar to the result of the GetAppPath() example. The main difference is that we didn't start out with a certain file extension, but with a specific class name.

INI Access

Class

Oldinireg

Base class

Custom

Class library

Registry.vcx

Parent class

Registry

Sample

None

Dependencies

Registry.h

INI files are somewhat out of fashion. Too many people preach about using the Windows registry instead (and I have to admit I'm one of them). However, there are a couple of scenarios where you still have to use old-fashioned INI files. This might be the case when you have to modify older (or even newer) applications. Let's just assume we need to maintain multiple INI files that are virtually identical. This is hard to do using the registry. The INI Access foundation class makes dealing with INI files very easy.

The INI Access class has two important methods: GetINIEntry() and WriteINIEntry(). Both methods require four parameters: the value (passed by reference to the GetINIEntry() method), the section (all INI files are organized in sections), the actual entry name, and the name of the INI file. Here's one section of the Win.ini file that I found in my Windows directory:

[Devices]

Symantec WinFax Starter Edition=OLFAXDRV,LPT1:

EPSON Stylus 400=EPIDRV10,\\EPS-NT\Epson400

 

Obviously this is a very small section of a huge INI file. Here's how I can read a specific setting:

LOCAL lcValue, loINI, lnError

loINI = NewObject("oldinireg","registry.vcx")

lnError = loINI.GetINIEntry(@lcValue,"Devices","EPSON Stylus 400","C:\Windows\win.ini")
IF lnError = 0

? lcValue

ENDIF

Again, the method returns a Windows API error code. The actual value is returned in the first parameter, which is passed by reference.

Writing a value to an INI file works in a similar fashion. Here's an example:

LOCAL loINI, lnError

loINI = NewObject("oldinireg","registry.vcx")

lnError = loINI.WriteINIEntry("EPIDRV10,\\NTS\Epson400",;

"Devices","EPSON Stylus 400","C:\Windows\win.ini")
IF lnError = 0

MessageBox("Value set successfully.")

ENDIF

ODBC Registry

Class

Odbcreg

Base class

Custom

Class library

Registry.vcx

Parent class

Registry

Sample

...\Samples\Vfp98\Solution\winapi\odbcreg.scx

Dependencies

Registry.h

When dealing with ODBC data sources, it is helpful to know what's available. The ODBC Registry object allows you to query all available ODBC data sources. Once you have those data sources, you can query all the options for each individual source.

Let's start out with the GetODBCDrvrs() method, which queries all available ODBC data sources and places them in an array that's passed by reference as the first parameter. This should be done like so:

LOCAL laDrivers(1), loODBCReg, lnCounter
loODBCReg = NewObject("odbcreg","registry.vcx")

loODBCReg.GetODBCDrvrs(@laDrivers,.F.)
FOR lnCounter = 1 TO Alen(laDrivers,1)
? laDrivers(lnCounter)
ENDFOR

There are two different arrays this method can create, depending on the second parameter you pass. The version above creates a one-dimensional array with the names of all drivers (parameter 2 is .F.). Here's an example for the contents of this array:

Microsoft Access Driver (*.mdb)

Microsoft dBase Driver (*.dbf)

Microsoft Excel Driver (*.xls)

Microsoft FoxPro Driver (*.dbf)

Microsoft Text Driver (*.txt; *.csv)

SQL Server

Microsoft Visual FoxPro Driver

Microsoft ODBC for Oracle

The second version creates a two-dimensional array that lists the driver names as well as the data source name. Here's an example (the columns are separated by commas):

MS Access 97 Database, Microsoft Access Driver (*.mdb)

dBASE Files, Microsoft dBase Driver (*.dbf)

Excel Files, Microsoft Excel Driver (*.xls)

FoxPro Files, Microsoft FoxPro Driver (*.dbf)

Text Files, Microsoft Text Driver (*.txt; *.csv)

Visual FoxPro Tables, Microsoft Visual FoxPro Driver

Visual FoxPro Database, Microsoft Visual FoxPro Driver

VLPSQL, SQL Server

Once you retrieve driver names, you can enumerate the driver options using the EnumODBCDrvrs() method. This method, once again, populates an array that's passed by reference. The array is two-dimensional. The first column represents the option setting name, while the second column holds the current value. The number of the retrieved options as well as the individual options vary from driver to driver. Here's an example of using this method:

LOCAL laOptions(1), loODBCReg, lnCounter

loODBCReg = NewObject("odbcreg","registry.vcx")
loODBCReg.EnumODBCDrvrs(@laOptions," Microsoft Visual FoxPro Driver")
FOR lnCounter = 1 TO Alen(laOptions,1)
? laOptions(lnCounter,1) + ", " + laOptions(lnCounter,2)
ENDFOR

Yet another method is similar to the one we've just discussed: EnumODBCData(). This method creates the same array as the EnumODBCDrvrs() method, with the difference that you have to specify a data name instead of a driver name. To me, this seems to be somewhat easier than dealing with the driver name because some of those are quite cryptic. The method must be called like so:

loODBCReg.EnumODBCData(@laOptions," Visual FoxPro Database")

Registry Access

Class

Registry

Base class

Custom

Class library

Registry.vcx

Parent class

Custom (base class)

Sample

...\Samples\Vfp98\Solution\winapi\regfox.scx

Dependencies

Registry.h

The Registry Access class provides access to the Windows registry in general (who would have guessed it?). Let's go through its methods one by one.

One of the first things I ever did with the registry was reading key values. This can be accomplished using the GetRegKey() method like so:

LOCAL loRegistry, lcValue, lnError

loRegistry = NewObject("registry","registry.vcx")

lnError = loRegistry.GetRegKey("ResWidth",@lcValue,;

"Software\Microsoft\VisualFoxPro\6.0\Options",;

HKEY_CURRENT_USER)

IF lnError = 0
? lcValue
ENDIF

The first parameter identifies the value we want to read, in this case "ResWidth". Parameter 2 is passed by reference and will be populated with the key value we are asking for. Parameter 3 is the path to our key and parameter 4 is the root key. In my example I use "HKEY_LOCAL_USER", which is a predefined value (defined in Registry.h). The method returns an error code. Zero (0) means that everything went fine, and all other values are Windows API error codes.

Now that we know how to read values from the registry, we also want to be able to change them and write new values to the registry. This can be accomplished using the SetRegKey() method. The parameters passed to this method are identical to the ones passed to the GetRegKey() method, with the obvious exception that the value is the value to be set and not the value to be retrieved. For this reason, there is no need to pass parameter 2 by reference. Here's an example:

lnError = loRegistry.SetRegKey("ResWidth","1600",;

"Software\Microsoft\VisualFoxPro\6.0\Options",;

HKEY_CURRENT_USER)

Note that the value I set is a character value even though it seems that the "ResWidth" setting would be numeric. However, the Registry object can handle only string values.

Creating new values is easy. You simple use the SetRegKey() method and specify a value name that doesn't yet exist. The Registry Access object then automatically creates that new value for us. If you just tried that and now have a registry value you didn't really want, you can delete it using the DeleteKeyValue() method like so:

lnError = loRegistry.DeleteKeyValue("MyValue",;

"Software\Microsoft\VisualFoxPro\6.0\Options",;

HKEY_CURRENT_USER)

The methods I described so far are usually sufficient to handle the registry. However, there is more to come. The EnumOptions() method allows you to enumerate all the values and subkeys located under a certain key. The method takes four parameters.

 

Here's an example:

LOCAL laOptions(1)
lnError = loRegistry.DeleteKeyValue(@laOptions,;

"Software\Microsoft\VisualFoxPro\6.0\Options",;

HKEY_CURRENT_USER,.F.)

Parameter 4 specifies whether you want to query all the options (.F.) or all the subkeys (.T.). In the first scenario, a two-dimensional array is created that holds all the options (column 1) and all the values (column 2). If you're looking for all the subkeys, the resulting array will be one-dimensional, holding simply the key names.

Shell Execute

Class

_shellexecute

Base class

Custom

Class library

_environ.vcx

Parent class

_custom

Sample

...\Samples\Vfp98\Solution\ole\buttons.scx

Dependencies

_base.vcx

Often the programmer has to manage and handle files that don't belong to his application Word documents, for instance. Wouldn't it be nice if you could simply open the application associated with this document to edit the actual document? Well, with this class you can.

The Shell Execute class has only one method and it's surprisingly simple to use. In most cases you have to pass only a single parameter, which is the name of the document you want the user to edit. This can be done like so:

oShellExecute = NewObject("_shellexecute","_environ.vcx")
oShellExecute.ShellExecute("MyDocument.doc")

The ShellExecute() method returns an error code that takes a while to get used to. Codes higher than 32 tell you that everything worked fine. Codes below 32 indicate an error (the documentation lists all the possible error codes).

There are two additional parameters you can pass to the ShellExecute() method: Parameter 2 specifies the default path the application will start in. Parameter 3 allows you to specify additional operations. Unfortunately, this parameter is virtually undocumented and I haven't yet encountered a use for it.



Advanced Object Oriented Programming with Visual FoxPro 6. 0
Advanced Object Oriented Programming with Visual FoxPro 6.0
ISBN: 0965509389
EAN: 2147483647
Year: 1998
Pages: 113
Authors: Markus Egger

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net