2007-05May-18
Navigation to the webpage was canceled
When you download a CHM file or a ZIP archive containing a CHM file with IE 7, you get an error message when you try to open the help file. The message is "Navigation to the webpage was canceled" or "Dieses Programm kann die Webseite nicht anzeigen." on a German OS. This error message is part of Microsoft's attempt to make Windows more secure. After all, if you don't read the help files, you don't know all the variations of damaging your system.
To fix this, navigate to the folder that contains the file. Right click and choose properties. On the properties dialog there's an option to unblock the file:
Afterwards the help file can be opened. If you are testing Guineu, please perform these steps for the ZIP file.
2005-05May-18
Resolution of SECONDS()
On Win 9.x SECONDS() has a resolution of 1 ms. On NT based systems, SECONDS() changes every 10 ms, as you can see
with the following program:
For t=1 to 100
? Seconds()
endfor
On NT you can change the resolution for SECONDS() using the timeBeginPeriod API function:
Declare long timeBeginPeriod in WinMM.dll long
timeBeginPeriod(1)
Now SECONDS() increments every millisecond:
For t=1 to 100
? Seconds()
EndFor
2007-05May-18
Secure error handling
Recently I reviewed a Visual FoxPro application for security issues. This application was using a popular file encryption DLL to transparently encrypt all tables. That's actually a good thing because unencrypted DBF files allow hackers to inject code into a VFP application. Breaking encryption algorithms is a futile exercise for all standard encryption algorithms.
Yet, it was very easy to decrypt all files, because this particular application wasn't protecting the start up process properly. What I did was to rename the encryption DLL. The application failed with an error message, because it couldn't load the DLL. Unfortunately, the error dialog was one of the standard dialogs that offer Cancel and Ignore. After hitting ignore, the next error message was something like "Crypt_Register.PRG not found".
The DLL that defined this function hasn't been loaded. When Visual FoxPro resolves a procedure name, at last it looks for an external PRG file in the current directory. Being equipped with the name of the procedure, I created a small PRG file that merely receives a number of parameters and displays each parameter in a message box. After copying the PRG to the program directory, I launched the application again. Sure enough, one of the parameters was the password.
The lesson to learn from this is that you should never allow the user to continue after an error occurred, unless you can guarantee that the program returns to a safe point. There usually is no such point until you reached READ EVENTS. If an error happens before you got to the READ EVENTS, terminate the application immediately.
2007-05May-16
Optimal slow
Optimizing queries in Visual FoxPro is often attributed with increasing speed. Years ago we've seen with the discussion about an index on DELETED() that this is not a universal rule. Optimizing queries can be quite a tricky thing. Here's a situation to think about. You have two tables A and B. The query returns all records from A and about half the records of B:
SELECT * FROM A ;
JOIN B ON A.PK = B.FK ;
WHERE SomeCondition.
SomeCondition is not optimized. So you think about optimizing the query by creating necessary indexes. Congratulations! You successfully reduced the amount of data that had to be transferred across the network.. and slowed down the query at the same time.
What seems to be an oxymoron at first is easily explained. When Visual FoxPro reads records in a loop, it never reads single records but a block of records. In the first case, Visual FoxPro has to scan sequentially through table B reading like a dozen of records with each read operation.
When you optimize the query, Visual FoxPro creates a map of hits. If there's one miss in a dozen hits, Visual FoxPro has to split the single read request of 12 records into two read requests of five and six records. The more records you filter out, the more fragments you have to read. In the end, you might end up with only 50% of the records, but require 600% percent more read operations to retrieve them.
Read operations across a network are expensive. They frequently map to a single network packet. Every additional packet adds overhead for protocol headers, adds delay due to network latency and adds workload to the network for routing and filtering packets. Congratulations!
2007-05May-16
SET PATH oddities
Without testing this code in the Command Window, can you say what paths Visual FoxPro searches for each of the following SET PATH statements?
SET PATH TO "111,222",333
SET PATH TO 111;"222,333"
SET PATH TO 111, 222 333
The path statement is a little inconsistent. There are some easy rules to follow, though. Everything following TO is treated as a single string. The only exception is if the string starts with a quotation mark. In this case, SET PATH only reads until it encounters the terminating quotation mark and ignores the remainder of the string. Parsing happens strictly on the two delimiting characters comma and semicolon.
With this in mind here's what directories VFP searches for each variation:
1) The last directory is ignored, since VFP only reads until the terminating quotation mark that follows 222.
.\111
.\222
2) 222 and 333 are parsed separately. You cannot specify a directory that has a comma in the name. Note that the last two directory names each contain one quote which renders the path invalid.
.\111
.\"222
.\333"
3) If you have a path with a blank you should not use quotes. Visual FoxPro keeps spaces in the name. It removes, however, blanks at the beginning and the end.
.\111
.\222 333
2007-05May-04
The current state of Guineu
I've been pretty busy in the past months which kept me from reporting on Guineu's progress. Since November I added the object engine, implemented a number of base classes and started working on the data engine. I also added several functions and commands. The entire feature set is still very basic compared to what Visual FoxPro offers, but it's sufficient to write working applications.
As a demo application I wrote a small inventory form. A user can enter a barcode (by hand or by scanning) and specify a quantity. Both values are added to a text file. Here's what the form looks like in VFP 9:

This is what the same form looks like using the Guineu runtime for Windows desktops. Guineu automatically translates the FoxPro form into a .NET WinForm. The form is fully working:

As Guineu is compatible with the .NET Compact Framework, I also have a runtime for PDAs. To run FoxPro code on the PDA, you copy the Guineu runtime files and your FXP files onto the PDA, that's it. Here's what the same form looks like on a PDA:

Right now Guineu is completely written in managed code. There's no VFP COM server involved, nor does Guineu rely on a Windows DLL. For this reason, you can run Guineu on Mono. Here's what the FoxPro form looks like on Suse Linux 10.0:

It's not as pretty, but still fully working. If you are interested in testing Guineu, just drop me a mail at guineu-beta@foxpert.com.