Latest Articles related to all categories. Microsoft, Twitter, Xbox, Autos and much more

Full width home advertisement

Post Page Advertisement [Top]

This section presents examples of using selected foundation classes in a VFP app. The classes
chosen are intended to be a representative sample, but are not exhaustive by any means.
Registry Access Foundation Class
The registry foundation class is probably the one I use most often. It is located in the FFC class
library named registry.vcx. Because its name does not begin with an underscore, you can tell right
away that the registry class is not derived from the FFC base classes in _base.vcx. In fact, the
registry class is sub-classed from the VFP custom base class.
The registry foundation class methods are mostly wrappers around the Windows API calls needed
to read and write the Windows registry. You could write your own code to call the Windows API
calls directly, but using the registry foundation class enables you to access the Windows registry
without having to be concerned about the underlying plumbing of the API.
Registry terminology
Before jumping in to a discussion of the FFC registry class methods, it might be helpful to review
the organization of the Windows registry and the terminology used to describe it.
The structure of the registry is conceptually similar to the structure of folders and files on a hard
drive. The contents of a hard drive are organized into a hierarchy of folders and subfolders that
contain one or more files. The contents of the registry are organized into a hierarchy of keys and
subkeys that contain one or more values.

On a hard drive, the hierarchy of specific folders and subfolders that identify the location of a file
is referred to as the path. In the registry, the hierarchy of specific keys and subkeys that identify
the location of a value are referred to simply as the key. In both case, the reference can be written
using the familiar syntax of a series of names separated by backslashes.
There are five root keys in the Windows registry. As an application software developer, you
typically work with the HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE root keys,
which are abbreviated HKCU and HKLM respectively. Application-specific settings are typically
written to an application-specific key under HKCU\Software.


The analogy to files on a hard drive may become a bit more difficult to understand when it comes
to the values in a registry key. This may be especially true for Visual FoxPro developers, to whom
the word value generally refers to the contents of a memory variable or a property on an object.
When talking about the registry, however, the word value corresponds to the concept of a file on
disk. A registry value has three attributes: the value name, the value type, and the value data. If
you think of a value name as being like a file name, then the value type corresponds to the type of
file (file extension) and the value data corresponds to the contents of the file.
Registry value data can one of several types. The most common type is a string, which is referred
to as type REG_SZ. The SZ stands for “string zero”, meaning a null-terminated string. Unlike
folders on disk, which do not have to contain any files, keys in the registry always have at least
one value called the default value. The default value has value type REG_SZ and its value data is
generally null, which shows up as (value not set) in the Registry Editor.
Working with the registry class
To work with the registry foundation class, first create an instance of it.
loRegistry = NEWOBJECT( "registry", "registry.vcx")
If you’re doing this in a program, it's a good idea to include the registry.h header file, which
defines several constants you can use in your code. For the sake of readability, the examples that
follow sometimes use defined constants from registry.h, such as HKEY_CURRENT_USER, even though
the sample code is not part of a complete program. If you want to run the sample code from the
command line, replace the defined constant with its value from registry.h.
The examples in this section are based on the registry entries for a hypothetical application named
myVFPApp. Following the recommended key structure for application settings in the registry,
which includes the company name, application name, and version number, the entries for
myVFPApp v1.0 are located in the registry key HKCU\Software\ITA\myVFPApp\1.0. By my
choice as the developer, this key contains subkeys named Application Settings and User
Preferences, which in turn contain the values I want to store for this application.

image

Figure 7: The registry entries for myVFPApp v1.0 are stored in HKCU\Software\ITA\myVFPApp\1.0. The
values are in subkeys Application Settings and User Preferences.
As shown in Figure 7, the Application Settings key contains two values. The AppDir value stores
the location where the application is installed, and the DataDir value stores the location where the
application’s data is located.
The User Preferences key is not shown, but it also contains two values, AskOnExit and
PrintPreview. By design, the value data of each of these can be either Yes or No. The AskOnExit
value determines whether or not the application should ask the user “Are you sure?” when
terminating the app. The PrintPreview value determines whether the app displays reports in
preview mode or sends them directly to the printer.
Reading the registry
The IsKey( ) method queries the registry to see if a key exists. This method is one of the simplest
to use. It takes only two parameters, the name of the key, and the ID of the root key in which to
look. For example, the statement
?loRegistry.IsKey("Software\ITA\myVFPApp\1.0", HKEY_CURRENT_USER)
returns True if the registry key HKCU\Software\ITA\myVFPApp\1.0 exists, or False if it doesn’t.
The GetRegKey( ) method returns the setting (the value data) from a specified value name in a
specified key. The following example returns the setting of the AppDir value in the Application
Settings key.
* Read a registry key value using GetRegKey()
lcKey = "Software\ITA\myVFPApp\1.0\Application Settings"
lcValueName = "appdir"
lcValueData = ""
loRegistry.GetRegKey( lcValueName, @lcValueData, lcKey, HKEY_CURRENT_USER)
?lcValueData && Displays C:\Program Files\ITA\myVPFApp
Note that the return value is placed in lcValueData, which must be passed by reference. It is not
necessary to use variables for the other two parameters, but I chose to do so in order to make the
example more clear. The statement could have been written equally as well like this:
loRegistry.GetRegKey( “appdir”, @lcValueData, "Software\ITA\myVFPApp\1.0\Application Settings",
HKEY_CURRENT_USER)
If you look at the source code for the GetRegKey( ) method in the registry class, you find that it
is actually a wrapper for calls to two other methods in the same class, OpenKey( ) and
GetKeyValue( ). The OpenKey( ) method opens a registry key and sets the value of a class

property named nCurrentKey. The GetKeyValue( ) method relies on nCurrentKey having already
been set, and reads the value data from the specified value name in that key.
The advantage of using GetRegKey( ) is you can read the value in one statement, but you could
also use OpenKey( ) and GetKeyValue( ) directly if you want to.
* Read a registry key value using OpenKey() and GetKeyValue()
lcKey = "Software\ITA\myVFPApp\1.0\Application Settings"
loRegistry.OpenKey( lcKey, HKEY_CURRENT_USER, .F.)
lcValueName = "datadir"
lcValueData = ""
loRegistry.GetKeyValue( lcValueName, @lcValueData)
?lcValueData
Note that GetKeyValue( ) requires only two parameters because the key has already been opened.
Like GetRegKey( ), the variable for the return value (lcValueData) must be passed by reference.
The third parameter in the OpenKey( ) method determines whether or not the key should be
created if it doesn’t already exist.
The EnumKeys( ) method populates an array with the subkeys for a specified key. The following
code returns an array with two rows, one for each of the subkeys under
HKCU\Software\ITA\myVFPApp\1.0.
* Enumerate the subkeys for a key using OpenKey() and EnumKeys()
lcKey = "Software\ITA\myVFPApp\1.0"
loRegistry.OpenKey( lcKey, HKEY_CURRENT_USER, .F.)
loRegistry.EnumKeys( @laKeys)
DISPLAY MEMORY LIKE laKeys
The EnumKeyValues( ) method returns an array with the value names and value data for each of
the values with a specified key. The array is two-dimensional, where the first column in each row
is the value name and the second column is the value data. The following code reads and displays
the values in the HKCU\Software\ITA\myVFPApp\1.0\User Preferences key.
* Enumerate the values for a key using OpenKey() and EnumKeyValues()
lcKey = "Software\ITA\myVFPApp\1.0\User Preferences"
loRegistry.OpenKey( lcKey, HKEY_CURRENT_USER, .F.)
loRegistry.EnumKeyValues( @laValues)
FOR lni = 1 TO ALEN( laValues, 1)
? laValues[lni,1] + " = " + laValues[lni,2]
ENDFOR
The CloseKey( ) method closes a previously opened key and resets the value of the nCurrentKey
property to zero.
Writing to the registry
The SetRegKey( ) method enables you to write a value to a key, and optionally to create the key
if it does not already exist.
* Create a registry key using SetRegKey()
lcKey = "Software\ITA\myVFPApp\1.0\Application Settings"
lcValueName = "AppDir"
lcValueData = "C:\Program Files\ITA\myVFPApp"
loRegistry.SetRegKey( lcValueName, lcValueData, lcKey, HKEY_CURRENT_USER, .T.)

The fifth parameter passed to SetRegKey( ) determines whether or not the key should be created
if it doesn’t already exist. SetRegKey( ) returns zero if successful, otherwise an error number is
returned. Refer to registry.h for a list of the error numbers and their meanings.
Like GetRegKey( ), SetRegKey( ) is actually a wrapper around two other method in the registry
class. SetRegKey( ) calls OpenKey( ) to open the key, then calls SetKeyValue( ) to set the value.
As you’ve already guessed, you can call these two methods directly from you code if you want to.
* Create a registry key and value using OpenKey() and SetKeyValue()
lcKey = "Software\ITA\myVFPApp\1.0\Application Settings"
loRegistry.OpenKey( lcKey, HKEY_CURRENT_USER, .T.)
lcValueName = "DataDir"
lcValueData = "C:\Program Files\ITA\myVFPApp\Data"
loRegistry.SetKeyValue( lcValueName, lcValueData)
Like SetRegKey( ), SetKeyValue( ) returns zero if successful, otherwise it returns an error code.
Deleting registry keys and values
The registry foundation class provides DeleteKey( ) and DeleteKeyValue( ) methods to delete
keys and values from the registry. These methods operate much like the Get and Set methods
described above. I am not including any examples for the Delete methods because I don't want to
encourage you to run code that deletes anything from your own registry until you’re certain you
know what you’re doing. When you’re gained confidence using the registry class, you can write
your own code to create some sample registry entries and then delete them to see how these
methods work.
Working with INI files
Like Rodney Dangerfield, INI files don't get any respect these days, but in my opinion they are
still quite useful. INI files are easy to work with because they’re plain text files, and are therefore
well suited for storing application settings when there’s a chance you—or worse, an end user—
may need to manually change a setting in the field.
The registry foundation class library helps you work with INI files. It contains a subclass of the
registry class named oldinireg, which provides methods for reading and writing INI files.
The examples for using this class are based on the same application settings and user preferences
used in the registry examples above. If these settings were stored in an INI file, the file might be
named myVFPApp.ini and would look something like this:
[Application Settings]
AppDir=C:\Program Files\ITA\myVFPApp
DataDir=C:\Program Files\ITA\myVFPApp\Data
[User Preferences]
AskOnExit=Yes
PrintPreview=Yes
The structure of an INI file is quite simple: An INI file has sections, and sections contain entries.
In the example above, the lines with values in square brackets are the section names. The other
lines are the entry names and their corresponding values. To access an entry in an INI file, you

need to supply the INI file name, the section name, the entry name, and (for writing) the entry's
value.
To use the oldinireg foundation class, start by creating an instance of it.
loINI = NEWOBJECT( "oldinireg", "registry.vcx")
The methods in this class take several parameters, one of which is the name of the INI file. You
need to use a fully qualified file name (drive, path, and file name) or the methods won’t work. An
easy way to do this is to set up a memory variable.
lcINIFile = FULLPATH( "myVFPApp.ini")
The GetINIEntry( ) method reads the value of an entry in the INI file. It’s parameters are the INI
file name, the section name, the entry name, and a place holder for the return value (but not in that
order). The following code reads and displays the value of the AppDir entry from the Application
Settings section of myVFPApp.ini.
* Retrieve the value of an entry
lcValue = “”
lcSection = "Application Settings"
lcEntry = "AppDir"
loINI.GetINIEntry( @lcValue, lcSection, lcEntry, lcINIFile)
?lcValue
Writing an entry to an INI file is equally straightforward. The WriteINIEntry( ) method takes the
same parameters as GetINIEntry( ), except you also need to supply the value to be written. The
following code illustrates how to set the value of the AskOnExit entry to “No” in the User
Preferences section of myVFPApp.ini.
* Set the value of an entry
lcSection = "User Preferences"
lcEntry = "AskOnExit"
lcValue = "No"
loINI.WriteINIEntry( lcValue, lcSection, lcEntry, lcINIFile)
The WriteINIEntry( ) method returns zero if successful, otherwise an error number is returned.
Working with INI files is simpler than working with the registry, which is another reason you may
want to use them. But although INI files are still useful, they in no way take the place of the
registry. Fortunately, the registry foundation class make it easy to work with both.
The registry foundation class library also contains three other subclasses—filereg, foxreg, and
odbcreg—which you can explore on your own.
MouseOver Effects Foundation Class
The MouseOver Effects foundation class is a user interface enhancement that adds a dynamic
highlight to a control as you mouse over it on a form. The _mouseoverfx class is found in the
_ui.vcx class library, and is accessible from the User Controls catalog in the Component Gallery.

The MouseOver Effects class is quite easy to use. Simply drop an instance of the class on a form,
then add a call to its HighlightMe( ) method in the control(s) to which you want to apply dynamic
highlighting. The HighlightMe( ) method takes one parameter, which is an object reference to the
control. For calls made from within a method of the control itself, simply pass THIS as the
parameter.
You can see how the MouseOver Effects works by running the sample from the Component
Gallery. In the sample, the call to the HighlightMe( ) method of the MouseOver Effects class is in
the MouseMove( ) method of the control.
* The Command1.MouseMove( ) event code from the MouseEffects sample
LPARAMETERS nButton, nShift, nXCoord, nYCoord
THISFORM.cusMouseOverFX.HighlightMe(THIS)
While this works, it does not remove the highlight until the user moves the mouse over another
control on the same form that also calls the HighlightMe( ) method. If a form has only one control
that uses the MouseOver Effects class, then once highlighted, the control stays highlighted until
the form is closed.
To me, it would be preferable to have the dynamic highlighting disappear when the mouse moves
off the control, regardless of where it moves from there. This can be accomplished by calling the
CancelHighlight( ) method from the MouseLeave( ) event. Also, calling HighlightMe( ) from the
control’s MouseOver( ) event means the event fires continuously while the mouse is moving over
the control. This is unnecessary, so to me it makes more sense to call HighlightMe( ) from the
MouseEnter( ) event. The modified code would look like this:
* The CancelButton.MouseEnter( ) event code
LPARAMETERS nButton, nShift, nXCoord, nYCoord
THISFORM.cusMouseOverFX.HighlightMe(THIS)
* The CancelButton.MouseLeave( ) event code
LPARAMETERS nButton, nShift, nXCoord, nYCoord
THISFORM.cusMouseOverFX.CancelHighlight()
With this code in place, the cancel button is highlighted when the user moves the mouse over it,
and the highlight disappears when the user moves the mouse off the control. Note that this is a
change to the implementation of the class, not a change to the class itself.
The MouseOver Effects class has properties enabling you to control the width and colors of the
highlight effect. The effect requires two colors, one for the top and left (highlight) and one for the
bottom and right (shadow). The initial value of these colors is established in the Init( ) method of
the class, which calls the GetSysColor( ) API to get the system's 3D highlight color and 3D
shadow color. Unfortunately, this means you cannot override the colors by setting different values
in the instance on your form, because when Init( ) runs it sets them to the defaults.
There are at least a couple of ways to change the highlight colors, though. One way is to set the
colors explicitly before calling HighlightMe( ). This approach enables you to select different
colors for different controls, should you need or want to do that. Another way would be to create
a subclass of the MouseOver Effects class and either pass the colors as parameters to the Init( )
method, or add a SetHighlightColors( ) method to set the colors after Init( ) has already run.

Figure 8 shows a form with a cancel button that uses the MouseOver Effects class to add dynamic
highlighting. The highlight color is set to red and the shadow color is set to blue. I chose these
colors because they show up well in the screenshot to illustrate the effect, even though I doubt
anybody would actually use red and blue in a real application.

imageimage
Figure 8: A sample form with the MouseOver Effects foundation class applied to the Cancel button. The
effect is off, as shown on the left, and appears only when the mouse moves over the control, as shown
on the right.
The session downloads include a form named frmMouseFX that implements this effect. The code
in the Cancel button’s MouseEnter( ) event looks like this:
* The revised CancelButton.MouseEnter( ) event code.
LPARAMETERS nButton, nShift, nXCoord, nYCoord
WITH THISFORM._ mouseoverfx1
.iHighlightcolor = RGB(255,0,0) && red
.iShadowColor = RGB(0,0,255) && blue
. HighlightMe(THIS)
ENDWITH
The MouseOver Effects class is not limited to command buttons; it can be applied to other types
of objects as well. Check out the solution sample for more examples.
About Dialog Box Foundation Class
The About Dialog Box foundation class provides a template for creating an About form for an
application. To explore it from the Component Gallery, select the Dialogs catalog, right click on
the About Dialog icon, and choose Create Form from the popup menu.
Out of the box (no pun intended), the new form looks like this:

image

Figure 9: Before you customize it, the About Box Dialog is simply a template form.
If you open the About Dialog Box class in the Class Designer, you can see it includes an instance
of the Registry foundation class. The class Init( ) method uses the Registry class to retrieve the
location of msinfo.exe, which is launched from the Click( ) event of the System Info button.
The class Init( ) method also calls GetRegisteredCompany( ) and GetRegisteredOwner( ), which
are stub methods to retrieve the captions for Registered Owner and Registered Company labels.
Rather than changing the captions of these labels directly, change the code in the two methods to
retrieve the information from wherever it is stored in your application or license manager.
Finish customizing the About box by adding a graphic and changing the captions of the top four
labels, as appropriate. You now have simple but entirely suitable About form for your app.image

Figure 10: The finished About Box Dialog has a plain yet polished appearance, suitable for use in an app.
Hyperlink Label Foundation Class
The Hyperlink Label foundation class—like its two siblings, the Hyperlink Button class and the
Hyperlink Image class—provides a way to launch the default web browser by clicking on the
control. These classes are found in the _hyperlink.vcx visual class library, and are accessible from
the Internet catalog in the Component Gallery.
One thing I like to have on the About form for my apps is a link to my website. The Hyperlink
Label class is ideal for this. To use this class on the About form from the previous example,
simply open the form in the designer and drop an instance of the Hyperlink Label class on it.
Position the label where you want it on the form. Set the label's caption to whatever you want; for
a standard website, I like to use the URL without the http:// in front of it. Then set the cTarget
property to the complete URL of the website you want to open when then the label is clicked.
After doing this, the About form now has a hyperlink label underneath the trademark line, as
shown in Figure 11. The control’s blue color and underlined caption are visual cues that it’s a
hyperlink, plus the mouse pointer changes to the hand symbol when the mouse is hovered over the
label. Clicking the label opens the website in the default browser.image

Figure 11: The Hyperlink Label foundation class makes it easy to add a hyperlink to a form.
The Hyperlink Button and Hyperlink Image foundation classes work the same way as the
Hyperlink Label class. The one you chose to use is simply a matter of design preference.
File Version Foundation Class
The File Version foundation class retrieves the version information from a file and stores it in an
array. The class is essentially a wrapper around the AGetFileVersion( ) function, which was also
introduced in VFP 6.0.
One place the File Version foundation class can be useful is in the About form. Instead of
manually changing the caption on a label to reflect a new version number, drop the File Version
class on the form. Add code to the label's Init( ) method to set the cFileName property to the
name of your application's EXE file, and call the GetVersion( ) method to return the current
version number.
* The Init( ) for lblVersion uses the File Version foundation class to set its caption.
IF DODEFAULT()
WITH thisform._FileVersion1
IF _vfp.StartMode = 0 && Development version running in the IDE, use vfpX.exe
.cFileName = HOME(1) + "vfp" + ALLTRIM( STR( VERSION(5)/100)) + ".exe"
ELSE
.cFileName = SYS(16) && Name of the program being executed
ENDIF
.GetVersion()
this.Caption = "Version " + .aVersion[4] && Array element 4 is the version number
ENDWITH
ENDIF

If you're running in the IDE, the version number displayed will be the version number of Visual
FoxPro. If you're running from a compiled EXE, the version number displayed will be the version
number of the applications' executable file.image
Figure 12: This About form uses the File Version foundation class to retrieve the version number from the
program being executed.
Mover and Super Mover Foundation Classes
The Mover foundation class is designed to be placed on a form, where it provides side-by-side list
boxes with controls to move items from one side to the other. The Mover class is found in the
_movers.vcx class library and is accessible from the User Controls catalog in the Component
Gallery.
When placed on a form, the Mover class is a container with two list boxes and two command
buttons. The list boxes are populated from arrays. In typical use, the list box on the left contains
the list of available choices while the list on the right shows the items already selected. The Add
button moves a choice from the list on the left to the list on the right, and the Remove button
moves a selection from the list on the right back to the list on the left.
The array containing the list of choices is initialized by calling the InitChoices( ) method on the
Mover class and passing in an array. In the example I developed for this session, the initialization
is done in the Init( ) method of the form itself; a SQL Select statement retrieves a list of the
speakers at this conference from a table and creates a local array, which is then passed to
InitChoices( ).
* frmMover.Init( )
SELECT * FROM tblSpeakers INTO ARRAY laSpeakers

thisform._MOVER1.initchoices( @laSpeakers)
After adding an OK button and adjusting the height of the list boxes for a better fit, the form
looks like this:image
Figure 13: The Mover foundation class provides two lists and buttons for moving items from one list to the
other.
Once the user has selected the desired item(s), your program needs a way to get that information
back from the Mover class. The Mover class provides the GetSelection( ) method is this purpose.
This method populates an array (passed by reference) with the selected items, and returns the
number of items selected.
To effectively use the Mover class, you need to keep it in scope until you can call GetSelection( )
to return the results. One way to do this is to save the containing form as a class, create an
instance of it when needed, and keep the instance in scope until you're done with it. You'll want to
make the form modal so code execution in the calling method is suspended while the form is
active. You'll also want to change the OK button so it hides the form instead of releasing it, and
set the form's ControlBox property to False so the user has to use the OK button to close the
form.
The session downloads include an example to demonstrate the use of the Mover class. The form
itself is stored in class library myClasses.vcx as class frmMover. Also included is a program
named MoverDemo.prg, which runs the form and displays the results.
* The MoverDemo program runs the Mover foundation class example.
LOCAL ofrmMover, lni, lnSelected, lcMsg
LOCAL ARRAY laSelected[1]
laSelected = ""
ofrmMover = NEWOBJECT( "frmMover", "myClasses.vcx")
ofrmMover.Show()
lnSelected = ofrmMover._mover1.GetSelections( @laSelected)
lcMsg = "You selected " + TRANSFORM( lnSelected) + " speakers:"
FOR lni = 1 TO ALEN( laSelected)
lcMsg = lcMsg + CHR(13) + laSelected[lni]
ENDFOR

MESSAGEBOX( lcMsg)
ofrMover = null
The Super Mover foundation class is an enhanced version of the Mover class. The buttons
between the two list boxes have arrow-shaped pictures instead of text, and there are also buttons
for Add All and Remove All. The Super Mover class works the same as the Mover class, but I
think the buttons are more attractive and the two extra buttons give the user more control.image
Figure 14: The Super Mover class works just like the Mover class, but is more attractive and has buttons
for Add All and Remove All.
The session downloads also includes an example of the Super Mover class and the code to run it.
Look for class frmSuperMover in myClasses.vcx, along with SuperMoverDemo.prg.
Shell Execute Foundation Class
It's often useful to be able to open a file outside of your application, using the file's associated
application on the user's machine. Examples might include opening a readme file in Notepad,
opening a PDF file in the user's default PDF reader, or opening an image file in the user's default
image editor.
The Shell Execute foundation class makes this easy to do. This class is named _shellexecute. It is
found in the _environ.vcx class library, and is accessible from the Utilities catalog in the
Component Gallery. As you might expect, this class is a wrapper around the ShellExecute API.
The Shell Execute class has only one method, ShellExecute( ). Although the VFP Help File lists
only three, this method can take four parameters: the name of the file, the default path, the
operation to perform, and how to show the application. All of the parameters except the file name
have default values and are optional.
In its simplest form, you can use the ShellExecute class to open a file in its associated application
by passing only the first parameter. The following example creates an instance of the Shell
Execute foundation class and opens the file sample.txt in the file's associated application, which by

default is Notepad. Because a directory is not specified, the file must reside in the current
directory or the class won't find it.
* Open a file in the current directory.
loShellExecute = NEWOBJECT( "_shellexecute", HOME(1) + "FFC\_environ.vcx")
loShellExecute.ShellExecute( "sample.txt")
If the file does not reside in the default directory, you need to tell Shell Execute where to find it.
You can do this by passing a fully qualified path and file name as the first (and only) parameter, or
you can pass just the file name as the first parameter and the path as the second parameter.
* Open a file in a directory in the specified path.
loShellExecute.ShellExecute( "redist.txt", HOME(1))
* Another way to do the same thing.
loShellExecute.ShellExecute( HOME(1) + "redist.txt")
The third parameter specifies the action to be taken. If omitted, the default is "open". Other
choices are "edit", "explore", "find", and "print". Not all applications can handle all options. The
following example opens the file sample.txt in Notepad and prints it.
loShellExecute.ShellExecute( "sample.txt",,"print")
If you pass a folder name in the first parameter and "explore" as the third parameter, Shell
Execute open the folder in Windows Explorer.
loShellExecute.ShellExecute( HOME(1),,"explore")
The optional fourth parameter determines how to show the application window. The values for
this parameter are documented as defined constants in the source code for the Shell Execute class.
The defined constant SW_SHOWMAXIMIZED can be used to maximize the application window.
The following example opens a PDF file and maximizes the PDF reader application. The file
redist.pdf, which is simply a PDF copy of redist.txt, is included in the session downloads.
loShellExecute.ShellExecute( "redist.pdf",,,SW_SHOWMAXIMIZED)
All of these examples are included in the session downloads in program ShellExecuteDemo.prg.
Note that program execution continues after calling ShellExecute( ). The demo program has a
WAIT WINDOW after each command so it doesn't blow through all of the examples all at once.

No comments:

Post a Comment

Bottom Ad [Post Page]