
![]()
Editor.rpt --
By
VFUG
Update -- By the VFUG Board Members
Microsoft
News -- By Ken Levy and others
SQL Server for Foxpro Developers --
By Les Pinter
Closing a Form --
By Fletcher Johnson and Hugh Winter
Why
Visual Foxpro? Why Visual Extend? -- By Rainer Becker
Errors with "Built
In" Microsoft ActiveX Controls --
By Robert McNeal ![]()
Code your own Web Browser
with Visual FoxPro 8 -- By Grady McCue
FoxHound Source Control --
By Brett Carraway ![]()
Wireless Devices, Part 12:
Microsoft Does Bluetooth! -- By Tom O'Hare
What's
New for Spanish VFUG Members -- By Isaac Venegas
Resources
for German VFUG Members -- By Rainer Becker
Conferences
-- By
Resources--
By the Editor and Other Contributors
o Visual FoxPro and Programming
o MS KnowledgeBase
o Hardware, Software
and Operating Systems
o Web Services,
XML, HTML and Other Internet Items
o General
Interest
Tips
'n Tricks -- By the Membership
o Append Command Ignores Default Values -- Robert
McNeal (from the VFUG ListServe)
o DLL to handle Picture Files -- James Khan ![]()
o OLE DB Provider Problems --
Tony Green
o Dates and DateTime in
a SQL-Select -- Bob Morrell (from the VFUG ListServe)
o Does a Field Exist? (Continued
from December) -- Joe Gonzalez and Robert McNeal
o Where is the Windows
Directory (Continued from December) -- Arto Toikka
o Position a Right Click
Popup -- Robert McNeal (from the VFUG ListServe)
o Three Tips for Mobile
Users -- Tom O'Hare
o Cool
Trick (Literally) -- Tom O'Hare
ON SHUTDOWN....
![]()
Editor.rpt -- By Barbara Paltiel
First, we are proud to announce that our Technical Manager, Arnon Rotem-Gal-Oz is now a Senior Solutions Development Architect working for Microsoft in Israel. Best wishes on your new position, Arnon.
Well it's nice to know that people are reading my editorials. Unfortunately, several of my writers took the advice from December (Computing shouldn't take over your life) to heart and emailed me "I've found things more fun than writing - maybe I'll do an article for you in February". And I promised Margaret Duddy, the new VFP SIG leader for our local multi-subject programmers group, that I'd give a talk on 'Basics of West Wind Connection'. No big deal, I thought in November - and ended up spending hours writing an outline and preparing notes as well as setting up my new laptop with every example I needed. Of course all my examples were on my server - worked beautifully there, too. So why couldn't they just be reinstalled on the laptop?
It was obvious when I thought about it - my projects cover about 4 years of work, and some were in VFP6, others in VFP7 and the last in VFP8. Oh I'd installed all the run time libraries on the laptop. But the brand new laptop only had the VFP-compiled latest version of West Wind. And I found a couple of areas where things just wouldn't match up.
Finally I got everything working at home - but a bad case of nerves let me forget to use ONLY the compiled EXEs - and one of my samples simply failed. VERY publicly during the talk.
So all of the preceding chat is just to explain why I haven't written anything of substance this month. I spent the holidays in Los Angeles with my sister's family, though and had a great time. Did anybody know there's a Museum of Neon Art? Complete with old signs and new art works. Very "LA". And the new cathedral is quite literally awesome - doesn't matter what your religion, the building is amazing. We're going back for another visit later after learning more about the computer-woven tapestries, the huge bronze doors and the many other works of art. We started for a Persian restaurant one night, ended up at a Cuban bistro instead, because it smelled so good as we walked past. (Tasted good too.)
I hope all of you managed to take some time off also, even if you spent it alone with a book or hiking a nature trail.
I'll leave you with a quote Carl Warner found on the ExtremeTech site:
"There are two ways of constructing a software design: one way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult." - C. A. Hoare
![]()
If you can't remember your password, send me an email (barbara@vfug.org) giving me your original email if you know it, your full name (first and last) and any other pertinent information like company, country, city, etc. I'll try to find you in the membership list and email you back. This may take a day or two - I DO have to work for a living. If you're named Steve Smith or Alberto Rodriguez or any other fairly common name (we have 5 of each) give me as much information as you can. I will NOT send a login to anyone unless I'm sure it's the right person.
![]()
Every Thursday at 3 PM Eastern Standard Time,
Chat subjects can range from a topic like “Using Visual FoxPro in a Linux environment” to one we had “Valhalla, a management tool for VFP” presented by it’s author Pablo Flores.
So if you have a topic and would like to lead a chat please mail John
Chambers. The chats start at
If you would like to be on the list of people sent reminders of the chat, sometimes if there is a topic a day or 2 before the chat and one as the chat starts. Email John@VFUG.org?subject=AddChatNotificationList Please be sure to enclose your name and the address you would like the notice sent to.
![]()
See you next month - and it's time for readers in groups 30+ to send me a tip, a question, an article or other newsletter information. Check your group on your email subject line. If you're reading this on the VFUG site, you get to join any group you want.
Have you noticed how many of the tips come from ListSever messages? Join the ListServe and see what else you're missing. Just send a message to VFUGListServer@VFUG.Org with the message SUBSCRIBE
-- Barbara
As we are a free service to you, the membership, we thank the supporters of VFUG who have placed paid banner ads on our opening page. They help defray the costs of running the server for this site and give their products and services some well deserved exposure. Be sure to check out their offerings as you may be surprised how much their latest versions can help you.
|
|
VFP Vendor |
Product or Service |
|
|
|
Visual ProMatrix Framework |
|
|
|
|
Foxfire! Report Writer and Consulting Services |
|
|
|
|
Custom Programming Services |
|
|
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
![]()
|
At the VFUG Web Site: |
|||
| VFUG Home | Chat | Real-time online chatting at least every week, usually on Thursday at 3pm EST, 2pm CST, etc. Topics are sometimes announced but are open. | |
| File Archive | Fox-related files, utilities, & newsletter downloadables. | ||
| Lectures | Online lectures, presentations, conferences. | Support | Use the VFUG Forum to post questions and supply answers to anything that is FoxPro-related. Categories are clearly shown. |
| Knowledge Base | Knowledge Base from our members. | ||
| Vendor List | List of current and past Vendors of the Month. | FAQ | Frequently Asked Questions (FAQs) for the Fox community. |
| VFP Resource Center | Tutorials are underway for beginners to MS Visual FoxPro. | ||
| Newsletters | This area allows you to view all VFUG newsletters. | Links | This is an area that is constantly under construction as new web links of interest to the Fox community are posted. |
| Case Studies | Case studies from our members. | ||
| Job Bank | Job opportunities and jobs wanted postings. | Members | This area is where you can view the latest additions to the VFUG community as well as update your vital statistics including mailings. |
VFUG Officers:
| # | Name | VFUG Function | E-Mail Address |
| 1. | John Chambers | Public Relations Manager | John@VFUG.Org |
| 2. | Colin Keeler | Web Manager | Colin@VFUG.Org |
| 3. | Carl Warner | Marketing Manager, Vendor Relations | Carl@VFUG.Org |
| 4. | Arnon Rotem-Gal-Oz | Technical Manager | Arnon@VFUG.Org |
| 5. | Tom O'Hare | Operations Manager | Tom@VFUG.Org |
| 6. | Barbara Paltiel | Newsletter Editor | Barbara@VFUG.Org |
![]()
By the VFUG Board Members
Don't forget this newsletter is always available on line. In fact I post it as I put it together so you'll see an 'Under Construction' note on the link and the file downloads will probably say 'file not found' However it's a LOT easier to read in HTML, and all files to download are just a quick link away. It's a lot prettier and easier to read in HTML - we use a lot of colors and you can jump from any entry in the Table of Contents to the actual article or tip. And finally you can search the text of the online newsletters for any word or phrase.
Check out the latest VIM download. Tom O'Hare has added quite a few new features which we've been testing in the weekly Thursday Chat. Just log onto VFUG and download it or pick it up from the tip in the online version of the newsletter. It's FREE like everything else at VFUG (except our banner ads).
Newsletters are now being sent as ZIPped text files. If you want to receive the Newsletter in TEXT only format you will have to log onto the VFUG site, go to "Members", then "Update your Account Information" and change your Mailing information from "Full Service ZIP File" to "Full Service Text File". Note that almost every mail server will accept a ZIP file attachment, but many now are rejecting text files particularly those with 'programming language' or 'scripts' in them. Which, of course, our newsletter is stuffed with.
Thanks!
![]()
Ken Levy and Others
Visual
FoxPro 8.0 Service Pack 1 Released
Download Visual FoxPro 8.0 Service Pack 1 (SP1). Discover the many enhancements
and stability improvements designed to improve the reliability and performance
of Visual FoxPro 8.0.
New RSS XML Support
Microsoft recently added RSS XML support for the Visual FoxPro section of MSDN.
For more information about RSS newsfeeds on MSDN, refer to the MSDN
RSS Feeds page. Thanks to Microsoft MVP Rick Strahl, FoxCentral.net now
provides an RSS XML news feed. To access the RSS feed, visit the FoxCentral.Net
site site and click on the RSS image which links you to the RSS
feed. You can use these and other RSS XML news feeds with any RSS news aggregator.
Latest News on Visual Foxpro: Read Ken's monthly letter. The most recent letter describes "Europa", the next version of VFP and give a sneak-preview of some screen shots.
![]()
SQL Server for FoxPro developers
Les Pinter
If you write an application using DBFs, the day may come when you’ll be asked to solve problems that are inherent in their use: They’re not secure (anyone who can get into your DBF directory can see the data); they get slower as more records are added to tables, especially on Local Area Networks (LANs); and occasionally, you have to kick out all of the users, open each table exclusively and rebuild the indexes. Finally, your application data is spread over many files - DBFs, FPTs, CDXs, DBCs, DCXs and DCTs. This makes distributing and managing an application more difficult.
Multiuser environments compound these problems. Performance degrades as tables grow, due to the way indexes are shared in memory on all attached workstations. Eventually, performance can get really, really bad. And security issues involving DBFS are only made worse in a LAN environment. Anyone can sit at a workstation and open up the data. An error in a single byte of the first 32 bytes of a DBF can render it unreadable. (This is less likely to occur these days, but a friend of mine made enough money to retire off this little problem.) Also, you have to build your own password system to control who can read or change the data.
Usually the solution is a Structured Query Language (SQL) server. SQL is a simple mechanism; how hard can it be when it only has 4 commands (INSERT, SELECT, UPDATE and DELETE)? It can be accessed via either Remote Views or via SQL Pass-Through (SPT). We won’t discuss remote views in this book, since as seductive as they may seem, for our purposes they’re more trouble than they’re worth ( although they’re very useful for data migration and conversion, as you’ll see later.)
SPT can be implemented with just three commands:
Listing 1 - Connecting to SQL using a connection string SQLConnect ( DSN ) or SQLStringConnect( ConnectionString) to get a "handle"; SQLExec ( Handle, CommandString, CursorName ) to send SQL commands; and SQLDisconnect ( Handle ) to close the connection.
Here’s an example to open a connection, get a record, and close the connection:
Listing 2 - Connecting to SQL and returning a cursor
lcStr = [Server=(local);Driver={SQL Server};Database=pubs;UID=sa;pwd=;]
lh = SQLStringConnect ( lcStr )
lcCmd = [SELECT * FROM AUTHORS WHERE AUID = ] + lcAuID
lr = SQLExec ( lh, lcCmd, [AuthorCursor] )
SQLDisconnect( lh )
BROWSE && AuthorCursor is open at this point
It’s my contention that a mechanism that only uses three functions isn’t all that hard, either. It’s pretty easy to add SQL capabilities to any screens you might already have that are based on DBFs.
Most FoxPro applications use DBFs to store data. DBFS are wonderful for single user applications. You open all tables exclusively and bind table fields to form controls (like textboxes and checkboxes). You no longer have to use memory variable copies of all data fields for adding and editing. You simply set buffering mode to 3 to effectively separate the screen controls from the data fields, then issue TableUpdate(.T.) to make the changes permanent or TableRevert(.T.) to forget they ever happened.
On a Local Area Network, you just open all DBFs in SHARED mode, and except for a little slowdown you have a multi user application. (There are some theoretical issues involving the possibility that two users try to edit exactly the same record at exactly the same time. But the probability that such a conflict will actually occur is infinitesimal in most systems, and the cost to code for this contingency is not justified. Base your decision to add the expense of this additional code on the nature of the requirement.)
Usually you add all tables and views to the form’s Data Environment and let it open them for us. Since all aliases have to be open before the form’s controls are created (instantiation of form objects happens between the form’s Load and Init events), using the Data Environment to open tables saves us a little programming. If you instead use your own code in the form’s Load event to open cursor and dbfs, you have more control. And that little additional bit of control makes all the difference.
When you add a table to the Data Environment, the record pointer of that table will be moved to the first record in the active index tag when the table is opened. If you wanted to use the record that had been selected previously by another form, you’d be better off using the OpenDBF routine developed earlier. To refresh your memory, here’s the code again:
Listing 3 - Opening a DBF Program-ID....: OpenDBF.PRG Purpose ......: Opens the file if not already open, and selects it regardless * : If an index tag is supplied, activates the named index tag PARAMETERS AliasName, IndexTag IF NOT USED ( AliasName ) SELECT 0 USE ( AliasName ) ENDIF SELECT ( AliasName ) IF NOT EMPTY ( IndexTag ) SET ORDER TO TAG ( IndexTag ) ENDIF
Instead of including table and view names in the Data Environment, you should get in the habit of using calls to a routine like this in the Load event of our forms to open tables and views. So our Invoice form would need the following code added to its Load event (I opened Invoices last so that it would be selected when the form opens):
Listing 4 - Using the LOAD event of a class to open DBFs OpenDBF ( [InvDetl], [InvDetl] ) OpenDBF ( [Customer], [CustID] ) OpenDBF ( [States], [State] ) OpenDBF ( [InvView], [] ) OpenDBF ( [Invoice], [InvNum] )
However, as you’ll see shortly, instead of opening a DBF, you will instead create a cursor and import data from SQL data into the cursor. Let’s see how SQL works, then consider what’s the best way to use data binding in the SPT environment.
Don’t rush out and buy SQL: You may already have a copy. Microsoft ships a copy of a "Personal SQL" called Microsoft Data Engine (MSDE) with Visual Studio as well as with VFP. You can even distribute MSDE with your applications, royalty-free: When you build an installation setup for your application, selecting a single checkbox will add the installation of MSDE to your installation disk.
SQL data is encrypted by its nature. It’s stored inside a monolithic file in a form that can’t be read unless you have a Logon Name and a password. SQL solves the performance problem caused by FoxPro index traffic on a network, since it doesn’t send index information to workstations. So, performance doesn’t degrade as tables grow very large. (SQL performance is, however, considerably slower than that of DBF-based systems, but users seem to tolerate it well enough.) And SQL has a UserID and Password system built in; change the password, and only the users who know the new one can get it.
There is a difference: When you write a SQL-based database application, the cursors that are returned are not bound to the tables as they are in a DBF-based app. Instead, you send a SELECT statement (or call a stored procedure that executes a SELECT statement) via the SQLExec() function and get back a cursor containing the selected records.
But the cursor that’s returned isn’t the same one that you opened in your form’s Data Environment or Load event. How do you connect the two without breaking the connection? At Pinter Consulting, we use a simple solution that eliminates a huge amount of programming and implies only a small performance penalty. In the form’s Load event, we create a cursor that exactly duplicates the structure of the table that’s stored on the SQL Server, and bind the form’s controls to it. (We actually create a DBF and add it to the Data Environment just long enough to design the form, and then erase it. More on that later...)
Then, whenever we return records, we simply ZAP the local cursor and append the SQL records into it. Since the local cursor remains bound to the form’s controls, the connection is never broken.
Saving is different. When you save additions orchanges, you construct either an INSERT or an UPDATE statement that sends the data back to SQL. The UPDATE statement must include one or more key fields that uniquely identify the record to be updated.
To use SPT, your program first establishes a connection to the server. This is usually done using the SQLConnect() or SQLStringConnect() functions. SQLConnect uses a DSN, which you create by running ODBCAD32.EXE on your workstation and filling in a few parameters. With a DSN-less connection, you don’t need to run the ODBCAD32 step on each workstation. I much prefer the DSN-less connection.
Either function returns an integer value (1, 2, etc) called a handle. Subsequently, SQLExec() function calls which use the handle as the first parameter and a SQL statement as the second parameter, operate on the table named in the SQL statement. If you supply a name as the third parameter, data is returned in the named cursor. If no cursor is named, the cursor is given the name SQLResult by default. We generally don’t bother to supply a name for the cursor, except when populating a grid for a search form.
Listing 5 - Returning a handle using a DSN into the default cursor SQLResult Handle = SQLConnect ( [MYDATASOURCE] ) lr = SQLExec ( Handle, [SELECT * FROM CUSTOMER WHERE CustID = 123] )
This would return the record for customer# 123 into a cursor called SQLResult.
Listing 6 - Returning a handle using a connection string into a named cursor
StrCmd = [Server=(local);Driver={SQL Server};Database=One;UserID=aa;pwd=b;]
Handle = SQLStringConnect ( strCmd )
lr = SQLExec ( Handle, [SELECT * FROM CUSTOMER], [AllCusts] )
This would return the entire customer table into a cursor named "AllCusts"
However, this isn’t the name of the cursor that you bound the form’s controls to. When you design a form, you drag fields from a DBF in the data environment to the screen, thus automatically setting the ControlSource of each field. The ControlSource contains the name of the cursor, a period, and the name of the field (e.g., Customer.Phone.) You can’t use the existing cursor as the third parameter, because SQLExec expects to create a new cursor. But if you append it into the cursor that was opened in the Load event, it won’t break the data bindings. All you have to do is make sure that the field names are the same.
Of course, you can’t simply write
SQLExec ( Handle, [], [ABC] ) SELECT XYZ APPEND FROM ABC
because ABC is an alias, not a DBF, and the APPEND FROM statement requires a DBF name. However,
APPEND FROM DBF ( [ABC] )
works just fine, since the DBF() function returns the temporary file name that the alias is using (usually something like 30324142.tmp).
How do you create a cursor in the Load event? You could hard-code the creation of each cursor, but there’s a better way: You can use a Data Dictionary that contains the information needed to build the cursor, then call the CreateCursor() function described below.
The Data Dictionary table looks like this:
Listing 7 - The DataDict table for creating cursors as needed DATADICT.DBF: CursorName Character(30), FieldName Character(30), FieldType Character(10), FieldLen Numeric ( 3), Decimals Numeric ( 1)
I’ve written a little program to make it easy for you to add your existing DBFs to the Data Dictionary table:
Listing 8 - Program to add a DBF’s structure to the DataDict table Program-ID... ..:Add2DD.PRG Purpose.........: Adds a table’s fields to the DataDict table IF EMPTY ( ALIAS() ) MessageBox ( [No table is open in the current work area], 64 ) RETURN ENDIF NewAlias = ALIAS() =AFIELDS( FA ) FOR I = 1 TO ALEN ( FA ) INSERT INTO DataDict VALUES ( ; NewAlias, FA(I,1), FA(I,2), FA(I,3), FA(I,4) ) ENDFOR
The CreateCursor function follows. Note that the Create Cursor command requires an array with 16 columns, since that’s the number of columns in arrays created by AFIELDS() function:
Listing 9 - Program to create a local cursor using a structure from DataDict
* Program-ID...: CreateCursor.PRG
* Purpose......: Creates a cursor from a tablename
PARAMETERS CurName
SELECT FieldName, FieldType, FieldLen, Decimals FROM DataDict ;
WHERE ALLTRIM(UPPER(CursorName)) == ALLTRIM(UPPER(CurName))INTO ARRAY CurDef
IF TYPE ( [CurDef(1)] ) = [U]
Msg = [Programmer error:] + CHR(13) ;
+ CurName
+ [ fields not found in data dictionary]
MESSAGEBOX( Msg, 64, _VFP.Caption )
ENDIF
DIMENSION CA ( ALEN(CurDef,1), 16 )
STORE [] TO CA
FOR I = 1 TO ALEN ( CA,1)
CA(I,1) = ALLTRIM(CurDef(I,1))
CA(I,2) = ALLTRIM(CurDef(I,2))
CA(I,3) = CurDef(I,3)
CA(I,4) = CurDef(I,4 )
CA(I,5) = .F.
CA(I,6) = .F.
ENDFOR
CREATE Cursor &CurName FROM ARRAY CA
USE EXCL
RELEASE CA, CurDef
IF USED ( [DataDict] )
USE IN DataDict
ENDIF
If you’re already using MS SQL 2000 and your data tables have already been built, you can use the Enterprise Manager to generate scripts that you can use to create tables locally. Expand the Databases node, then right click on your Database name, select All Tasks, select "generate SQL scripts", check the All Tables option and provide a file name.
Scripts are files with an ‘.sql’ extension that contain the SQL code needed to create a table or a stored procedure inside the SQL Query Manager (isqlw.exe). But the SQL syntax for creating a DBF is almost identical to that of VFP. So you can open the .sql script, copy the CREATE TABLE statement to a .PRG, make any necessary modifications, run it to create the table, then run the Add2DD program once for each table. Don’t forget to delete the DBF afterwards if you don’t need it.
You may want to wait to delete the DBF until you’ve finished building your forms. The reason is that, even though you’re going to use cursors for your tables, you need to open a DBF and add it to the form’s Data Environment in order to use Drag-and-Drop to place fields on the form. So create the DBFS and add them to the Data Environment of your forms. Then, after you’ve dropped all editable and displayable fields on the form, delete the DBFs and add the CreateCursor() function calls that you need to the form’s Load event.
This may surprise you, but you may want to duplicate some of your SQL tables as DBFs in the application directory. The reason for this is performance. Some of your forms probably have combo boxes or list boxes that are populated using records from small tables. Do you really want to go to SQL Server once for each one of these little tables every time you instantiate each of your forms? Probably not.
Instead, you should keep a complete copy of these tables locally as DBFs, refreshing them whenever the Server copy of the table changes. We’ll add a mechanism for synchronizing these local tables later in this article.
Before you modify your form classes to work with SQL Server, let’s learn a little more about SQL.
I strongly recommend that you install a copy of SQL Server, preferably SQL Server 2000 or its MSDE equivalent, on your development computer. SQL applications don’t care where the server is, so your commands will work exactly the same whether your server is on your own computer or on another computer on your Local Area Network.
You will be asked at one point in the installation process whether you want to use "mixed NT and SQL authentication" or "SQL login and password authentication". I recommend that you not use NT authentication in your development environment. Managing NT security is a far more complex matter than is simply providing a userid and password to SQL, and there’s nothing to be gained by complicating our programming task.
Once you’ve finished installing SQL, you’ll see a SQL Server icon on the Windows taskbar. Double click on it, and the SQL Server Service Manager interface will maximize on your screen. If the Server name is blank, right click on My Computer on your desktop (Windows 2000), select Properties, select the Network Identification page, and copy the Full Computer Name entry to the blank input field on the Service Manager screen. I don’t know why it sometimes doesn’t fill in automatically, but that’s what it’s looking for. I also check "Auto-start service when OS starts".
Next, open up the Query Analyzer. You may want to add a shortcut to it on your
desktop. The program name is isqlw.exe, and it will be located in your MSSQL\bin
directory, probably in your Program Files directory. (I usually install in a
directory called MSSQL at the root level.) You’ll see the screen shown in
Fig. 1 - the SQL Server Query Analyzer screen
Again, if the SQL Server name is blank, fill in your computer name.
When you install SQL Server, a default System Administrator user with Login name "sa" and a blank password is installed. Since every copy of SQL is installed with this Login Name and password, you probably will want to add a new UserID and delete this one. But first, take a moment to understand how Logins work. Click on Ok to go to the next screen, shown in Fig. 2.
Fig. 2 - The Query Analyzer Screen when the System Administrator ("sa") login is used
Since the System Administrator logon has access to all databases, you can pull down the DB combobox and pick any of them. If the Logon only had access rights to a single database, you’d only be able to select that database. In fact, when you first see this screen, the DB name that’s displayed would be the database that the logon had been assigned to as its default database.
Before you create a database, you should understand what files are involved. SQL databases are monolithic files that have the extension ‘MDF’ by default. Generally you simultaneously create a LOG file in the same directory. When you execute commands against your database, the commands themselves are added to the LOG file. If you execute a Backup, the database file is copied to a backup format and the LOG file is emptied. Thereafter, if your database file is destroyed, you can RESTORE the database using (1) the backup file and (2) the current LOG file, which contains all transactions entered since the backup.
Obviously, it might be a good idea to store the Backup and the LOG file somewhere other than the hard drive where the .MDF file is located. A head crash is the worst case scenario, and if it takes out your .MDF file, your .BAK and your .LOG file, you’re not going to recover. So understanding how these files are used should dictate your choice of locations for them. I use a SYQUEST 1 GB drive, and I change the cartridges between backups. A word to the wise is sufficient.
You can create your database using the Query Analyzer, simply by typing in a command to creates the DAT and LOG files. However, it’s better to use the SQL Enterprise Manager. It walks you through all of the required steps, it doesn’t require that you memorize the command syntax, and it lets you create the Logon and password that you’ll use to access SQL from your programs. Add a shortcut to C:\WINNT\system32 \mmc.exe /s "C:\MSSQL\BINN\SQL Server Enterprise Manager.MSC" on the desktop, pointing to the \MSSQL\Binn directory at the same time. Doubleclick on it to bring up the screen shown in Fig. 3. (You can also simply drag it from the Start menu to the desktop.)
Fig. 3 - The SQL Enterprise Manager screen
The first thing you’ll have to do, if it’s not already been done for you by the installation process, is to register your SQL Server. The screen you’re looking at is the Microsoft Management Console screen. (MMC is a utility that provides an interface for managing resources if this type.)
Expand the SQL Server Group branch, then RightClick on the right pane and select New SQL Server Registration. The Register SQL Server Wizard screen will appear.
The first page of the Wizard presents a list of all SQL Servers that you’ve previously registered using the SQL Client Network Utility. That means that you can register remote SQL servers that you have access to, including the SQL server that your Internet Service Provider has set up for you. You can use the Enterprise Manager to manage your SQL server at your ISP, using TCP/IP as the network connection. The first time I did this I was simply amazed - it really works!
For now, enter (local) - parentheses and all, as I’ve done in Fig. 4.
Fig. 4 - Entering the name of your SQL Server
On the next page, select SQL Server authentication (shown in Fig. 5), as we
discussed above:
Fig. 5 - Selecting the Authentication mode
It’s safest to have the server ask for a userid and password each time you connect for administrative purposes, so select the appropriate option on the screen shown in Fig. 6:
Fig. 6 - Requiring a logon to access the server from within the Management Console.
Now you can open the server and manage it. Double click on the server to open
it, and expand the tree to expose the Databases node. Click on it to select
it. At this point, you can right click on the right pane and select New Database.
You’ll see the New Database Properties screen shown in Fig. 7:
Fig. 7 - New Database Wizard dialog page
The purpose of this screen is to create an initial database file and its corresponding log file. The initial size is not too important in your testing, since you’ll probably only use a couple of megabytes of storage space. SQL Server automatically allocates additional space as needed (unless you Restrict Growth.)
As you can see in Fig. 7, when I entered Pinter, SQL automatically created a file named Pinter_Data.MDF in the default data subdirectory that SQL defined during SQL setup. You don’t have to use this location. In fact, on my development machines, I prefer to create a root-level directory for the database for each application that I build. The LOG file is by default created in the same directory, but you already know what I think of that. Click OK to save the new database file.
But we’re not finished. In order to get into SQL, you must create a logon name. Go to the bottom of the MMC tree for your server and expand Security, then select Logins. RightClick on the right pane and select New Login to open up the dialog shown in Fig. 8.
>
Fig. 8 - The SQL Server New Login dialog
I entered Les for the Logon name and "xyz" for the password. I also pulled down the Database combobox and selected Pinter as the default database. This is very important, since among other things it tells the Query Analyzer to select this database by default when you logon as Les, password xyz.
Next, select the second page of the page frame. As you can see in Fig. 9, I’ve used the down arrow and the spacebar to select every type of Server Role available. It’s my database, after all. If you were creating a logon for access only, you might want to be less generous. But you can leave that to the Database Administrator. Database security management is a big job, and you don’t want it. Just practice saying "it’s not my job..."
Fig. 9 - Selecting Server Roles for our logon
Finally, go to the Database Access page, select the Pinter database, and again check everything that’s available (Fig. 10).
Fig. 10 - Selecting databases that this logon has access to
Click on OK. The dialog will verify the password that you chose on the first page, so enter it again.
Now, start up the Query Analyzer again and enter Les as Logon name and xyz as the password. You’ll see the Query Analyzer screen with the name of the Pinter database in the DB combobox. You’re in!
In the Query Analyzer window, type the code shown in listing 10:
Listing 10 - Creating a SQL table in the Query Analyzer CREATE TABLE States ( State Char(2), LongName Char(15), Country Char(15) ) INSERT INTO States VALUES ( ‘AK’, ‘Alaska’, ‘USA’ ) INSERT INTO States VALUES ( ‘AL’, ‘Alabama’,‘USA’ ) INSERT INTO States VALUES ( ‘CA’, ‘California’, ‘USA’) SELECT * FROM States
You should see the screen shown in Fig. 11.
Fig. 11 - creating a table and adding records to it
That should server to get you started with SQL Server. In part two of this series, we'll see what you can do from inside FoxPro.
See 'ya.
Les
![]()
Fletcher Johnson and Hugh Winters
Oh VFUG Gurus, please help with this question:I just want a form to close when a User Double clicks on a grid after they move to the desired record? I tried to put Thisform.release in the Double Click method and it does not work? Do you know why?
- - - -
[Fletcher] Thanks for such a wonderful question. This leads to all kinds of fun issues.
The main problem is that you aren't putting the code in the correct place. But then, you knew that. Here are a couple of things to keep in mind when working in VFP:
It is always a good approach to have a special close method in the form. I use mClose. Then instead of calling the form’s release method, you call the form’s mClose method and let that method call the release method.
Why would you do this you ask?
This way, you can have any code that needs to run (say to check for changes, save, ask if the user is sure, whatever) in that one place. You can also set the queryUnload method to call this instead (by using the NoDefault clause to keep it from exiting the way it normally does.)
So now, if you need your form to close, whether by clicking on a close button on the form, in the toolbar, a file/close menu item, or even right clicking on the grid, there is one place to call to a) Check to see if they need to save or not and b) close the form properly.
As Hugh and I mulled this over, Hugh had some fun playing with the various methods that fire. In that endeavor, he found the following:
[Hugh] To make it easy to test which Form events fired when, in the DEACTIVATE, DESTROY, HIDE, QUERYUNLOAD, UNLOAD events and RELEASE (method) I put the following code:
=STRTOFILE(PROGRAM(0)+CHR(13),'c:\temp\formcloseevents.txt',1) DODEFAULT()
[Fletcher] Note StrToFile() will take a string and save it as a file. The last parameter tells it to append rather than overwrite the file. If you think this is cool, check out FileToStr() and how fast it can read a large file.)
[Hugh] What I came up with is kind of interesting...
Test 1) When I closed the form by clicking on the [X] form close button the following events fired:
FORM1.QUERYUNLOAD FORM1.DESTROY FORM1.UNLOAD
Test 2) When I closed the form by clicking on a button on the form that called the form's release method the following events fired:
FORM1.COMMAND1.CLICK FORM1.DESTROY FORM1.UNLOAD
Test 3) When I called the form using the NAME keyword to grab an instance handle on it and closed it by calling its name.RELEASE() method as below:
DO FORM "c:\vfug\formcloseevents.scx" NAME loForm
loForm.RELEASE()
The following events fired:
FORM1.DEACTIVATE FORM1.RELEASE FORM1.DESTROY FORM1.UNLOAD
As you can see, the destroy and then the unload events are the key things that run when a form is closed. If the release method is used to close the form, you will see that. But a queryUnload event does the same thing (unless you use NODEFAULT which prevents that from happening.) You don't call the destroy method though. Call the release method since that is its job.
[Fletcher] 2) On the Grid, there are lots of controls. When you double click on the grid, what is actually happening is that the column, header, or textbox is catching the doubleclick instead. One approach is to use BindEvents to fix this.
You could use code similar to the following in your grids init:
*-- Bind all the controls in the grid to the dblClick handler For Each loColumn In This.Columns *-- The column doesn't have a dblClick method, so we *-- just need to get all the controls in this column For Each loControl In loColumn.Controls Bindevent( loControl,"DblClick", Thisform, "mDoubleClickHandler") EndFor && Each loControl In loColumn.Controls EndFor && Each loColumn In This.Columns *-- Now get the grids dblclick as well Bindevent( This,"DblClick", Thisform, "mDoubleClickHandler")
- - - - -
Note that this assumes you have added a method named mDoubleClickHandler" to your form.
[Fletcher] Also, if you do this, you will find that the square in the upper left portion of the grid as well as the delete box to the very left of the grid do not respond to a doubleclick (turn on view events in the debugger to see what does fire when you double click in these areas.) You can add code to the mouse down/up methods, etc to also track double clicks (measure the time between mouse downs), but I am sure you can add that code if you want it.
A quick note on BindEvents: This is a super cool feature in VFP 8.0. If you haven't played with it, I recommend that you do so. Essentially, you can tell VFP that when an event fires in an object, instead of running the default method assigned to that event, it should run some other event. You can choose to run the other method before, after, or instead of the default method. In the example above, I tell VFP to call the forms "mDoubleClickHandler" method instead of the controls default double click handler. One note of warning: The new event handler must have the same parameters as the default event handler.
If you think about it, you could also use this same approach to make it so that all the controls on a form behave the same way if you double click on them. Or right click on them.
[Hugh] That's a great idea to cycle through the collection of controls contained in the grid. That way no matter how many columns, textboxes, headers, etc. that you have, they will all fire the same code. Hey! Why not add the mDoubleClickHandler code as a method to your grid class? Then your grid object doesn’t have to depend on the form that contains it.
Hope this helps,
Hugh and Fletcher
![]()
Why Visual FoxPro 8.0 ?
Why Visual Extend 8.0 ?
Rainer Becker
Where do we come from, where are we standing now, and, after all, where do
we want to go? These questions may appear a little bit unusual in the introduction
to the manual of a framework. But nevertheless it is worth wile reading, informative
and perhaps entertaining. And if we can reach at least some agreement of opinions
in the following chapters, we should get along well in the future because then
you know more exactly where we want to go and how far your aimed direction matches
our ideas, and how it helps you with achieving your objectives.
The advantages of FoxPro
Perhaps you know the saying, "moving house thrice is just like a home burnt down once". Those who had fought their way from FoxPro/DOS to FoxPro/ Windows were very busy with this first move. But as the underlying concept was already quite a modern one, this change could be handled well in most of the cases. And what did a FoxPro developer receive with his development environment – about the following offer still sounding very attractive today:
Looking back, the move from FoxPro/DOS to FoxPro/Windows was relatively easy when compared to the step from FoxPro/ Windows to Visual FoxPro. This second step was a substantially bigger challenge due to completely new concepts like object orientation and inheritance, methods, events, and properties. Regrettably and unexpectedly, some developers have – and alas, with success – avoided this change until today. As a result of this, the know-how and the decision-making ability for a possible change are missing. The question is, how long shall this go on?
The advantages of FoxPro enumerated in this first section have been kept up in Visual FoxPro. And the following substantial extensions have been added:
It was a stroke of genius not only to keep up the hybrid approach of data access (record-oriented and set-oriented), but to establish a model of programming which is now hybrid, also (procedural and OOP). Changing freely between SKIP and SQL now became possible as well as calling a procedure from an objects method. With this comes the tremendously practical feature of directly editing the class definitions and form definitions (so-called metadata). This has always permitted bending the inheritance hierarchy into shape in order to insert or correct intermediate levels later. The concept of hierarchical containers replaced the SimpleFrame interface and turned out to be very practical as well. The SimpleFrame user interface was fostered by Microsoft but did not allow two objects with identical names within one form, thus making the basically interesting reuse of aggregated objects a painful job.
Some programmers had used to copy code and adapt it instead of building an extended standard function, and thus it was their specialty to exchange a small saving of development time for a large lot of maintenance work. In the new Visual FoxPro world, they could of course continue to do this, ruining any thinkable advantage from the very outset. This happened more often than not. On the other hand, the desperate effort to model really everything and anything in classes and to introduce a separate layer of empty intermediate classes for any level thinkable lead to a much too complicated concept of development, a concept nobody can ever communicate to new staff on a project. As always, the truth is to be found somewhere in the middle.
Development really ripened with the large leap in features of the stable and capable version Visual FoxPro 6.0 which is considered the most frequently used version of Visual FoxPro. Owing to its downward compatibility each further update, beginning with Visual FoxPro 3.0, was rather smooth. Therefore people could change to the following version any time, although the German edition of version 7.0 seemed to have several annoying storage leaks.
Yet more advantages with Visual FoxPro 8.0
The current version Visual FoxPro 8.0 is a substantial step forward from its predecessor, featuring a leap in developing like with the popular version 6.0. You see this especially clearly in the respective treatment by Christian Desbourse which contains a quantitative comparison of all Visual FoxPro versions to date. The translated article has been published in the 12th instalment of the German loose -leaf periodical FoxX Professional, but it is also available online in the dFPUG (German-speaking FoxPro User Group) document portal and in the original English version on Mr. Desbourse’s website (http://www.cdesbourse.com/ Technology/t_vfp_evolution_en.htm). Unfortunately, this large step forward in developing is not yet known well enough, and many FoxPro developers do not see it, let alone see the resulting benefit for the practical work.

The most important features of Visual FoxPro, version 8.0 are:
It is called the biggest update since Visual FoxPro 6.0, and rightly so. There is plenty to learn for the users, especially for those of us who have left out one or more updates, i.e. for the majority of those who have now changed from Visual FoxPro 6.0 or even 5.0 directly to VFP 8.0 and may learn the innovations of two or three versions in one go. But to pity them is inappropriate, as any soldier of fortune does update his equipment and sharpens his knife – only FoxPro developers are fond of skipping one or two updates, thus missing out 3 to 5 years of evolution in a market where 5 years mean one generation. Of course it is true: Updating takes not only the update fee, but also a lot of time of getting used to the new thing. And why should one update an existing application when the direct benefit to the paying end user is not already apparent?. On the other hand, it is also true that learning in continuous small steps is better than not to update for years and then be forced to take a giant step which in many cases consumes more time than available in everyday work, ending up in a failure.
In this context Microsoft’s announcements are nearly as important as the multitude of practical technical extensions. For example
A sad thing is of course the general stop of the localization of the user interface and help file for German and Spanish (all other language supports have come to an end with version 6.0 or at the latest with 7.0, but nobody noticed that around here anyway). Therefore the following bits of information are helpful:
Putting together the German user interface, the help file of Visual FoxPro 7.0 (if you have got that one), and the update book for VFP 8.0, almost everything except for the Wizards exists in German. Therefore Microsoft ’s cost-cutting renunciation of a localization should have little effect on developers’ everyday work. As soon as the German documentation becomes available, this issue comes to an end anyway.
By the way: There might be an additional argument for you to update to Visual FoxPro 8.0 right now from Visual FoxPro 5.0 and 6.0 or Visual Studio 6.0 / 97. All these old and outdated versions are still allowed to upgrade for low cost and it might be for the last time you will be able to update for such low cost. You should prefer to upgrade old versions right away so you earn an additional year of learning experience (even if you do not use the new version in your production environment) while preserving your update rights for the upcoming version. Alternatively you can spend the money of two updates for one full version in about a year when you want to have the upcoming version Europa with its excellent report writer extensions that you need to have anyhow.
The advantages of Visual Extend
The framework Visual Extend has never left its FoxPro foundation, and we consider this fact an important reason for the success of the product. The summarizing marketing buzzwords have stayed unchanged for many versions, still hitting the nail on the head:
The existing versions of Visual Extend support the Visual FoxPro developer by means of the following tools:
These features successfully cover all standard areas of application development either purely in Visual FoxPro or as a 2-layer application with a back-end database (such as e.g. SQL Server or MSDE) according to the client/server principle. The efforts to implement a complete 3-layer architecture with a separated business logic have not been continued. The demands of this architecture and the level of necessary theoretical background knowledge for developing attractive applications in the area of small to medium businesses are much too high in most of the cases.
Apart from technical reasons there are some further heavyweight arguments in favor of Visual Extend:
Just for the reasons named above, in the German-speaking area more licenses of Visual Extend are sold than of all other suppliers of frameworks in total, and this has a very positive influence on the reliability of the further development and maintenance of the product, even though of course Visual Extend just like Visual FoxPro itself suffers a bit from the often weak willingness of the users to buy an update.
Even more advantages with Visual Extend 8.0
The current version of Visual Extend keeps moving in the same strategic direction that has made the earlier versions of FoxPro so popular, focusing on a stepwise evolution while keeping up backward compatibility as far as possible. The new version Visual Extend 8.0 brings about the largest update ever. The free intermediate release 7.1 did already guarantee the pure ability to run under the new version of Visual FoxPro, 8.0, thus relieving us of time pressure to ship as soon as possible due to the new FoxPro version. Therefore emphasis could be put on a general overhaul and essential extension in many areas. A brief overview of the most important ones among the new features:
The report designer always came in as the top issue when the dFPUG conducted big opinion polls about the demands on the new Visual FoxPro version 8.0. The new version of Visual Extend expands the report designer by PDF output and eMail output, and hence increases the utility of existing applications without additional labor. The menu designer came in second. It is also being addressed thoroughly and in an elegant manner in the new version .
Something had to be done about the look-and-feel also. Treeviews are state of the craft, and Windows XP has beautiful looks, but extended picklists and many other extensions of the user interface are naturally indispensable for the production of easily usable applications. In any case, here is also a large variety of possibilities not only to develop new applications faster, but also extend existing applications easily in order to offer a reworked release to customers.
As almost half of the professional developers work in the field of client/server computing as well, the database update feature has been extended for this area. For the others a function for data backup was added which is simple to integrate into one’s own application. It generates ZIP files without further license fees or installation hassle.
And for those who do not only develop in-house, but also offer their software on the free market, we now finally have a sensible solution for updating the application via the Internet, and also a product activation with individual rights for up to 32 modules by means of an activation key freely definable. This method is working well in the sales of Visual Extend itself. We therefore offer an extended variant of it to all developers.
The multilingual ability of Visual Extend has proved its worth, too. The international spread of its users show this. For that reason we offer this feature in an enlarged variant to all developers: The language support of the generated applications has been extended from hitherto German, English, French, Italian and Spanish by Greek, Bulgarian and Czech to 8 languages in total supported by the applications. Additional languages are soon to follow.
As with the Service Pack 1 for Visual FoxPro 8.0 we can announce a new build for Visual Extend 8.0 to. Yes, there were some bugs fixed but additionally we added the following capabilities:
The new build is available at the website http://www.visualextend.com for free download.
The next versions
For the next version of Visual FoxPro named Europa, a first list of new features has been disclosed for the second half of 2004; among others, you will find
The main emphasis of Visual FoxPro’s next version, apart from the important issue of the report generator, will be the cease of limitations in any respect and the increase of developers’ productivity. This improves the value of the product for the developer considerably without interfering with frameworks in any way whatsoever. And of course we can already draw up a list of the first ideas about Visual Extend, version 9.0, though not a definitive one:
If you have additional ideas and wishes please contact us in the newsgroup and send your ideas to Visual Extend as soon as possible.
As it will take some time until Visual FoxPro 9.0 is completed, we have looked for other areas of improvement meanwhile. That is, making further sample applications and ready-to-run solutions to be taken over into the developer’s own range of software, e.g. in the subject areas as follows:
However Visual FoxPro 9.0 and the corresponding version Visual Extend 9.0 lay some time ahead of us. So for the time being you should not worry about that, just be sure that the respective products are obviously under continuous development, and this fact can only be of benefit to you. That is the only thing such product previews shall demonstrate. And they shall prevent you from investing work in the development of features which you are going to receive in the following version anyway. So announcing the next version is useful, but under no circumstances shall it be an obstacle to working your way into the current version of Visual FoxPro and Visual Extend – and using them.
![]()
Errors with "Built In" Microsoft ActiveX Controls
Robert McNeal
Recently, I had a problem on some client computers where the MS ProgressBar control caused an error. The error message was "Class not registered for use." I included the mscomctl.ocx in my installation package and registered it properly, but the error persisted.
After several hours on the phone with MS Tech Support, the end result was that Visual FoxPro handles instantiation of ActiveX controls created through the CreateObject() Function differently than when the controls themselves are placed directly on the screen at design time. The error was the result of VFP attempting to create the "Developer’s Version" of the control rather than the run-time version.
This problem would disappear when the control was placed directly on the screen in the form designer at design time. While this is one approach to solving the problem, I prefer not to add ActiveX controls this way since, in my experience, the can become very "buggy" when any other version of the control is registered on the user’s computer. Instead, I prefer to use the version independent prog id (such as MsComCtlLib.ProgCtrl) to instantiate the control through CreateObject().
Since VFP tries to instantiate the "Developer’s Version" of the control and the license key(s) in the registry are not present, the control throws an exception. The only fix for this situation was to add the license key for the control to the user’s registry. License keys for most of the Microsoft ActiveX Controls are stored in HKEY_CLASSES_ROOT\Licenses. Microsoft tech support could not tell me which key was the one for the progress bar control, so we added all of the keys to the offending machine and deleted them one by one until the problem returned. I have 47 listed on my computer, but I have VFP 6, 7, and 8 installed, as well as VS 6 and .NET 2003. The ProgressBar control uses the registry key below, which you should be able to find on your development computer and export to a .reg file or include in an installation package.
[HKEY_CLASSES_ROOT\Licenses\ED4B87C4-9F76-11d1-8BF7-0000F8754DA1]
@="knlggnmntgggrninthpgmnngrhqhnnjnslsh"
This key appears to work for all of the controls in the mscomctl.ocx library, which include the ImageCombo, ImageList, ListView, ProgressBar, Slider, StatusBar, Toolbar and TreeView controls.
I finally built my own ProgressBar control in VFP using several shape controls in a container. The code should be available on the VFUG website in the file RMProgBar.zip, if anyone is interested.
Download RMProgBar.zip
![]()
Code your own Web Browser with Visual FoxPro 8
Grady McCue
Are you new to Visual FoxPro 8? Here’s another article that I hope will help to reduce your amateur VFP developer learning curve. This time, we are going to make our own web browser. Fortunately, the VFP programmers at Microsoft have done most of our work for us. So, let’s do this one in 10 easy steps.
1. Create a form.
2. In the INIT method of the form type:
This._Webbrowser41.Navigate('http://www.foxunc.dns2go.com')
Thisform.refresh
3. Close the INIT method
4. From the VFP Tools menu, open the Component gallery
5. Select ‘World Wide Web’
6. Select ‘Visual FoxPro’
7. Select ‘Internet Classes’
8. Click on and drag _Webbrowser41 onto the form
9. Drag open the _Webbrowser41 class to the viewing size you want
10. Save and run the form
The line -
This._Webbrowser41.Navigate('http://www.foxunc.dns2go.com')
contains the URL for my web site. You can put any URL you want into it. Or, you may want to pass a URL to a variable in the Navigate method.
As you saw, this is a very basic web page, but if you look in the Solution sample that comes with Microsoft Visual FoxPr0 8.0 you will find a web browser example. When you study it, you will learn how to add navigation buttons and an address bar to the form. With a little imagination you can make it very eye appealing.
Grady is an independent VFP developer who has worked for EDM, ATB and IBM Canada.
He has owned and used all the Fox db products since FoxBase 1.0 and knows MVS
systems including COBOL etc.
![]()
Brett Carraway
Geek If
this image offends you, you probably should not use FoxHound!
FoxHound is a native source control alternative for VFP. It is compiled in VFP6. It has been developed in small increments for over a decade. I have used FoxHound off and on over the years and just recently made some major refinements so that I could begin to share it with other developers.
I feel FoxHound is a good alternative to VSS having used it to great extent. There are some benefits over VSS (mentioned below). FoxHound is not a polished product by any means. FoxHound is not an enterprise source control solution, at least, in its current state. So if you are a stickler for perfection who does not have a sense of humor, please don't use FoxHound. In spite of its easy-going user interface, FoxHound has served me well and I am hopeful it will do the same for other VFP developers.
If you are not using source control, or are frustrated with the one you are using, I encourage you to give FoxHound a try. You may contact me at Carr2649@bellsouth.net for help and to provide feedback (please). I am anxious to see if FoxHound works as well for others as it does for me. Plus, if enough developers start using it, I will have incentive to do some of the major improvements I have been neglecting to do (like history tracking and retrieval).
Note that while some of the following documentation may be somewhat out-of-date, it will still provide the general information needed to start using FoxHound.
How Does It Werk (spelling intended) <g>
FoxHound allows a development team to store a master copy of a FoxPro project on a shared, network drive. This copy is the shared code base for all updates to the source code. The network location for a FoxPro project under source control may be referred to as the repository.
A FoxHound database is created when one selects the repository project copy during the add-project-to-source-control procedure (outlined below). This FoxHound database resides with the repository copy of the project in a subfolder of the project named FoxHoundData.
A memory file is added to the local development and repository copies of the
project. This memory file (lovingly named "FoxHoundDroppings") lets
the local project know where to find the repository (when the network is visible).
Check out / in Processes
When a file is checked out / in, the following takes place.
I refer to a FoxPro project which is under FoxHound source control as "a
FoxHounded project" in this document.
There are future plans to create a local FoxHound databases; that is, FoxHound
databases which reside with the developer's copy of the project; not just the
repository copy. This would facilitate working while disconnected from the network
(tentative check-ins ...). Also, I would like to add better history tracking
and retrieval. Hearing that someone else would use such enhancements may inspire
me to do it.
Some Benefits of Using FoxHound Source Control
Note that not all differences are currently detected. Such as new, empty form methods and some differences are reported in error.
FoxHound has been tested under the following conditions
In other words, one cannot have project components which exist at paths other than the project path (except for having relative paths). FoxHound may still be used for other project elements which do reside under the project folder; however, any project components which do not reside under the project folder and are not on a relative path on the same drive will not be FoxHounded. Note that project files with relative paths to the project folder may be FoxHounded.
Currently, FoxHound will only work for one project in any project folder.
Acknowledgements
I would like to thank Steven Black for his public domain MsgSvc which I have used to provide the Geek dialogue throughout!

I would also like to thank others like Drew Speedie for inspiring me through his source code (I have developed using Visual MaxFrame by Drew Speedie) and Gary DeWitt for inspiring me to do more.
Brett Carraway is a dedicated FoxPro developer since FoxPro 2.0 (DOS). Brett has worked on a variety of applications such as billing, manufacturing, real estate and fire department records management. Currently, he works for Kemper Auto & Home; a UNITRIN company as a Senior Business System Analyst developing custom applications for the underwriting department.
Editor's Note: The download file, FoxHound.zip, contains the "How to Use FoxHound Source Control" document, with complete directions for setting up and using FoxHound. Only the application description has been printed here.
Brett Carraway
Geek
Download FoxHound.zip
![]()
Wireless Devices, Part 12: Microsoft Does Bluetooth!
Tom O'Hare
Microsoft (MS) has finally embraced the Bluetooth (BT) technology as evidenced by its latest line of PC accessories. MS had pledged support for BT for some time but it took longer then I suspected for them to get fully into it. But it was with great cheer that I discovered MS went way beyond the obvious with their new BT enabled Keyboard & Mouse product.
This article is not about keyboards and mice. It is more about the extras that encompass the technology that makes the BT devices work, and work well beyond just keyboards and mice.
(Writer’s Note: In the simplest terms Bluetooth is an advanced wireless technology. For more background on the Bluetooth technology, search the VFUG.Org web site newsletter archives to see some of my past articles that expand on Bluetooth wireless technology and what it is capable of).
They key to the MS BT accessory is a BT USB (Universal Serial Bus) attachment that can nicely fit into a USB slot on a notebook PC either directly or via an included long cable extension. This is a BT transmitter (TX) and receiver (RX) in a single package.
After installing the MS software and "pairing" the MS Keyboard & Mouse to my laptop I decided to see just how far I could go with the new MS BT hardware. Or more specifically, how far could I go with the BT TX/RX device.
Using Win XP Pro, and then going to the Control Panel (CP), I now see a "Wireless Link" selection. Opening this selection now displays dialog with BT devices and drivers on separate tabs.
This next part is beyond the scope of this article, but in short, using this new dialog in the CP I was also able to pair my Sony Ericsson P900 BT enabled cell phone to the MS BT adapter attached to the laptop. What this means is that when I am finished with this article I am writing at the "Blue Zoo" restaurant in the Walt Disney Dolphin Hotel (Orlando), I will transmit it to California over the Internet via my cell phone’s GPRS (General Packet Radio Service) Internet connection where it will be edited and posted on the VFUG.Org web site. From the time I finish this article until it arrives in California will only take several minutes and require "no wires". In other words, this document will be attached to an email, and then transmitted via the MS BT adapter to the cell phone. From there the GPRS connection will hook into the AT&T Internet backbone and deliver the email, with document attached, via the Internet. Now that is cool, totally wireless and without the need for extra hardware. A road warrior’s dream comes true!
And a special thanks to Tanya, the bar manager, for putting up with my PC antics…
Editor's Note: Tom was sending the article to me at my home in California - I read it while he was still at the "Blue Zoo", and could have sent it back to him the same way if I'd needed any changes. This is an editor's dream as well as the road warrior's.
![]()
What's New for Spanish VFUG Members
Isaac Venegas
VFP 8 Spanish HELP File
After starting on October 20, 2003 with the translation to Spanish of Visual FoxPro 8, PortalFox release the Help for Visual FoxPro 8 on January 5, 2004.
This project has been accomplished thanks to the collaboration of 59 Volunteers from the PortalFox Community and the dedication to translation, review and coordination of all the assigned tasks.
To download the Spanish Help for Visual FoxPro 8 get the ZIP File and Here for RAR File
The translation took 3068 hours and was completed in only 3 months. The people leading the work included:
| Pablo Roca | Spain |
| Ana Maria Bisbe York | Cuba |
| German Giraldo | Colombia |
| Rafael Bilbao Aragonés | Spain |
| Edhin Jiménez | Venezuela |
Plus many others. (Complete list of translators)
For Information (Spanish) about this project and also for more release news, see the Spanish IDE web page
SysOp Chat y Relaciones Publicas Para Noticias usando VFP con Web Services:
![]()
Resources for German VFUG Members
Rainer Becker
Details regarding the German DevCon (including German and French IDE for VFP8) can be found in the portal of the German usergroup as well as in the complete online coverage of the event.
| German FoxPro User Group |
The dFPUG supports 800+ companies in Germany, Austria and Switzerland with a quarterly magazine, regional meetings in a dozen cities, a wellknown yearly conference and a lot of online material. |
| dFPUG Newsgroup | dFPUG Newsgroups on a number of topics from VFP9 to Clipper |
| dFPUG Wiki | Interactive Wiki |
| dFPUG Interactive Forum | Interactive Forum |
| dFPUG Portal | German SharePoint Portal for Visual FoxPro (http://portal.dfpug.de/dfpug)
with the conference binders of the yearly German VFP Developer conference
(800 pages 1994-2002) and the quarterly loose-leaf-magazine FoxX Professional
(200 pages per issue). Use category "English" as starting point
for english material related to Visual FoxPro. |
| dFPUG Newsletter | The newest offer is an electronic newsletter, which is published every 4-6 weeks with actual information e.g. about the next German VFP DevCon (http://devcon.dfpug.de), changes in the VFX-framework (http://www.visualextend.com) or regarding localization for VFP 8.0 done by dFPUG. |
![]()
I strongly urge you to go to at least one of these. Pick the one closest to your home to reduce travel time. Pick the one where you can understand the speakers' language. But argue your boss into letting you have the time off to attend one at least every 2 years. You'll be glad you did.
Send me an email to add yours to the list. Please include a URL and contact name/email if possible.
Report Writing Boot Camp January 24, 2004 in Los Angeles, California. Presented by the Los Angeles Visual FoxPro Developers Group. Cathy Pountney will teach this all-day class, and a copy of her book The Visual FoxPro Report Writer: Pushing it to the Limit and Beyond will be included as part of the admission fee.
Essential Fox 2004 June 4 - 7, 2004 in Kansas City, Missouri. Ken Levy will deliver the keynote address to kick off the Essential Fox Conference with VFP 8.0, previews of Europa (next version of Visual FoxPro), Whidbey (next version of Visual Studio), and other news and great demos!
Advisor DevCon September 29 - October 4, 2004 in Las Vegas NV. More details soon.
Tell me what others to list!
![]()
By the Editor
|
Microsoft |
|
|
Microsoft |
|
|
MSDN |
|
| Microsoft Visual FoxPro Bug Report | Microsoft |
| Visual FoxPro OLE DB Provider | Microsoft |
| Microsoft | |
|
Task Pane |
|
| Developer Tools - Check out these VFP tools (many are VFP8 only) | Kirtland Software |
| Visual FoxPro Coding Standards | Craig Berntson |
| Integrating Crystal Reports with Visual FoxPro | Craig Berntson |
| Cross Tab generator - gsXtab1 - An alternative to VFPXTAB | WinnerSoft |
.NET, Microsoft KnowledgeBase and Other Links
| Blaster Worm Removal Tool for Windows XP and Windows 2000 | Microsoft Downloads |
| Working with Microsoft Office Word 2003's XML | DevX |
| Microsoft
extends Windows 98, ME support to 2006 |
ComputerWorld |
| Avoid sending deleted text along with your docs | TechRepublic |
| XML Data in SQL Server "Yukon" | Developer.com |
| Outlook 2003 Add-in: Personal Folders Backup | Microsoft Downloads |
| Security enhancements in Microsoft Windows XP Service Pack 2 | Knowledgebase |
| MS Office Templates (updated) | MS Office Online |
| PowerPoint Templates Pack 1 | Microsoft Downloads |
| Office 2003 XML Reference Schemas | Microsoft Downloads |
| What
You Need to Know About Microsoft Office InfoPath 2003 |
WinNetMag |
| A
Solution for Windows XP Folder Amnesia? |
PCMag |
| How to open Acrobat quicker: | PlanetPDF |
Hardware, Software and Operating Systems
| Decision Support: A virus-protection chart - compares many virus-prevention products. | TechRepublic (requires free login) |
| Microsoft Getting a Bigger Slice of Database Pie | eWeek |
| Cool USB Key Locks Your PC | eWeek |
| Flash Remoting a new way to use Macromedia's Flash |
PCMag |
| Protection Bypass Vulnerability in Microsoft Word | WinNetMag |
| State of Alaska saves 10 percent on mainframe software - Even if you aren't buying software for your entire state there's some good ideas here. | TechRepublic |
| The seven habits of wildly unsuccessful CIOs - Problems all of us have seen (and some of us do) | TechRepublic |
| Clear the Clogs - Printer heads, that is.... | PCMag |
| DCOMbobulator
- Effortlessly Tame Windows Dangerous DCOM Facility |
GRC Software |
| Ultimate Data Destruction - Cleaning old hard drives for reuse or disposal | TechTV |
| Understanding
SQL Server 2000 Locking |
DatabaseJournal |
| Tracking e-mail -- who sent you that e-mail? - A tutorial on email headers | VisualWare |
| Software glitch brings Y2K deja vu | MSN-Cnet |
Web Services, XML, HTML and Other Internet Items
| Tracking
the seeds of destruction - Internet viruses have something in common
with plant diseases |
ZDNet |
| Critical steps for Web services | ZDNet |
| Phishing: Spam that can’t be ignored | ZDNet |
| XML Volumes Increase Dramatically, but EDI Dominates Networked Supply Chain | ZDNet |
| The Social Life of XML - Why does XML have a better social life than I do? | XML.COM |
| Getting the best speeds from a dial-up connection | TechRepublic |
| Alabama workers clock in with their fingerprints | The Register |
| Ultimate Utility Guide - Some free, some not. | PCMag |
| Which apps should you migrate to .NET? They're talking VB, but they do have some good generic ideas. | TechTarget |
| Switching between Virtual Java Machines - Microsoft or Sun | Java.com |
| Dog Tracks Deceased Pal to Funeral Home | Chicago Tribune (requires free login) |
| Patented: Germ-zapping mailbox | CNN Money |
| Electronic Product Code - Do we REALLY want to know all this? And what will this technology do to our personal privacy? | Baseline Mag |
| Lilliputian
Levitation |
PCMag |
| Mars, Iran, Peru and many others - views from space | Space.com |
| Cool Tool Kit - turn that old refrigerator into a tool kit (or at least make it LOOK like one) | PWMEnterprises |
![]()
By the Membership
Append Command Ignores Default Values
Q: I have a table in a VFP7 database which has a few fields that have default value settings in the DBC. I'm trying to append data from a delimited text file into this table. I want the database to fill in the two fields with default value settings, so I'm specifying the fields I want the data to be imported into in my APPEND FROM statement.
But for some reason, VFP isn't populating the two "default value"
fields for me and my triggers fail (because I restrict INSERTS on this table
via RI and both of these "default value" fields together comprise
my primary key). I proved this behavior by creating a small table in my database
with two
fields defined with default values and two without. I created a test import
file with two rows and when I appended the file, the two "default value"
fields remained empty!
Why isn't VFP populating my default value fields if I'm *not* specifying those fields in my APPEND FROM command?
A: You cannot do this with a delimited file. Append the data into a VFP table, then make sure that the fields you want for you default values DO NOT EXIST in the temp table. Your append into the real table will then get the defaults.
Robert McNeal (from the VFUG ListServe)
![]()
Last year, I spent a lot of time developing a picture treatment dll, there are
6 functions in this dll:
1 formtobmp
2 formtobmpA
3 tojpeg
4 tobmp
5 getbmpdimension
6 getjpgdimension
Anybody who would like to have the source code for this dll, please email to njjane@21cn.com (the dll is written in C++, not VFP).
Editor's Note: The pct_dll.zip file contains a readme.txt file with complete descriptions of each function, required parameters and directions for implementation plus VFP examples.
http://www.myf1.net/foxcryptor/
![]()
After installing VFP 8 onto my Windows 2000 machine, whilst keeping both VFP 6 and VFP 7 installed as well, I noticed that when testing a web site locally I was getting errors that did not appear when testing the site on the internet.
The difference in the environments was simply that the internet server had the VFP 7 OLE DB Provider installed and my machine now had the VFP 8 OLE DB provider installed and VFP 8 itself of course.
I thought that this problem could easily be overcome by simply renaming the VFP 8 OLE DB provider dll and reinstating the VFP 7 OLE DB provider dll into the 'C:\Program Files\Common\System\OLEDB\' folder on my machine.
Unfortunately this did not overcome the problem.
The errors that I was getting were in the main explained in the supporting MS Word Document that is available from the Microsoft FoxPro Developer area: Microsoft OLE DB Provider for Visual FoxPro 8.0At least this offered a clue about where the new SQL errors were originating from but it did not explain why I was now seeing 'Feature not available' errors when I was calling a stored procedure in the database that had SQL INSERT INTO statements embedded within it. Keep in mind that this code works perfectly in a VFP 7 Internet Server environment
I followed the advice of the article and placed a config.fpw text file in the 'C:\Program Files\Common\System\OLEDB\' folder on my machine that contained these two lines of code:
TABLEVALIDATE=0
ENGINEBEHAVIOR=70
This immediately stopped the SQL errors that were being generated due the difference in the GROUP BY clause syntax for VFP 8, but still left me with the 'Feature not available' errors.
I tried numerous other bits and bobs to overcome the problem but as they did nothing to correct it I will not mention those things here as it would only confuse an already very confusing situation.
Then I stumbled upon another area that might be causing the problem, namely file association on my machine!
When I looked at the database file association it pointed to VFP 8 and so I tried changing this to VFP 7 for the .dbc, .dct and .dcx files. This little change made all of the 'Feature not available' errors disappear immediately and I was able to run the web site locally exactly as though it was running live even though my machine had VFP installed.
Obviously if the internet server updates to VFP 8 then all of these problems will raise their heads again but then I should be able to recode the web pages to call the stored procedures in a slightly different way and also recode any offending SQL on the VFP side of things to correct the problems there.
So in summary it is possible to still simulate a VFP 7 environment on a machine with VFP 8 installed when utilising the new VFP 8 OLE DB Provider if you make these small adjustments to your system.
I have tested VFP 8 itself running normal VFP 8 apps on this altered machine and their are no side effects that I can see.
![]()
Dates and DateTime in a SQL-Select
Q: I recently changed the properties on some SQL views so that they would display dates instead of datetimes. Now this union made for a print job will not work:
select * from vwmd, vwmdgrp INTO cursor mdboog ;
where vwmd.mdnum=vwmdgrp.mdnum ;
UNION select mdnum, mdlast, mdfirst, mdaddr1, mdaddr2, mdcity, ;
{ / / :AM}, { / / :AM};
from vwmd where mdnum not IN;
(select mdnum from vwmdgrp)
saying "SELECT are not union compatible" i believe the blank datetime is to blame. how do i change the ,{ / / :AM},{ / / :AM}; to reflect the date component, or is that the problem?
A: Try one of these three:
William Sanders (from the VFUG ListServe)
![]()
Does a Field Exist (Continued)
Last month we showed you two ways of discovering if a field exists in a specific table. Joe and Robert each sent us a third method using FSize():
llFieldExists = FSIZE("FIELDNAME") > 0
Joe Gonzalez and Robert McNeal
![]()
Where is the Windows Directory (Continued)
Last month we showed you how to find the Windows Directory, and Arto sent us another method:
Maybe this is the easiest one
?ADDBS(JUSTPATH(FULLPATH("WIN.INI")))
or if you want to avoid returning HOME() if WIN.INI is not found then the next
one
?IIF(FULLPATH("WIN.INI")#HOME(),ADDBS(JUSTPATH(FULLPATH("WIN.INI"))),"")
![]()
Position a Right-Click Popup Menu
Q: In my text entry controls, I have some code in the RightClick event that displays a shortcut menu with editing functions (Cut, Copy, Paste, et al. I think all that's in a past newsletter). I thought it would be cool to utilize the context key that's on most keyboards now (next to the Windows button). I determined the keycode is 93 (which is actually Shift+F10). I check for that code in my KeyPress event and then call the RightClick event with a parameter. What I'm trying to do is display the popup menu right below the control. I use MCOL() and MROW() normally, but in this case, the mouse could be far away from the control and it would look silly for this popup menu to show up in an arbitrary location.
I tried DEFINE POPUP shortcut SHORTCUT RELATIVE FROM this.Top+this.Height,this.Left MARGIN, but that's not right because Top and Left aren't the correct representation of the actual corrdinates of the object (in terms of the big picture).
So, the actual question is, how can I determine the coordinates to use that correspond to the lower-left of an object?
I think I've determined that it's a pixels vs foxels issue. I believe the menu coordinates are in terms of foxels whereas "Left" and "Top" values are in pixels (unless the scalemode is set to 0-foxels on the form).
A (part 1): (Carl Warner) How to Convert Screen Object Positions Between Platforms
A (part 2): (Robert McNeal) Take a look at the ObjToClient() function.
It determines a size or position of a control relative to the form.
Steve's final code with his comments:
lnRow = (OBJTOCLIENT(this, 1)+this.Height)/FONTMETRIC(1) lnCol = OBJTOCLIENT(this, 2)/FONTMETRIC(6) DEFINE POPUP shortcut SHORTCUT RELATIVE FROM lnRow, lnCol MARGIN
That will put my popup directly below my textbox/spinner/editbox when I tap
the context menu button on my keyboard. Note I had to convert the result of
OBJTOCLIENT to foxels using the knowledge I gained from the KB article Carl
sent before.
Robert McNeal and Carl Warner (from the VFUG ListServe)
![]()
1. EMail: some email client packages do not allow email "Headers only" as an email checking option. If using both a cell phone/PDA and a laptop PC, it may be better to check the email first with your cell phone or other mobile device. The reason is that most mobile devices that have email capability allow you to download "Headers Only". With the email headers only on your mobile device, you can more efficiently get a preview of your email and delete the mail that is not desired, leaving only what you need. Then you can connect your laptop via your cell phone (as a modem or other type of Internet interface) and download the entire email to your laptop. Obviously working with a laptop is easier then a mobile device when it comes to ease of use (i.e.: screen size). Plus laptops have additional storage space to save emails that need to be kept.
2. Internet vs. WAP connection: If your mobile device supports the abilities
to be both an Internet connection (like a wireless modem) and a WAP connection
(connect via your carriers service) then this is worth noting.
Many mobile devices do not allow both an Internet connection and a simultaneous
WAP account connection. Be sure to first disable one or the other depending
on your needs. A WAP connection is better for checking email with your mobile
device. The "Internet connection" supports using your mobile device
as a type of modem for a laptop connection to the Internet. Which one you use
depends on your needs at the time. But don't be surprised if you see "Access
Denied" or similar messages. This very well can mean your mobile device
is already connected as one of the above mentioned methods while you try to
connect via a second method.
3. If checking email (For example) and during the update from the server you receive "corrupt data", or similar message, the problem may not be your own server. In wireless environments, such as cell phone devices, the carrier (or service provider) almost always uses a Proxy type server between you and your physical server where your actual data resides. What usually causes this error is the proxy server cache somehow becomes corrupted. Unless your provider gives you some sort of cache clearing mechanism, you may have to postpone your data session. Until the proxy cache is "clean" again, the corruption will continue to interfere with you receiving valid data. If no cache clearing mechanism exists, you will most likely have to wait until either your physical location changes or a timeout occurs. The trick is to just wait until either the life of the data cache times out, and clears itself, or you move to a location serviced by a different proxy server. Only then may you finally be able to communicate with your own server again.
![]()
I am using a "brick" case for a server (very small case). Motherboard
temperature was high on both servers (same cases) and beyond the default limit
(~120 F). I reversed the direction of the chassis fan to blow "in"
instead of "out" and the motherboard temperature has dropped 30F -
40F, well below the normal limit...
![]()
Some final comments....
Coming Soon: More articles by
Generally, regular CHAT sessions are held every Thursday. For more information on scheduled chat sessions here at VFUG, contact John Chambers or check the VFUG newsgroup out for current info.
Want to be (in)famous? All you have to do is send VFUG an article, tip or otherwise useful item. We are happy to publish most Fox related tidbits, and you can help your fellow developers worldwide!
VFUG is also always looking for additions to our Vendor program. Would your company be interested? Contact Carl Warner to get with it. Also, if you are interested in your company placing a banner advertisement on our home page, please contact Carl.
![]()
|
|