Foxpert Software Development & Consulting

Menu

Whitepapers
Downloads
Knowlbits
Guineu

2008-04Apr-28

REPLACE FOR ErrorIn(REPLACE)

REPLACE is one of those 174 commands in Visual FoxPro that looks easy at first glance. The only easy thing about REPLACE, though, is the easiness of introducing subtle errors in your code. A well known behavior of REPLACE is that a line like

REPLACE alias.field WITH value

Doesn't replace anything when the current work area is in EOF(); a description that doesn't do the actual behavior justice. In fact, the syntax above only happens to work correctly when there's a random record available in the current work area. When no table is open at all in the current work area, the REPLACE line causes an error 52: "No table is open in the current work area".

What makes this bug so hard to spot is that it's a context dependent error. All you need is one routine that changes the current work area but doesn't restore it properly combined with one routine that uses this REPLACE line without activating the correct work area. Suddenly you have the error, but only when the user triggers the code in a specific order.

Obviously that's not an error you want to have in a COM server or unattended application. Maybe that's a good time to point to the relatively new command

SET TABLEPROMPT OFF

Which doesn't fix the error, but at least doesn't hang your application with a file open dialog when you encounter the problem.

[UPDATE] As has correctly been pointed out: This issue can only become a problem if you omit the IN clause. Once you switch to using

REPLACE field WITH value IN alias

or any other combination that includes the IN clause, the issue is non-existent. Well, you can still introduce errors by specifying empty work areas, but those bugs are much easier to spot.

2008-04Apr-18

ActiveX generic fix

After reading my article on dealing with non-responding ActiveX controls, Carlos Alloatti came up with a generic fix for the problem:

*!* Enable ActiveX Windows

#Define GW_CHILD    5
#Define GW_HWNDNEXT    2

Declare Integer GetWindow In win32api As apiGetWindow ;
  Integer nhWnd, ;
  Integer uCmd

Declare Integer RealGetWindowClass In win32api ;
  As apiRealGetWindowClass ;
  Integer nhWnd, ;
  String  @pszType, ;
  Integer cchType

Declare Integer EnableWindow In win32api As apiEnableWindow ;
  Integer nhWnd, ;
  Integer bEnable

Local ;
  m.lnChildHWnd As Integer, ;
  m.lnCmd As Integer, ;
  m.lnEnable As Integer, ;
  m.lcClassName As String, ;
  m.lnBufferLen As Integer

*!* For testing, change m.lnEnable to 0 to
*!* disable OleControl windows
m.lnEnable = 1

If Thisform.ShowWindow = 2 Or Thisform.ScrollBars > 0 Then
  m.lnChildHWnd = apiGetWindow(Thisform.HWnd, GW_CHILD)
Else
  m.lnChildHWnd = Thisform.HWnd
Endif

m.lnCmd = GW_CHILD

Do While .T.
  m.lnChildHWnd = apiGetWindow(m.lnChildHWnd, m.lnCmd)

  If m.lnChildHWnd = 0 Then
    Exit
  Endif

  m.lcClassName = Space(254)
  m.lnBufferLen = apiRealGetWindowClass(m.lnChildHWnd, ;
    @m.lcClassName, Len(m.lcClassName))
  m.lcClassName = Left(m.lcClassName , m.lnBufferLen)

  If m.lcClassName == "CtlFrameWork_ReflectWindow" Then
    apiEnableWindow(m.lnChildHWnd, m.lnEnable)
  Endif

  m.lnCmd = GW_HWNDNEXT
Enddo

Previous KnowlBits

RSS

April 2008 (2)

January 2008 (2)

December 2007 (2)

November 2007 (2)

October 2007 (1)

September 2007 (1)

August 2007 (5)

July 2007 (4)

May 2007 (6)

March 2007 (3)

February 2007 (7)

January 2007 (6)

November 2006 (1)

October 2006 (3)

September 2006 (10)

June 2006 (2)

May 2006 (6)

April 2006 (1)

Southwest Fox 2008, Mesa, AZ, October 16 - 19, 2008

Impressum Kontakt Contact