<?xml version="1.0" encoding="iso-8859-1" ?>
<rss version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <channel>
  <title>Christof Wollenhaupt</title>
  <link>http://www.foxpert.com/knowlbits.htm</link>
  <description>My notes on Development, the Universe and Everything</description>
  <generator></generator>
  <item>
<title><![CDATA[
How empty is an empty RecordSource?
]]></title>
<link>http://www.foxpert.com/knowlbits_200808_1.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>
Can a record source be empty? Is empty the same as empty? Are all empty record sources equal, or are some more equal than others? Does a grid suffer it doesn't have a record source? Questions over questions...
</p><p>
...and not easy ones, for sure. The grid distinguishes <i>empty</i> as in having the default value and <i>empty</i> as in specifying an empty string as the record source value.
</p><p>
The second one means just that. The record source is unknown, empty, unspecified, unavailable. Not knowing what do the grid just stares blank at you, literally.
</p><p>
The first one, leaving the grid at the blank default value, though gives the grid the opportunity to show you how smart it is. It figures, you either forgot to specify a record source, or it's so blatantly obvious what record source you want the grid to use. Hence, it uses the cursor in the current work area by default.
</p><p>
If that's what you want, that's fine. However, if you create an index on the record source, specify filter, and assume you can use code like this
</p><pre>
IF NOT EMPTY(This.RecordSource)
  SET FILTER TO something IN (This.RecordSource)
ENDIF
</pre><p>
you are as mistaken as I am every once in a while when I stumble over this behaviour in Visual FoxPro. If you want an empty record source, use ="" for the property value in the form, otherwise specify a valid alias. But don't leave the property simply at its default value.
</p>
</DIV><STYLE>.fp-text
{
	font-size: 11pt;
	text-align: justify;
	line-height: 15pt;
	width: 600px;
	margin-left: auto;
	margin-right: auto;
	text-indent: 10px;
}

.fp-text pre
{
	border: 1px dashed black;
	padding: 6px;
	background-color: Beige;
	font-family:monospace;
	margin-left: 10px;
	margin-right: 10px;
	text-indent: 0px;
	line-height: 100%;
}

.fp-text,.fp-sidebar p
{
	margin-top: 6pt;
	margin-bottom: 6pt;
}

.fp-sidebar
{
	width: 200px;
	vertical-align: top;
	font-size: 11pt;
}

.fp-sidebar #search
{
	margin-top: 30px;
}


.fp-text h1
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
	padding: 0px;
	margin: 0px;
}

.fp-text span
{
	font-size: 9px;
	float: right;
	padding: 0px;
	margin: 0px;
	font-weight: normal;
	font-style: italic;
}

.fp-divider
{
	height: 32px;
}

.fp-text h2
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
}

</STYLE>]]></description>
<author>Christof Wollenhaupt</author>
<pubDate>Mon, 25 Aug 2008 12:13:44</pubDate>
</item>
<item>
<title><![CDATA[Events happen]]></title>
<link>http://www.foxpert.com/knowlbits_200807_2.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>
I think it was Jim Booth who used to say this in his sessions. It's a valuable lesson one shouldn't forget. Given that frmDialog.SCX is a form with just one label and the following code in the Init:
</p><pre>
LParameter tcText
Thisform.lblMsg.Caption = m.tcText
</pre><p>
Do you see any problem with the following code?
</p><pre>
SELECT customers
DO FORM frmDialog.SCX WITH "Deleting customer."
DELETE NEXT 1
</pre><p>
Well, I didn't at first glance when I reviewed the code. However, displaying a form makes an awful lot of events happen, like the Activate event. Obviously (after thinking about it, of course), any of these events can change the current work area and not properly reset it. DELETE doesn't necessarily delete the customer record; it can be any record in any table. In fact, destructive commands like DELETE, ZAP or even REPLACE should never be used without the IN clause.
</p>
</DIV><STYLE>.fp-text
{
	font-size: 11pt;
	text-align: justify;
	line-height: 15pt;
	width: 600px;
	margin-left: auto;
	margin-right: auto;
	text-indent: 10px;
}

.fp-text pre
{
	border: 1px dashed black;
	padding: 6px;
	background-color: Beige;
	font-family:monospace;
	margin-left: 10px;
	margin-right: 10px;
	text-indent: 0px;
	line-height: 100%;
}

.fp-text,.fp-sidebar p
{
	margin-top: 6pt;
	margin-bottom: 6pt;
}

.fp-sidebar
{
	width: 200px;
	vertical-align: top;
	font-size: 11pt;
}

.fp-sidebar #search
{
	margin-top: 30px;
}


.fp-text h1
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
	padding: 0px;
	margin: 0px;
}

.fp-text span
{
	font-size: 9px;
	float: right;
	padding: 0px;
	margin: 0px;
	font-weight: normal;
	font-style: italic;
}

.fp-divider
{
	height: 32px;
}

.fp-text h2
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
}

</STYLE>]]></description>
<author>Christof Wollenhaupt</author>
<pubDate>Wed, 16 Jul 2008 12:02:22</pubDate>
</item>
<item>
<title><![CDATA[
Grids, images and a crash.
]]></title>
<link>http://www.foxpert.com/knowlbits_200807_1.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>
In my session "Crashing VFP and preventing crashes" I show that displaying a corrupted image in a grid crashes Visual FoxPro. There's actually more to that as such a crash isn't limited to invalid images.
</p><p>
Right now I'm working on a control that displays images as small thumbnails. Take a look at the Windows Vista Photo Gallery to get an impression what the control looks like. There have been a few lessons I learned from writing this control.
</p><p>
Using BackStyle_Access is a cool technology. Unfortunately, cool does not always translate very well to fast. It might be related to the fact that I display several images in each grid cell. However, BackStyle_Access is called several times for each cell. The strangest thing happens when the form with the grid does not have the focus. In this case, the access method fires permanently. Moving around in the grid is sluggish at best. Again the grid redisplays all images every time the column or row changes.
</p><p>
Hence, I switched back to the traditional DynamicCurrentControl approach having one container for every row. Displaying images works much faster now. Unfortunately, crashing Visual FoxPro is easy, too.
</p><p>
The grid control is very sensitive to displaying itself while it has focus. That's a known issue. For instance, when I need to call the Refresh method, I usually move the focus to some non-visible control, call Refresh and then move the focus back. Not doing so can cause the grid to show no records. They would only come back if you click on the grid and press the up arrow key.
</p><p>
It's not only Refresh that is making problems, but drawing operations in general. In my image control I use the MouseWheel event to resize the image. Doing so changes RowHeight, the width of the column, potentially the ColumnCount property and also needs to redraw all images in the grid. Sooner or later the form crashes. So far, the one rule seems to be that the grid crashes the faster the more optimized my code is. I guess it's related to the number of drawing operations or maybe some overlapping actions.
</p><p>
Funnily - well, not - the crashes only happen when the grid is starting the series of events. Using the mouse wheel on the grid, moving around in the grid very quickly, both crash VFP. But if I trigger the same action from a command button outside the grid, so far I haven't got a crash.
</p>
</DIV><STYLE>.fp-text
{
	font-size: 11pt;
	text-align: justify;
	line-height: 15pt;
	width: 600px;
	margin-left: auto;
	margin-right: auto;
	text-indent: 10px;
}

.fp-text pre
{
	border: 1px dashed black;
	padding: 6px;
	background-color: Beige;
	font-family:monospace;
	margin-left: 10px;
	margin-right: 10px;
	text-indent: 0px;
	line-height: 100%;
}

.fp-text,.fp-sidebar p
{
	margin-top: 6pt;
	margin-bottom: 6pt;
}

.fp-sidebar
{
	width: 200px;
	vertical-align: top;
	font-size: 11pt;
}

.fp-sidebar #search
{
	margin-top: 30px;
}


.fp-text h1
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
	padding: 0px;
	margin: 0px;
}

.fp-text span
{
	font-size: 9px;
	float: right;
	padding: 0px;
	margin: 0px;
	font-weight: normal;
	font-style: italic;
}

.fp-divider
{
	height: 32px;
}

.fp-text h2
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
}

</STYLE>]]></description>
<author>Christof Wollenhaupt</author>
<pubDate>Tue, 8 Jul 2008 14:31:12</pubDate>
</item>
<item>
<title><![CDATA[
Function argument value, type, or count is invalid.
]]></title>
<link>http://www.foxpert.com/knowlbits_200805_1.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>
Another problem that is hard to locate. You build a COM project, either an EXE or any of the DLL types. After creating the EXE or DLL file, Visual FoxPro suddenly displays the error message "Function argument value, type, or count is invalid" and stops building the project. There is a DLL or EXE in the directory, but it doesn't contain any COM registration information. The TLB and VBR files are also missing.
</p><p>
If this happens to you, check the names of all methods and properties in the COM server that are neither protected nor hidden. Visual FoxPro doesn't properly generate the type library when names contain umlauts or other non-English characters. If you have a method like "GetDoppelg&auml;nger", this method would cause the error.
</p>
</DIV><STYLE>.fp-text
{
	font-size: 11pt;
	text-align: justify;
	line-height: 15pt;
	width: 600px;
	margin-left: auto;
	margin-right: auto;
	text-indent: 10px;
}

.fp-text pre
{
	border: 1px dashed black;
	padding: 6px;
	background-color: Beige;
	font-family:monospace;
	margin-left: 10px;
	margin-right: 10px;
	text-indent: 0px;
	line-height: 100%;
}

.fp-text,.fp-sidebar p
{
	margin-top: 6pt;
	margin-bottom: 6pt;
}

.fp-sidebar
{
	width: 200px;
	vertical-align: top;
	font-size: 11pt;
}

.fp-sidebar #search
{
	margin-top: 30px;
}


.fp-text h1
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
	padding: 0px;
	margin: 0px;
}

.fp-text span
{
	font-size: 9px;
	float: right;
	padding: 0px;
	margin: 0px;
	font-weight: normal;
	font-style: italic;
}

.fp-divider
{
	height: 32px;
}

.fp-text h2
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
}

</STYLE>]]></description>
<author>Christof Wollenhaupt</author>
<pubDate>Tue, 27 May 2008 16:41:22</pubDate>
</item>
<item>
<title><![CDATA[REPLACE FOR ErrorIn(REPLACE)]]></title>
<link>http://www.foxpert.com/knowlbits_200804_2.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>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
</p><pre>
REPLACE alias.field WITH value
</pre><p>
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".
</p><p>
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.
</p><p>
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
</p><pre>
SET TABLEPROMPT OFF
</pre><p>
Which doesn't fix the error, but at least doesn't hang your application with a file open dialog when you encounter the problem.
</p><p>
<b>[UPDATE]</b> As has correctly been pointed out: This issue can only become a problem if you omit the IN clause.
Once you switch to using
</p><pre>
REPLACE field WITH value IN alias
</pre><p>
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.
</p></DIV><STYLE>.fp-text
{
	font-size: 11pt;
	text-align: justify;
	line-height: 15pt;
	width: 600px;
	margin-left: auto;
	margin-right: auto;
	text-indent: 10px;
}

.fp-text pre
{
	border: 1px dashed black;
	padding: 6px;
	background-color: Beige;
	font-family:monospace;
	margin-left: 10px;
	margin-right: 10px;
	text-indent: 0px;
	line-height: 100%;
}

.fp-text,.fp-sidebar p
{
	margin-top: 6pt;
	margin-bottom: 6pt;
}

.fp-sidebar
{
	width: 200px;
	vertical-align: top;
	font-size: 11pt;
}

.fp-sidebar #search
{
	margin-top: 30px;
}


.fp-text h1
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
	padding: 0px;
	margin: 0px;
}

.fp-text span
{
	font-size: 9px;
	float: right;
	padding: 0px;
	margin: 0px;
	font-weight: normal;
	font-style: italic;
}

.fp-divider
{
	height: 32px;
}

.fp-text h2
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
}

</STYLE>]]></description>
<author>Christof Wollenhaupt</author>
<pubDate>Tue, 29 Apr 2008 17:25:58</pubDate>
</item>
<item>
<title><![CDATA[ActiveX generic fix]]></title>
<link>http://www.foxpert.com/knowlbits_200804_1.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>
After reading <a href="http://www.foxpert.com/knowlbits_200801_1.htm">my article</a> on dealing with non-responding ActiveX controls, Carlos Alloatti came up with a generic fix for the problem:
</p><pre>
*!* 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

</pre>
</DIV><STYLE>.fp-text
{
	font-size: 11pt;
	text-align: justify;
	line-height: 15pt;
	width: 600px;
	margin-left: auto;
	margin-right: auto;
	text-indent: 10px;
}

.fp-text pre
{
	border: 1px dashed black;
	padding: 6px;
	background-color: Beige;
	font-family:monospace;
	margin-left: 10px;
	margin-right: 10px;
	text-indent: 0px;
	line-height: 100%;
}

.fp-text,.fp-sidebar p
{
	margin-top: 6pt;
	margin-bottom: 6pt;
}

.fp-sidebar
{
	width: 200px;
	vertical-align: top;
	font-size: 11pt;
}

.fp-sidebar #search
{
	margin-top: 30px;
}


.fp-text h1
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
	padding: 0px;
	margin: 0px;
}

.fp-text span
{
	font-size: 9px;
	float: right;
	padding: 0px;
	margin: 0px;
	font-weight: normal;
	font-style: italic;
}

.fp-divider
{
	height: 32px;
}

.fp-text h2
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
}

</STYLE>]]></description>
<author>Christof Wollenhaupt</author>
<pubDate>Fri, 18 Apr 2008 20:17:52</pubDate>
</item>
<item>
<title><![CDATA[Positioning popup menus]]></title>
<link>http://www.foxpert.com/knowlbits_200801_2.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>
I'm not a big fan of right click menus. In many applications they are implemented incorrectly and cannot be triggered with the context menu key or the standard Shift+F10 combination. They also seem to be sort of a dump bin for many developers. Instead of thinking how to incorporate a new feature in a useful way, it's just added to all right click menus on the form. Lastly, right click menus are hardly discoverable for the end user. Having to click on every pixel just to discover whether there's some hidden feature is great for games, but not really appropriate for any productive application.
</p><p>
There are uses for right click menus. One should keep in mind, though, that the name "shortcut menu" comes from the fact that these menus originally provided a quicker way to access features with a mouse that would be available in the menu or on buttons, as well. Features which are only available through a shortcut or multi-level popup menus that merely open a dialog box somewhere else on the screen hardly fall into that category.
</p><p>
Back to the topic. There are times when it makes sense to provide less frequently used features on a form. For instance, a useful feature for a name textbox is to open a browser window with a web search. For such features I use a small button close to the textbox that displays a down arrow ("u" using the Marlett font). This button opens a small popup menu just below the button much in the same way you see this all over in Microsoft Office.
</p><p>
Positioning popup menus can be a little difficult in Visual FoxPro. The Menu Designer produces code that uses MCOL() and MROW() to position the menu at the mouse cursor. This works fine unless you click somewhere on the window title. In this case, the two functions return -1 moving the popup somewhere outside the window.
</p><p>
When you try to move the popup elsewhere you quickly realize that you have to give the position in Foxels instead of pixels. Foxels are in Visual FoxPro what Twips are in Visual Basic. A Foxel depends on the size of the current font of a form. In other words, changing Thisform.FontName or any other font related property changes the measurement for Foxels.
</p><p>
The rarely used ScaleMode property allows you to specify form coordinates in Foxels or pixels. As a side note: Switching a form to Foxels is a good way to break <i>generic</i> third party components. Most developers don't deal very well with positions that have decimal places and add pixels to Left, Top, Width, and Height without checking the scale mode before.
</p><p>
Hence, to position a popup control just below or above a command button, you switch the form scale mode, read the button position in Foxels and switch back to pixels. This works fine for buttons that are placed on the form directly. With nested controls, though, you have to use OBJTOCLIENT(), a function that completely ignores the ScaleMode property. To get around this, I add an invisible button right to the form:
</p><pre>
Local lnRow, lnColumn
If Vartype(Thisform.PosHelp) != "O"
  Thisform.AddObject("PosHelp","Commandbutton")
EndIf
Thisform.PosHelp.Move( ;
  Objtoclient(This,2), ;
  Objtoclient(This,1)+This.Height ;
)
Thisform.ScaleMode = 0
lnRow = Thisform.PosHelp.Top
lnColumn = Thisform.PosHelp.Left
Thisform.ScaleMode = 3
</pre><p>
With the position in Foxels I can now define a popup menu like this:
</p><pre>
DEFINE POPUP shortcut ;
  SHORTCUT RELATIVE ;
  From m.lnRow, m.lnColumn ;
  Font Thisform.FontName, This.FontSize
Define bar 1 of Shortcut Prompt "Item 1"
Define bar 2 of Shortcut Prompt "Item 2"
Define bar 3 of Shortcut Prompt "Item 3"
Activate Popup Shortcut
</pre><p>
Just in case you wonder about the FONT clause used here. Some clients insist on a resizer control on the form. That is, when they resize the form, the content becomes larger. With this clause the popup menu has the same size as everything else on the form.
</p>
</DIV><STYLE>.fp-text
{
	font-size: 11pt;
	text-align: justify;
	line-height: 15pt;
	width: 600px;
	margin-left: auto;
	margin-right: auto;
	text-indent: 10px;
}

.fp-text pre
{
	border: 1px dashed black;
	padding: 6px;
	background-color: Beige;
	font-family:monospace;
	margin-left: 10px;
	margin-right: 10px;
	text-indent: 0px;
	line-height: 100%;
}

.fp-text,.fp-sidebar p
{
	margin-top: 6pt;
	margin-bottom: 6pt;
}

.fp-sidebar
{
	width: 200px;
	vertical-align: top;
	font-size: 11pt;
}

.fp-sidebar #search
{
	margin-top: 30px;
}


.fp-text h1
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
	padding: 0px;
	margin: 0px;
}

.fp-text span
{
	font-size: 9px;
	float: right;
	padding: 0px;
	margin: 0px;
	font-weight: normal;
	font-style: italic;
}

.fp-divider
{
	height: 32px;
}

.fp-text h2
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
}

</STYLE>]]></description>
<author>Christof Wollenhaupt</author>
<pubDate>Wed, 9 Jan 2008 12:04:58</pubDate>
</item>
<item>
<title><![CDATA[ActiveFiX]]></title>
<link>http://www.foxpert.com/knowlbits_200801_1.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>
ActiveX controls don't work well in VFP with modal forms. Well, that's not exactly a big surprise for anyone who tried that. If you contact the creator of an ActiveX control you usually end up with one of two replies:
</p><p>
"Our controls work in all supported environment. What is Visual FoxPro, anyway?" or "Go away! We don't write unmanaged code, anymore." Even controls that usually behave well with VFP, like the controls from dbi exhibit this behaviour.
</p><p>
Why can't the vendors fix this? Admittedly, it's not really their bug; it's a Visual FoxPro bug. Not really a bug, more like a design issue. One of the problems that the Visual FoxPro team had to solve was that modal windows simply don't exist in the Windows API. OK, you see them, but that doesn't mean they are real.
</p><p>
Windows creates a modal window by disabling the parent window. That works fine with just a single level of modal windows like it's the case with a dialog box. However, with multiple windows (or forms) that can be modal, maybe with multiple forms in a form set that remain accessible while other windows are not, things get more confusing.
</p><p>
So here's what happens with ActiveX controls in Visual FoxPro: When you add an ActiveX control you actually add two windows to the form. The outermost is the OLE host window which is the one that Visual FoxPro controls. Inside the host window, the ActiveX control creates its own window(s) that remain under control of the ActiveX control. This inner window (or windows) is what we know as "the ActiveX control".
</p><p>
When you show a modal window, Visual FoxPro disables all OLE host windows on all other forms. The ActiveX control inside remains active, but doesn't receive any user input related messages anymore, because the parent window is disabled. As a result, the control does not respond to mouse or keyboard events, nor does it receive the focus. It continues to run, though. For instance, it can update itself, respond to other events, and the like.
</p><p>
Once the user closes the modal form, Visual FoxPro enables all previously disabled host windows. My bet (well, more a guess, actually) is that Visual FoxPro stores the previous state when it disables the OLE host window and restores that state when upon enabling them. The control receives messages and responds to user input. Well, that's what happens with just one level of modal forms.
</p><p>
It seems, though, that there's only one variable for keeping the previous enabled state of each OLE host window. So when the second modal form is launched, Visual FoxPro stores the state of the already disabled window and disables it again. When the form is closed, this disabled state becomes what is restored. In the end, the host window remains disabled even when all modal forms have been closed.
</p><p>
There is actually an easy fix that - unfortunately - is not generic. When the Activate event of a form fires you know for sure that this form should respond to user input. At this point none of the ActiveX controls on the current form should be disabled. You can ensure this by running the following code for every ActiveX control that is on the form:
</p><pre>
Declare Long GetParent in Win32API Long
Declare Long EnableWindow in Win32API Long, Long
EnableWindow( GetParent(oleControl.Hwnd), 1 )
</pre><p>
oleControl is a regular reference to the ActiveX control on the form (e.g. Thisform.oleControl1). The HWND property is not a standard property that VFP provides. It's completely up to the ActiveX control to provide the window handle and to pick the name for the property or method. You need to refer to the documentation of the ActiveX control.
</p>
</DIV><STYLE>.fp-text
{
	font-size: 11pt;
	text-align: justify;
	line-height: 15pt;
	width: 600px;
	margin-left: auto;
	margin-right: auto;
	text-indent: 10px;
}

.fp-text pre
{
	border: 1px dashed black;
	padding: 6px;
	background-color: Beige;
	font-family:monospace;
	margin-left: 10px;
	margin-right: 10px;
	text-indent: 0px;
	line-height: 100%;
}

.fp-text,.fp-sidebar p
{
	margin-top: 6pt;
	margin-bottom: 6pt;
}

.fp-sidebar
{
	width: 200px;
	vertical-align: top;
	font-size: 11pt;
}

.fp-sidebar #search
{
	margin-top: 30px;
}


.fp-text h1
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
	padding: 0px;
	margin: 0px;
}

.fp-text span
{
	font-size: 9px;
	float: right;
	padding: 0px;
	margin: 0px;
	font-weight: normal;
	font-style: italic;
}

.fp-divider
{
	height: 32px;
}

.fp-text h2
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
}

</STYLE>]]></description>
<author>Christof Wollenhaupt</author>
<pubDate>Mon, 7 Jan 2008 23:43:04</pubDate>
</item>
<item>
<title><![CDATA[This text is not right]]></title>
<link>http://www.foxpert.com/knowlbits_200712_2.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>
<a href="http://www.hentzenwerke.com/catalog/hackfox7.htm">HackFox</a> mentions this, but it's still annoying. Textboxes cannot be right aligned when using regular text. When you set the Alignment property to 1, you end up with a textbox that looks properly. Yet, as soon as the textbox receives the focus, the content moves to the left.
</p><p>
How much to the left directly depends on the maximum length of the value, either spelled out in the MaxLength property, or implicitly defined through the control source. Textboxes with a maximum length of 1 almost behave correctly. The text is right aligned when the control gets the focus. The longer the value can be, the more VFP shifts text to the left. If you have a control that can hold like 200 characters, you might end up only seeing the rightmost character when the textbox has focus.
</p><p>
Note to myself: It doesn't work. Don't waste your time trying to make it work.
</p>

</DIV><STYLE>.fp-text
{
	font-size: 11pt;
	text-align: justify;
	line-height: 15pt;
	width: 600px;
	margin-left: auto;
	margin-right: auto;
	text-indent: 10px;
}

.fp-text pre
{
	border: 1px dashed black;
	padding: 6px;
	background-color: Beige;
	font-family:monospace;
	margin-left: 10px;
	margin-right: 10px;
	text-indent: 0px;
	line-height: 100%;
}

.fp-text,.fp-sidebar p
{
	margin-top: 6pt;
	margin-bottom: 6pt;
}

.fp-sidebar
{
	width: 200px;
	vertical-align: top;
	font-size: 11pt;
}

.fp-sidebar #search
{
	margin-top: 30px;
}


.fp-text h1
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
	padding: 0px;
	margin: 0px;
}

.fp-text span
{
	font-size: 9px;
	float: right;
	padding: 0px;
	margin: 0px;
	font-weight: normal;
	font-style: italic;
}

.fp-divider
{
	height: 32px;
}

.fp-text h2
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
}

</STYLE>]]></description>
<author>Christof Wollenhaupt</author>
<pubDate>Sun, 30 Dec 2007 13:21:12</pubDate>
</item>
<item>
<title><![CDATA[HAVING gotcha]]></title>
<link>http://www.foxpert.com/knowlbits_200712_1.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>Without a GROPY BY clause HAVING operates similar to a WHERE clause, except that the filter operates on the result set:
</p><pre>
Create Cursor curSrc (Fld1 I, Fld2 I)
Insert into curSrc values (1,1)
Insert into curSrc values (2,2)

Select Fld1, fld1+1 as Fld3 ;
  From curSrc ;
  having Fld3 = 2
</pre><p>
In this sample the query only returns those records where expression "FLD1+1" results in 2. The ability to query fields in the result set is limited, though. You can only query field names that do not appear in one of the source tables. Rewriting the query like this gets you a different result. The only difference in the statement is that FLD3 is now named FLD2:
</p><pre>
Select Fld1, fld1+1 as Fld2 ;
  From curSrc ;
  having fld2 = 2
</pre><p>
FLD2 is only used an alias in the field list, yet the HAVING clause operates on curSrc.Fld2 instead of FLD2 from the result set. This can cause changes in program behaviour when you add a field to a table with the same name as a calculated column.
</p><p>
Once you aggregate the result set with GROUP BY, rules change slightly. Referring to the field name in the result set yields an error message, if a field with the same name exists in any of the source tables. In the following query, FLD1+1=2 works in the HAVING clause, FLD2=2 wouldn't:
</p><pre>
Select Fld1, fld1+1 as Fld2 ;
  From curSrc ;
  group by 1,2 ;
  having fld1+1 = 2
</pre><p>
The same query is valid if  the field name does not exist in any of the source tables. The following query uses FLD3 instead of FLD2 as the field name:
</p><pre>
Select Fld1, fld1+1 as Fld3 ;
  From curSrc ;
  group by 1,2 ;
  having fld3 = 2
</pre><p>
This is a situation you might encounter when doing refactoring and renaming fields. Changing the local field name suddenly causes errors when you run the query.
</p>
</DIV><STYLE>.fp-text
{
	font-size: 11pt;
	text-align: justify;
	line-height: 15pt;
	width: 600px;
	margin-left: auto;
	margin-right: auto;
	text-indent: 10px;
}

.fp-text pre
{
	border: 1px dashed black;
	padding: 6px;
	background-color: Beige;
	font-family:monospace;
	margin-left: 10px;
	margin-right: 10px;
	text-indent: 0px;
	line-height: 100%;
}

.fp-text,.fp-sidebar p
{
	margin-top: 6pt;
	margin-bottom: 6pt;
}

.fp-sidebar
{
	width: 200px;
	vertical-align: top;
	font-size: 11pt;
}

.fp-sidebar #search
{
	margin-top: 30px;
}


.fp-text h1
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
	padding: 0px;
	margin: 0px;
}

.fp-text span
{
	font-size: 9px;
	float: right;
	padding: 0px;
	margin: 0px;
	font-weight: normal;
	font-style: italic;
}

.fp-divider
{
	height: 32px;
}

.fp-text h2
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
}

</STYLE>]]></description>
<author>Christof Wollenhaupt</author>
<pubDate>Mon, 17 Dec 2007 13:48:40</pubDate>
</item>
<item>
<title><![CDATA[Vault error when checking in]]></title>
<link>http://www.foxpert.com/knowlbits_200711_2.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>
When you check a file into Vault and get the following error message:
</p><p>
<i>An exception was encountered during the transaction.  Exception: The Vault server could not be contacted to perform the operation.  Your network connection to the server may have been interrupted.  Please verify your network settings using the Options dialog under the Tools menu in the Vault GUI Client.The request failed with HTTP status 400: Bad Request.   at VaultClientNetLib.VaultConnection.BeginTx(Int32 nRepID, VaultRequestItem[]& requests, String& strTxID, String comment)
   at VaultClientOperationsLib.ClientInstance.Commit(ChangeSetItemColl givenItems, String strChangeSetComment, Boolean keepCheckedOut, Boolean removeLocalCopy, CommitType committype, VaultDateTime dateImport, Int32 nUserIDImport, Int64& nRevID, Int32[]& retBegEndTx)</i>
</p><p>
Verify that the check in comment does not contain any non-printable characters (little boxes). It might be hard to read in the checkin dialog. In this case, copy the entire comment over to Notepad or an editor with non-proportional fonts.
</p></DIV><STYLE>.fp-text
{
	font-size: 11pt;
	text-align: justify;
	line-height: 15pt;
	width: 600px;
	margin-left: auto;
	margin-right: auto;
	text-indent: 10px;
}

.fp-text pre
{
	border: 1px dashed black;
	padding: 6px;
	background-color: Beige;
	font-family:monospace;
	margin-left: 10px;
	margin-right: 10px;
	text-indent: 0px;
	line-height: 100%;
}

.fp-text,.fp-sidebar p
{
	margin-top: 6pt;
	margin-bottom: 6pt;
}

.fp-sidebar
{
	width: 200px;
	vertical-align: top;
	font-size: 11pt;
}

.fp-sidebar #search
{
	margin-top: 30px;
}


.fp-text h1
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
	padding: 0px;
	margin: 0px;
}

.fp-text span
{
	font-size: 9px;
	float: right;
	padding: 0px;
	margin: 0px;
	font-weight: normal;
	font-style: italic;
}

.fp-divider
{
	height: 32px;
}

.fp-text h2
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
}

</STYLE>]]></description>
<author>Christof Wollenhaupt</author>
<pubDate>Wed, 28 Nov 2007 17:03:22</pubDate>
</item>
<item>
<title><![CDATA[Date range conflicts]]></title>
<link>http://www.foxpert.com/knowlbits_200711_1.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>
One common problem in database applications is checking for conflicts in a date or datetime range. For instance, your application might manage appointments which have a start date and duration. We might talk about minutes or days here, the fundamental problem remains the same. When you enter a new appointment you have to make sure that it doesn't conflict with an existing one.
</p><p>
The problem with date ranges is that there are four variations you have to cover. (a) One range might have no conflicts with another range, (b) might completely fall into the other range, (c) start before, but ends within the other range, (d) starts within, but ends after the other range. I can never remember the query to check for any conflicting items. So here it is (based on <a href="http://ryanfarley.com/blog/archive/2004/08/19/966.aspx">http://ryanfarley.com/blog/archive/2004/08/19/966.aspx</a>):
</p><p>
If none of the dates can be empty:
</p><pre>
(NOT((table.date_end < m.date_start) ;
or (table.date_start > m.date_end)))
</pre><p>
If the end date in the table can be empty to mean a one day appointment, the code would look like this:
</p><pre>
(NOT ((table.date_end < m.date_start) ;
OR (table.date_start > m.date_end))) ;
OR (table.date_end=={} AND ;
BETWEEN(table.date_start,m.date_start,m.date_end))
</pre><p>
This expression can be used in a SET FILTER TO statement or a WHERE clause. If you need to filter on additional criteria (resource, etc.), you can add those filters with AND. The expression is Rushmore optimizable when you have an index on date_end and date_start in the table.
</p>
</DIV><STYLE>.fp-text
{
	font-size: 11pt;
	text-align: justify;
	line-height: 15pt;
	width: 600px;
	margin-left: auto;
	margin-right: auto;
	text-indent: 10px;
}

.fp-text pre
{
	border: 1px dashed black;
	padding: 6px;
	background-color: Beige;
	font-family:monospace;
	margin-left: 10px;
	margin-right: 10px;
	text-indent: 0px;
	line-height: 100%;
}

.fp-text,.fp-sidebar p
{
	margin-top: 6pt;
	margin-bottom: 6pt;
}

.fp-sidebar
{
	width: 200px;
	vertical-align: top;
	font-size: 11pt;
}

.fp-sidebar #search
{
	margin-top: 30px;
}


.fp-text h1
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
	padding: 0px;
	margin: 0px;
}

.fp-text span
{
	font-size: 9px;
	float: right;
	padding: 0px;
	margin: 0px;
	font-weight: normal;
	font-style: italic;
}

.fp-divider
{
	height: 32px;
}

.fp-text h2
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
}

</STYLE>]]></description>
<author>Christof Wollenhaupt</author>
<pubDate>Wed, 28 Nov 2007 00:57:52</pubDate>
</item>
<item>
<title><![CDATA[Accumulating the slow parts]]></title>
<link>http://www.foxpert.com/knowlbits_200710_1.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>
As a developer you need a fast machine and fast access to keep the duration of the typical edit-compile-run cycle at a minumum. Slow machines have direct impact on development times. Having a fast machine has a major drawback though: You don't get a feeling what your application feels like to a real user that doesn't work with local data on a fast machine.
</p><p>
Monitoring tools like FILEMON or Ethereal give you a first overview of the amount of data that your application transfers across the network in a particular situation. After optimizing the application to reduce bandwidth usage you might still be surprised.
</p><p>

Many statements in Visual FoxPro, especially SQL SELECT statements, cache heavily. Cached contents expires after a timeout period of five seconds, by default. You can control the time with SET REFRESH and the "Refresh" setting of CURSORSETPROP.
</p><p>

You might get nasty surprises if your code consists of a series of SELECT statements that access the same table. On your machine all these statements execute in less than five seconds. Consequently, only the first SELECT statement actually reads from the table. All subsequent SELECT statements access the cache. On real client machines, though, SELECT statements easily run for more than five seconds. VFP invalidates the cache right after terminating the first query. The next queries force VFP to read the entire table over and over again.
</p><p>

Instead of transferring like 60 MB in a two seconds for ten queries on your local machine, you might end up transferring 600 MB in a over a minute across the network... just because every single query runs for more than five seconds.
</p></DIV><STYLE>.fp-text
{
	font-size: 11pt;
	text-align: justify;
	line-height: 15pt;
	width: 600px;
	margin-left: auto;
	margin-right: auto;
	text-indent: 10px;
}

.fp-text pre
{
	border: 1px dashed black;
	padding: 6px;
	background-color: Beige;
	font-family:monospace;
	margin-left: 10px;
	margin-right: 10px;
	text-indent: 0px;
	line-height: 100%;
}

.fp-text,.fp-sidebar p
{
	margin-top: 6pt;
	margin-bottom: 6pt;
}

.fp-sidebar
{
	width: 200px;
	vertical-align: top;
	font-size: 11pt;
}

.fp-sidebar #search
{
	margin-top: 30px;
}


.fp-text h1
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
	padding: 0px;
	margin: 0px;
}

.fp-text span
{
	font-size: 9px;
	float: right;
	padding: 0px;
	margin: 0px;
	font-weight: normal;
	font-style: italic;
}

.fp-divider
{
	height: 32px;
}

.fp-text h2
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
}

</STYLE>]]></description>
<author>Christof Wollenhaupt</author>
<pubDate>Mon, 8 Oct 2007 12:16:36</pubDate>
</item>
<item>
<title><![CDATA[Passing Unicode strings to API functions]]></title>
<link>http://www.foxpert.com/knowlbits_200709_1.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>
Virtually all older API functions exist in two versions: An ANSI version ending in "A" and a Unicode version ending in "W". If you specify an API function without either of them, Visual FoxPro automatically adds "A" at the end and uses the ANSI version. All of this happens automatically, nothing to spend any thought on.
</p><p>
Similar transparent is passing strings to API functions. Most API functions expect strings to be zero-terminated, that is, end in CHR(0). Because this is so common, Visual FoxPro automatically adds CHR(0) to every string that it passes to an API function.
</p><p>
Life was good until Microsoft kept publishing new APIs that only accept Unicode parameters. To convert a String to Unicode, you can use the following line:
</p><pre>
STRCONV( lcString, 5 )
</pre><p>
When you call API functions, you have to take care of one more detail. A Unicode string doesn't require only one CHR(0) at the end, but two of them. One is added by VFP, but it's your responsibility to add the second one:
</p><pre>
STRCONV( lcString, 5 ) + CHR(0)
</pre><p>
Failing to do so results in API calls that work sometimes, and sometimes not. A typically pattern is that the function call works the first time, but no more after that. The first call was done with new, clean memory. Any further call reuses memory which has been filled by subsequent operations.
</p><p>
Another sign for forgetting CHR(0) is when your code works fine when you slowly step through it, but not if you run it normally. Visual FoxPro performs garbage collections regularly when debugging slowly. This vastly increases the likelihood that you get clean memory.
</p></DIV><STYLE>.fp-text
{
	font-size: 11pt;
	text-align: justify;
	line-height: 15pt;
	width: 600px;
	margin-left: auto;
	margin-right: auto;
	text-indent: 10px;
}

.fp-text pre
{
	border: 1px dashed black;
	padding: 6px;
	background-color: Beige;
	font-family:monospace;
	margin-left: 10px;
	margin-right: 10px;
	text-indent: 0px;
	line-height: 100%;
}

.fp-text,.fp-sidebar p
{
	margin-top: 6pt;
	margin-bottom: 6pt;
}

.fp-sidebar
{
	width: 200px;
	vertical-align: top;
	font-size: 11pt;
}

.fp-sidebar #search
{
	margin-top: 30px;
}


.fp-text h1
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
	padding: 0px;
	margin: 0px;
}

.fp-text span
{
	font-size: 9px;
	float: right;
	padding: 0px;
	margin: 0px;
	font-weight: normal;
	font-style: italic;
}

.fp-divider
{
	height: 32px;
}

.fp-text h2
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
}

</STYLE>]]></description>
<author>Christof Wollenhaupt</author>
<pubDate>Mon, 24 Sep 2007 14:46:30</pubDate>
</item>
<item>
<title><![CDATA[The SCAN command]]></title>
<link>http://www.foxpert.com/knowlbits_200708_5.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>
I've seen lots of FoxPro programs that use GO TOP before a SCAN loop and SELECT just before the ENDSCAN and before every LOOP statement. These statements aren't required anymore. Yet, many developers use them as a safety belt. So what does SCAN really do? Here are a number of observations:
</p><p>
SCAN saves the work area the first time it's executed. Subsequent calls restore the work area, not the alias. If you start in work area 4 as in the test code below, VFP doesn't care what table is open. The SCAN loop just runs until SCAN moves the cursor into EOF in whatever table is open in the work area at that time. This is important for generic code that closes and reopens a table. It's not sufficient to open it with the same alias. You have to open it in the same work area, too.
</p><p>
On the first pass, SCAN moves the cursor to the top of the file. Subsequent calls just skip by one record. This even true when the table changes in between. Hence, the following code skips through records 1-3 of Customers, and records 2-4 of Products. The total number of iterations is six, even though this would impossible with the FOR condition in just one table.
</p><pre>
Select 4
Use Northwind\customers
Scan for Recno() < 5
	? Select(), Evaluate(Field(1))
	If Used("Customers") and Recno() >= 3
		Use Northwind\Products
	EndIf
	Select 99
Endscan
</pre><p>
The NEXT clause is implemented as an independent counter. If you add NEXT 4 to the SCAN command above, the total number of iterations is four, not four for each table.
</p><p>
The FOR clause is bound to the SCAN statement which invalidates a filter when you switch tables:
</p><pre>
Clear
_screen.Cls()
ln = 0
Select 4
Use Northwind\customers
Scan for Iif(;
  _Screen.Print(Alias()+Transform(Recno())+Chr(13));
  ,.t.,.t.) and Upper(city)="A"
	? "  *"
	ln = ln+1
	If Used("Customers") and ln> 2
		Use Northwind\Products
	EndIf
	lnRecNo = Recno()
endscan
</pre><p>
When you run this code you see that VFP evaluates the FOR condition for the first record of Customers.DBF, all matching records in Customers (17, 55, and 65) and exactly the same records (17, 55, and 65) in the Products table. In other words, VFP is using the Rushmore bitmap for Customers on the Products table. Because Rushmore involves a record validation, the SCAN loop itself is only executed for the Customers table.
</p><p>
Reusing Rushmore bitmaps this way is a subtle source for errors. If you changed the condition from UPPER(City)="A" to UPPER(City)="W", you would end up with a "Record out of range" error message. The records with "W" as the city in Customers.dbf are record 43 and 91. The Products table, however, only has 77 records.
</p>
</DIV><STYLE>.fp-text
{
	font-size: 11pt;
	text-align: justify;
	line-height: 15pt;
	width: 600px;
	margin-left: auto;
	margin-right: auto;
	text-indent: 10px;
}

.fp-text pre
{
	border: 1px dashed black;
	padding: 6px;
	background-color: Beige;
	font-family:monospace;
	margin-left: 10px;
	margin-right: 10px;
	text-indent: 0px;
	line-height: 100%;
}

.fp-text,.fp-sidebar p
{
	margin-top: 6pt;
	margin-bottom: 6pt;
}

.fp-sidebar
{
	width: 200px;
	vertical-align: top;
	font-size: 11pt;
}

.fp-sidebar #search
{
	margin-top: 30px;
}


.fp-text h1
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
	padding: 0px;
	margin: 0px;
}

.fp-text span
{
	font-size: 9px;
	float: right;
	padding: 0px;
	margin: 0px;
	font-weight: normal;
	font-style: italic;
}

.fp-divider
{
	height: 32px;
}

.fp-text h2
{
	text-indent: 0px;
	font-size: 11pt;
	font-weight: bold;
}

</STYLE>]]></description>
<author>Christof Wollenhaupt</author>
<pubDate>Fri, 31 Aug 2007 17:53:42</pubDate>
</item>

 </channel>
</rss>
