<?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[Unit tests to validate COM interfaces
]]></title>
<link>http://www.foxpert.com/knowlbits_200906_2.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
"><p>
Creating a COM server in VFP is easy, maybe too easy. Check the OLEPUBLIC checkbox or add the OLEPUBLIC keyword to the class definition and you are done. Building a DLL creates a COM server that you can pass to anyone who needs to interface with your application. Using a COM server in VFP is similar uneventful. Instantiate the COM server using the ProgId and call methods on the object, that's it.
</p><p>
The ease of creating a COM server comes at a high price. We VFP developer tend to not think about how our COM server is consumed. Unlike Visual FoxPro, which due too its use of late binding is very forgiving when consuming COM servers, this isn't true for most other environments, especially .NET.
</p><p>
A COM interface consists of a list of method pointers. Each method is accessed by its index number. When .NET imports a COM server, it internally creates a mapping which forwards any call of a named method to the corresponding index in the interface. As long as the interface doesn't change, life is good. Have an updated version of the COM server? Just copy it over the existing DLL or EXE.
</p><p>
Any interface change, however, requires a lot of work for the .NET developer. The COM server needs to be imported again. The InterOp library must be generated anew. Depending on how the COM server is used by the application, the entire application might need to be recompiled. The old COM server has to be unregistered; the new one to be distributed and registered.
</p><p>
That's quite a bit of work, but manageable if you tell your clients about the modified interface. Unfortunately VFP makes it way too easy to introduce interface changes accidentally.
</p><p>
How does VFP generate the interface for a COM server?
</p><p>
For every COM class, VFP loops through all public properties and methods and assigns id values. The first method or property in the PRG file is id 0, the second PEM becomes id 1, and so forth. In other words, the physical order determines the id value. This index is the same one that early binding languages use to call methods and access properties.
</p><p>
It's probably obvious now that there're at least two ways to alter the COM interface in a way which wouldn't have any impact on Visual FoxPro, at all: If you rearrange methods in your source code, the index numbers change. Secondly, any new property or method that you don't mark protected or hidden, is added to the interface, as well.
</p><p>
At least for me the second one is a major source for headache. Visual FoxPro uses an object based approach to protected members where almost any other OOP language uses a class based approach. This renders protected PEMs in Visual FoxPro basically useless, which is why I often don't bother making procedures protected. I do even less so with properties as protected properties in Visual FoxPro make it hard to debug code properly and therefore affect code quality negatively. But that's food for another controversy discussion..
</p><p>
After refactoring code and accidentally changing the interface, I took a defensive approach to make sure this won't happen again. I added a unit test similar to the following one for every COM class in my project. It doesn't detect changes to the order of PEMs, but it's sufficient to make sure I'm aware of interface changes to the COM server:
</p><pre>
Procedure Test_CheckInterface

  Local loBO
  loBO = CreateObject("MyCOM.Server")
  This.AssertTrue( "Error loading MyCOM.Server", ;
    Vartype(m.loBO)=="O" )

  Local laPem[1]
  This.AssertEquals( "Wrong number of PEMs", 4, ;
    AMembers(laPem, m.loBO, 3) )
  This.AssertEquals( "#1", "Method1", laPem[1,1] )
  This.AssertEquals( "#2", "Method2", laPem[2,1] )
  This.AssertEquals( "#3", "PEM1", laPem[3,1] )
  This.AssertEquals( "#4", "PEM1", laPem[4,1] )

EndProc
</pre><p>
For every method there's one item in the array created by AMembers. Properties have two entries, one for the getter, and one for the setter. Since I added this unit tests, I made the same mistake several times. But I always spotted the problem before I even prepared the distribution set.
</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, 30 Jun 2009 13:40:16</pubDate>
</item>
<item>
<title><![CDATA[Get rid of security warnings
]]></title>
<link>http://www.foxpert.com/knowlbits_200906_1.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
"><p>
When you download a file with Internet Explorer, the file is tagged as being downloaded from the internet. This has impact on a number of file types. When the file is an EXE and you execute it, you (or more specifically, your users) get a warning:
</p><p>
<b>The publisher could not be verified. Are you sure you want to run this software?</b>
</p><p>
If the file is a CHM help file, the content is never shown. Instead you only see a "Navigation cancelled" error page. For archives the tag is often mysteriously inherited when you extract files. In other words, while this warning might be helpful to prevent malicious code to execute, the system causes a lot of unnecessary support effort for smaller application makers.
</p><p>
Technically, the tag is just an NTFS stream named "Zone.Identifier". This file is actually an INI file specifying the network zone from which the file originates:
</p><pre>
[ZoneTransfer]
ZoneId=3
</pre><p>
Since NTFS streams are only supported on NTFS drives, copying the file to a FAT32 formatted USB stick and pack to the disk effectively removes the security tag. This is neither an obvious, nor a very understandable solution. To an average user this approach sounds much like the famous "if your car stops working get our and back in to fix it" approach.
</p><p>
It would be better to handle this within the application. Providing you have write access to the files, the following program removes the security warnings for all files that match the patter you pass to it:
</p><pre>
*============================================================
* Removes the security warning for all files in a directory
* that match the pattern
*============================================================
LParameter tcPattern

  Local laDir[1], lnFile
  Declare Long DeleteFile in Win32Api String
  For lnFile=1 to ADir(laDir,m.tcPattern)
    DeleteFile( ;
      Addbs(FullPath(JustPath(m.tcPattern)))+;
      laDir[m.lnFile,1]+":Zone.Identifier" ;
  )
  EndFor
</pre><p>
To fix your updated EXE and CHM files, you would use:
</p><pre>
RemSecurityWarning("*.CHM")
RemSecurityWarning("*.EXE")
</pre><p>
You can specify a directory if the current directory is not the right choice.
</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, 30 Jun 2009 11:10:02</pubDate>
</item>
<item>
<title><![CDATA[RecordSource - bang.boom.gone
]]></title>
<link>http://www.foxpert.com/knowlbits_200905_1.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
"><p>
In Visual FoxPro every object belongs to a particular data session. Under normal circumstances this is the data session in which the object is created. The exception are objects that have an intrinsic data session, namely Form, FormSet, Toolbar, and Session. Instantiating these objects may create a new data session in which these objects are then built.
</p><p>
As objects must belong to only one data session, changing the data session inside a form method moves the entire form into the new data session. In my session "The Dark Side of Visual FoxPro" I explained that expressions are evaluated in the context of whatever data session is the current one. Expressions like ControlSources, and so forth might be evaluated at any time. This makes changing the data session risky, but not necessarily unfeasible.
</p><p>
The grid is unfortunately slightly more pro-active. Whenever the record source cursor disappears even for the fraction of a nanosecond, the grid responds immediately. Closing a cursor is an obvious way to hide a cursor. Creating a new cursor in the same work area isn't as obvious, but still understandable. In both cases the grid responds by removing all columns and the RecordSource. On the visual front the grid turns into a white rectangle with a thin black border.
</p><p>
Changing the data session isn't all that obvious. Nonetheless, moving the form - and along the grid - into a different data session constitutes a change in visibility of the cursor. Consequently, the grid updates itself and blanks out the RecordSources property and all ControlSources.
</p><p>
Contrary to closing the cursor in the current data session the column objects remain, only the binding information is gone. As a result the grid looks much like before. Except that there's no record shown. The only visible clue is that the deleted mark column on the left side of the grid is black for all records instead of cleared as it was before.
</p><p>
If this happens to you in a grid where you don't always expect data to be shown this can be a bug that is hard to discover and hard to nail down.  On a screen shot of your application, watch out for the deleted mark column.
</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, 19 May 2009 10:43:48</pubDate>
</item>
<item>
<title><![CDATA[ON SAVE DAYLIGHT RECOMPILE
]]></title>
<link>http://www.foxpert.com/knowlbits_200904_1.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
"><p>
This year I lost another hour of my life. I suffered the switch to daylight saving time twice: The first time early March in Seattle in the USA, the second time the past weekend in Germany. Windows has come a long way to adjust to these changes automatically, other devices I own aren't as smart, unfortunately. But that's a different story.
</p><p>
So this week is the week of the great recompile! If you build your project for the first time this week, you might notice that Visual FoxPro recompiles most files even if you haven't checked the "Recompile all" checkbox and haven't touched them in years. Participation in the great recompile depends on your storage location, though.
</p><p>
On NTFS, the standard file format for Windows these days, all file time stamps are stored in UTC time. UTC means Universal Time Coordinates and is a modern way of saying Greenwich Mean Time. That is, if people save their files all around the world within the same 100 nanoseconds, the time stamp for these files is identical. The time zone doesn't have any impact at all on the value that is stored.
</p><p>
Applications that determine time stamps usually do not work on the raw UTC time structure. Instead they rely on an operating system function to convert the UTC time stamp with its wierd format into a regular time structure based on the local system time. During your day to day work this behavior is what you expect.
</p><p>
Strange things happen, though, when you change the timezone offset, either by changing the timezone or by switching to or from daylight saving time. If you create a file at 9:00AM in January and look at it's creation time in April you'll see that it has been created at 10:00AM. The time that's 9:00 in the winter is 10:00 in the summer (spring forward, fall back).
</p><p>
The time stamp always reflects the absolute time, not the local time when you created a file. This allows Windows to precisely determine the time elapsed since the last modificiation. It also puts all files into creation order, even if you are a frequent traveller that changes time zones every day.
</p><p>
How does this relate to Visual FoxPro, after all?
</p><p>
Visual FoxPro optimizes the compile process and, by default, only compiles files that have been changed. A form or a class libary need to be recompiled when either the file itself has been edited, or when an associated included file has changed. The latter forces Visual FoxPro to keep track of when the include file has last changed.
</p><p>
While a sensible approach would have been to recompile whenever the include file is newer than the form or the class library, this is not the approach that FoxPro takes. Microsoft decided to use a more fail-proof way and includes the time stamp of all dependent header files in the VCX in a binary format. As you can guess this time is stored in the local time format.
</p><p>
So, twice a year the timezone offset changes and the include file suddenly has a different last modified date. Visual FoxPro, recognizing that the form isn't en par with the include file, decides to recompile the form.
</p><p>
Now you know why daylight saving time wastes hours of recompile time in Visual FoxPro projects all around the world... twice a year.
</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, 7 Apr 2009 23:58:32</pubDate>
</item>
<item>
<title><![CDATA[
Detecting idle users
]]></title>
<link>http://www.foxpert.com/knowlbits_200903_1.htm</link>
<description><![CDATA[<DIV class="fp-text" style="font-family:Verdana,Arial,Helvetica,sans-serif;
">
<p>
<b>Updated 2009-04Apr-10</b>
</p><p>
Many thanks to John L Veazey, Simon White, and Geof Shugar for pointing out that my original code turns the mouse pointer into an hour glass most of the time, and for mentioning some unneeded code lines. The updated version should not show this behaviour, at all. John also provided a different approach that I'll post shortly.
</p><p>
It's not too uncommon in business application development to face the requirement to log out users automatically after a period of time. Preventing access to the application by unauthorized users is frequently quoted as a reason for such a feature. This purpose, however, should better be handled on the corporate level. A policy that locks a computer after a certain period of time is more secure, more reliable and better way to prevent access.
</p><p>
Nonetheless, some users let applications run all night long. This is often facilitated by company policies that require the user to keep the computer running as backup and maintenance tasks are carried out during the night.
</p><p>
While an application that is connected to SQL server has little impact on SQL server's ability for maintenance issues, the same does not hold true for Visual FoxPro. Reindexing, packing, backing up, all requires exclusive access to the files.
</p><p>
Detecting activity used to be a tedious development issue. In most scenarios activity equals to moving the mouse and pressing keys. Up to VFP 8.0 the only solution was to insert code into the KeyPress and the MouseMove event of every single base class. Especially the KeyPress event does react differently when there's code in the event. Consequently, adding this feature at a later stage required a lot of testing. When third-party libraries or ActiveX controls had been used, this was even more difficult as they required special coding.
</p><p>
Visual FoxPro 9.0 introduced a great feature: BINDEVENT can bind to API messages. There are two ways to bind to messages. You can specify a single window and only receive messages that go to that specific window, or you can specify 0 as the window handle and automatically receive message for every FoxPro window.
</p><p>
The following program implements a timer that keeps track of the user activities. When the user has been idle for a specified number of minutes, the eventTimeout event is triggered. Here you can respond by logging the user out, shutting the application, or just giving a warning and increasing the timeout:
</p><pre>
*============================================================
* Detects user activity and fires an event after the
* specified period of inactivity.
*============================================================
Define Class InactivityTimer as Timer

  *----------------------------------------------------------
  * API constants
  *----------------------------------------------------------
  #define WM_KEYUP                        0x0101
  #define WM_SYSKEYUP                     0x0105
  #define WM_MOUSEMOVE                    0x0200
  #define GWL_WNDPROC         (-4)

  *----------------------------------------------------------
  * internal properties
  *----------------------------------------------------------
  nTimeOutInMinutes = 0
  tLastActivity = {/:}
  nOldProc = 0

  *----------------------------------------------------------
  * Timer configuration
  *----------------------------------------------------------
  Interval = 30000
  Enabled = .T.

*------------------------------------------------------------
* Listen to API events when the form starts. You can pass
* the timeout as a parameter.
*------------------------------------------------------------
Procedure Init(tnTimeOutInMinutes)
    DECLARE integer GetWindowLong IN WIN32API ;
      integer hWnd, ;
      integer nIndex
    DECLARE integer CallWindowProc IN WIN32API ;
      integer lpPrevWndFunc, ;
      integer hWnd,integer Msg,;
      integer wParam,;
      integer lParam
    THIS.nOldProc=GetWindowLong(_VFP.HWnd,GWL_WNDPROC)
  If Vartype(m.tnTimeOutInMinutes) == "N"
    This.nTimeOutInMinutes = m.tnTimeOutInMinutes
  EndIf
  This.tLastActivity = Datetime()
  BindEvent(0,WM_KEYUP,This,"WndProc")
  BindEvent(0,WM_MOUSEMOVE,This,"WndProc")
EndProc

*------------------------------------------------------------
* Stop listening
*------------------------------------------------------------
Procedure Unload
  UnBindEvents(0,WM_KEYUP)
  UnBindEvents(0,WM_MOUSEMOVE)
EndProc

*------------------------------------------------------------
* Every event counts as activity
*------------------------------------------------------------
Procedure WndProc( ;
  hWnd as Long,Msg as Long,wParam as Long,lParam as Long )
  This.tLastActivity = Datetime()
_screen.Caption = Str(Val(_Screen.Caption)+1)
Return CallWindowProc(this.noldproc,hWnd,msg,wParam,lParam)

*------------------------------------------------------------
* Check last activity against time out
*------------------------------------------------------------
Procedure Timer
  Local ltFireEvent
  ltFireEvent = This.tLastActivity + 60*This.nTimeOutInMinutes
  If Datetime() > m.ltFireEvent
    This.eventTimeout()
  EndIf
EndProc

*------------------------------------------------------------
* Override this event or bind to it to respond to user
* inactivity. You can change the nTimeOutInMinutes to offer
* multiple stages of timeouts.
*------------------------------------------------------------
Procedure eventTimeout

EndDefine
</pre><p>
To use the timer you can either create a sub class or bind to the eventTimeout using BINDEVENTS(). In any case, the instance must be available while the application is running, whether that's as a global variable, as a property in an application object, or by any other mean. For trying this class you can run the following sample code
</p><pre>
Public goForm
goForm = CreateObject("InactivityDemo")

Define Class InactivityDemo as InactivityTimer
  Procedure Init
    DoDefault(1)
  Procedure eventTimeout
    MessageBox("Timeout!")
EndDefine
</pre><p>
If you run this code and then stop working in Visual FoxPro for between one and one and a half minutes, you get a message box every 30 seconds until you stop the demo with CLEAR ALL.
</p><p>
There are a few situations where the inactivity timer is not updated. Long running statements like SELECT or COPY TO commands don't trigger any event handler. Moving the mouse only in the header area isn't captured by VFP. I also suspect that activity inside an ActiveX control is not reliable detected, either.
</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>Sat, 11 Apr 2009 09:25:30</pubDate>
</item>
<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>

 </channel>
</rss>
