GLR
 Software web site
2/6/2012
Visitor: 126156


 Home
 LifeCycle utilities
     Build
     FUnit

 Articles
 Links & Resources
 Tips and Tricks
 User Comments

 Free Downloads

 About Us
 Pictures
 My Blog
 Contact Information
 Email Us
 Fun Stuff
 Email a Friend
 Google Analytics

 Add to Favorites
 Printer Friendly

  Updated since last visited.
Fox with Sheep


Tips and Tricks


If you have any tips or tricks that you would like to share with others, or know of any web pages that express any, please send to me (Greg Reichert). Start the subject line with TIPS:. This will help identify your suggestion from all the other email I receive.


Content

11/2/06 Clicking a button while a loop is running
9/5/06 Late-binding of an object
1/16/00 Closing tables in correct order with AUSED()
11/10/99 Controlling the CENTURY ROLLOVER dynamically
11/3/99 VFP reports are printer specific.
6/30/99 In FRX, the paths to images are saved as absolute paths.
6/12/99 Slow form refresh with many controls
6/12/99 Non-READ EVENTS event loop.

Clicking a button while a loop is running


VFP 8.0+

It was asked on the UT; How can I click a botton to stop a loop process while the process is running? If the following code is placed inside the loop, it will make the appearance that the Stop button is being clicked.

*...
lnKey = INKEY(0.01, "MH")
IF lnKey=151
    loObj = SYS(1270)
    IF lower(loObj.Name) = "cmdStop"
        loObj.Click()
    ENDIF
ENDIF
*...

&& Check for Mouse click
&& User click the left mouse button
&& What object is the mouse over?
&& the Mouse id over the Stop button
&& Fire the click event.
Top

Late binding of objects


VFP 6.0+

After seeing the “My” object introduced to VFP 9.0, I decided to write a similar object for accessing many of the functions of FoxPro and windows called System.prg. In my first attempt, I encapsulated the FoxPro functions of SYS() and SET() to allow better readability. For example, Instead of the coding as SYS(3), the object version would be oSystem.UniqueName(). This helps make my coding more understandable. Well, after a while, I added other FoxPro functions like HOME, OS, VERSION, and etc. As the number of methods grew, so did the object. After a while, the time it took to instantiate the object grew also. Now recent I added methods that accessed the operating system using Win API and WMI queries. This was cool, but it was adding several seconds to the start up of my application. Something had to done to speed up the creation of the objects. The solution was not to create the individual object until they are accessed for the first time. The following snippet of code demonstrates how this is done.

loObject = CREATEOBJECT("MainClass")
? loObject.FirstObject.FirstMethod()

DEFINE CLASS MainClass as Container

    FirstObject = .NULL.

    PROCEDURE FirstObject_access
        this.FirstObject = IIF(ISNULL(this.FirstObject), ;
            CREATEOBJECT("FirstClass"), this.FirstObject)
        RETURN this.FirstObject
    ENDPROC

ENDDEFINE

DEFINE CLASS FirstClass as Container

    PROCEDURE FirstMethod
        RETURN "Hello World"
    ENDPROC

ENDDEFINE

If we step through using the debugger, you will notice that after loObject is created, the property FirstObject is NULL. But when execute the second line in attempt to call FirstMethod, the FirstObject_Access method is called first, therefore creating the object for first. Then the method FirstMethod called afterwards. With several dozen obj4ects, and hundreds of methods, this means of delaying the creation of the object until they are needed speeded up the startup of the application.

You can download the latest copy of this class here

Top


A Read Event loop without a READ EVENTS statement.


VFP 3.0,5.0,6.0

Sometimes we need to set a form up as the base form to a event loop, but we already have established a READ EVENTS statement. Well DOEVENTS to the rescue. Placing a DOEVENTS in a DO WHILE loop simulate the READ EVENTS statement. The _Exit variable controls the final exit of the loop. The last form sets it to .T. when it closes.

DO FORM ...
...
Private _Exit
DO WHILE NOT _Exit
    DOEVENTS
ENDDO

Top

Are your form refreshing to slow.


VFP 6.0 only

A colleague of mine purposed a problem he was having. The problem was that on his form (entire application), when he clicked a button or list box item, the highlighting of the selection was taking forever. First, his form had multiple page frames, and dozens (I mean DOZENS) of controls. I discovered that the FORM.PAINT event was being called when they were being clicked. Therefore, I suggested, and it worked, placing a NODEFAULT in the form's PAINT event.

Top

In FRX, the paths to images are saved as absolute paths.


all versions

I have noticed that if I place a image on a FRX report form, that when I save the report form the otherwise relative path to the image is resolved to an absolute path. Often my clients would like to see their logo on the header of there reports. Therefore, the image file needs to be external to the application, where they can modify it. But if the report form has an absolute reference to its location, it is difficult to alter it final location (naming anywhere on the SET PATH path). The solution I have found is to strip the path from this image reference when I perform my automated build.

UPDATE some.FRX ;
SET PICTURE = ["]+JUSTFNAME( ALLTRIM( EVALUATE( PICTURE )))+["] ;
WHERE ObjType = 17

Top

VFP reports are printer specific.


All VFP versions
Contributor: Gary Vollard, Parity Corporation.

"I have noticed on reports we have converted to VFP that they can behave differently on various printers. During the conversion process, we had to resize the fields to make sure that the data did not get truncated. Okay, fine. At the time, we used an HP LJ 4 as our test printer. After all this is said and done, we determined the field sizes for certain data types, which helped us speed up the conversion process. Unfortunately, it turns out that determining the field sizes did not prove to be a "universal" solution. The converted landscape reports, when run to the Panasonic KX-P2023 printer, are truncating the last digit of date fields. Many of our reports are very "tight" for space, so you can't rectify the problem by merely creating a utility program that increases field sizes in the .FRX
I called MS support, and explain the problem. Their tech. was able to recreate the problem by creating a simple VFP report from scratch. His conclusion was that the FoxPro report writer is "printer specific". They will document this problem in a white paper.
To increase your chances of success when FoxPro reports hit the field, make your field sizes bigger than absolutely necessary. Page margins are not handled well, either. Best bet is to implement a page margin of at least 0.20" when designing a report, so the data won't get chopped off on the left margin."

Top

Controlling the CENTURY ROLLOVER dynamically


VFP 5.0, 6.0
The Y2K issue is not only a problem now, but also when our application are running in the 21 Century.  For example, if a user enters a birth date of 6/10/60, the system should assume 1960, not 2060.  But if they enter a birth date for new baby born on 6/10/01, it should assume 2001, and not 1901.  VFP 5.0 and 6.0 have a ROLLOVER clause on the SET CENTURY statement to control this, but the value applied is the year the rollover occurs, and not the number of years into the future it should apply.  The following line resolves this oversight.  It keeps the rollover, in this case, ten (10) years beyond the current year.

#DEFINE kCentury 10
SET CENTURY TO 19 ROLLOVER MAX(0,(YEAR(DATE())+kCentury)-2000)


Top

Closing tables in correct order with AUSED()


VFP 5.0, 6.0
The AUSED() function build the array of open tables and views in the reverse order they were opened.  This can be very helpful when it comes time to close all open tables.   Another example I use is closing only tables and views that were open within a specific procedure.

PROCEDURE MyProc
LOCAL ARRAY laOpen [1,1]
=AUSED( laOpen )
...
* Perform procedure
...
LOCAL ARRAY laClose[1,1]
FOR x=1 TO AUSED( laClosed )
    IF ASCAN( laOpen, laClosed[x,1])=0
        USE IN (laClosed[x,1])
    ENDIF
NEXT

 


Style:

Quote of the Day:
You will always get a minimum amount of work for your minimum wage.

Favorite Sites
Univeral Thread
FoxForum
Foxite
Visual FoxPro Wiki
Fox Central
Hentzenwerke Publishing
Microsoft Visual FoxPro
Leafe
VFPx CodePlex
FoxLANWeb

Universal Thread







© 2003-2012   GLR Software - Gregory Lynn Reichert.    All rights reserved.