Thursday, December 27, 2012

A Christmas Present

I usually try to get a small project done over the Christmas holidays. This year, I finally tackled something I’ve wanted to do for years: I’ve posted most of the session white papers and magazine articles I’ve written over the past 16 years (146 documents in all) at the Technical Papers page of my personal Web site, DougHennig.com. The list is alphabetical by title and includes an abstract and links to download the document and sample files (if there are any). Since the documents go back to 1996, some of them are likely out-of-date (I think “Windows 95 Issues for FoxPro” falls into that category), but most of them are still applicable. Note that anything presented or published in 2012 isn’t in the list yet.

Since most of the documents were originally in Microsoft Word, I automated the process of opening each one, writing the title and abstract to a table used to generate the list of articles, and saving the document as a PDF. As a result, although I spot-checked a lot of documents, there could be some glitches in formatting. Also, I sometimes presented a conference session on a topic I’d written a magazine article about, so I tried to remove duplicates as best I could. Please let me know if you find any problems or duplicates with these documents and I’ll get them fixed up.

Friday, December 14, 2012

When a Comma Isn’t

Stonefield Query has the ability to output reports to a CSV file. “CSV” is an abbreviation for “comma-separated values”, meaning there’s a comma between each value (which represents a field) in a row (which represents a record). Except when it’s supposed to be something else.

We recently had a customer in France report that when they output a report to CSV and then opened it in Microsoft Excel, numeric values didn’t come out right. I figured it was likely a regional setting, so I used the Control Panel Region and Language applet to change my setting to French (France) and voila (appropriate word choice, non?), was able to reproduce the problem. I thought perhaps the issue was that Excel didn’t like the fact that in France, a comma is used as a decimal separator, but changing a value like “45,25” to “45.25” didn’t fix the problem. Then I notice something I hadn’t noticed or heard of before: in the Customize Format dialog (click the Additional Settings button on the Formats tab of the Region and Language dialog), there’s a “list separator” setting. We in North America (and probably other places too) are used to having it be a comma, but for France, it’s a semi-colon.

image

Changing the CSV output to use a semi-colon instead of a comma for the separator fixed the problem. However, how to get the current value of the list separator? While VFP has functions to determine some of the user’s regional settings, such as SET(‘POINT’) (the character used for the decimal separator) and SET(‘SEPARATOR’) (the character used for the thousand separator), it doesn’t have one for this. Google turned up a few references to the Window API GetLocaleInfo function, but for some reason, that just gave me a blank rather than the expected comma or semi-colon. Fortunately, another site mentioned that it’s stored in the Windows Registry in the sList key of HKEY_CURRENT_USER\Control Panel\International.

So, now you can output a CSV file from Stonefield Query and while the “C” in “CSV” may not be accurate, the file is.

Thursday, December 06, 2012

Stonefield Query SDK Version 4.3

We are pleased to announce the release of version 4.3 of the Stonefield Query SDK. See the Stonefield Query blog for details on new features.

Wednesday, December 05, 2012

New VFPX Administrator

Since the inception of the SednaX project (the previous name of VFPX) there have been three administrators of the project: Craig Boyd, Rick Schummer, and me. Jim Nelson has been a long-time contributor to VFPX with PEM Editor, Code Reference updates, Thor, and IntelliSenseX. His contributions to the community through VFPX are legendary. Jim also has made numerous suggestions to us over the years that have improved the experience on CodePlex. It only seemed natural that Jim take a more prominent role in the future of VFPX, so we’ve asked him to join us and he’s agreed. Thanks for all you do, Jim.

Tuesday, November 13, 2012

Another 2012 Lifetime Achievement Award Recipient

At a special session of the 2012 German DevCon, Rainer Becker presented Igor Vit with a FoxPro Lifetime Achievement Award.

IgorVit

I’ve known Igor for a long time. He was a Microsoft MVP, organizer of the Czech FoxPro DevCon, and responsible for localizing FoxPro in the Czech Republic. I’m glad to see him finally receive the recognition he deserves.

Friday, October 26, 2012

Fixing Yet Another Report Designer Issue

Last month I blogged about an issue in the VFP Report Designer that causes a “printer not ready” error if you don’t have a default printer set up, as is sometimes the case in a Terminal Server environment. Recently I discovered a related issue: the same error occurs when opening the Page Setup dialog. The cause is the SET(‘PRINTER’, 3) statement in the LoadDeviceInfo method of FRXDeviceHelper in _FRXCursor.VCX. The fix is to wrap that statement in a TRY structure.

Tuesday, October 23, 2012

2011 Southwest Fox Speaker Award

Cathy Knight (then Cathy Pountney) was the top-ranked Southwest Fox 2008 speaker, as measured by attendee evaluations. Her friends Toni Feltman and Jody Meyer felt that she deserved an award for this accomplishment, so they created one and presented it to her at the keynote of the 2009 conference. They filled the cup with chocolates because that’s Cathy’s favorite food (not dessert, food).

Since then, it’s been a tradition for the winner to present the award to the next year’s top-ranked speaker, so Cathy presented it to Rick Schummer for being the top speaker in 2009 and Rick presented it to me for 2010. I had the pleasure of presenting the award for 2011 to Rick Borup. You can watch the presentation at the 19:50 mark of the streaming keynote. Rick has always been one of my favorite speakers: he’s extremely well-prepared and his sessions are always thought-provoking. We filled the award with unshelled peanuts because Rick is a huge baseball (and peanut) fan. Rick unselfishly shared the peanuts with attendees of his sessions. I went to both of his sessions for 2012, Advanced Topics in Mercurial: Taking it to the Next Level and Amazon Elastic Cloud Computing for Fun and Profit, and think he’s a likely candidate to win it again.

Congratulations and well-deserved, Rick!

2012 Lifetime Achievement Award Recipients

At the keynote for Southwest Fox 2012, we had the pleasure of announcing this year’s recipients of the FoxPro Lifetime Achievement Award: Cathy Knight and Craig Boyd. If you couldn’t make it to the conference, you can watch the awards being presented at the 24:33 mark of the streaming keynote.

image

Cathy is the reigning queen of reporting for Visual FoxPro. In fact, both of her sessions at Southwest Fox were how to get the most of the Report Writer and were among the most popular sessions. I’ve used her tips in countless places in Stonefield Query and it’s a much better product as a result. You can read Cathy’s bio and her thoughts on winning the award.

image

Craig has one of the best VFP blogs on the planet and has developed some of the most insanely useful tools around. I’ve written numerous articles about them in FoxRockX and Rick Schummer did a session about some of Craig’s tools; both just barely scratched the surface. I also use several of his tools and techniques in Stonefield Query. Craig couldn’t be at Southwest Fox to accept the award in person (Bo Durban accepted it on his behalf) but I’ve been assured he watched the streaming keynote. You can read Craig’s bio here.

Congratulations to both Cathy and Craig. Well-deserved!

2012 VFPX Administrators’ Award

The VFPX Administrators’ Award is an annual award given by the VFPX Administrators (Craig Boyd, Rick Schummer, and Doug Hennig) to recognize those people who made outstanding contributions to the VFP community through their projects on VFPX. The nominees this year were:

At the keynote for Southwest Fox 2012, the award was given to both Matt and Jim. Both have done an incredible amount of work this year. Congratulations to both and thanks for all your efforts in making VFPX the future of VFP.

Monday, October 15, 2012

Last Minute Southwest Fox/Xbase++ 2012 Notes

Here are a few last-minute things about this year’s conferences:

  • Due to unforeseen circumstances, the Kokopelli scheduling application will not be available this year.
  • We are streaming the keynote presentation again this year, Thursday at 7:00 p.m. Mountain Standard Time (Arizona does not observe Daylight Savings Time): http://www.ustream.tv/channel/swfoxtv
  • The conference guide is now available for download. Please download and read it because there are important details about the conference you need to know. This is the only copy of the guide you are getting; in our continuing efforts to make our conference greener, we are not printing them this year.

Tuesday, October 02, 2012

Yet another reason to attend Southwest Fox/Southwest Xbase++

Yet another reason to attend Southwest Fox and Southwest Xbase++ 2012! All registered attendees at Southwest Fox and Southwest Xbase++ are eligible to win one of two one-year subscriptions for Visual Studio Professional with MSDN, each worth $799. Register today: http://www.swfox.net/register.aspx

Wednesday, September 26, 2012

Fixing Another Report Designer Issue

A couple of years ago, I blogged about a bug in FRXFormatUtil.ChooseFont. I ran into another issue in that method (not really a bug) recently. If you try to select a font for an object in the Report Designer and don’t have a default printer set up (as is sometimes the case in a Terminal Services environment), you get a “printer not ready” error. It turns out the reason is the use of the “P” switch in the GETFONT() function, which tells the Font dialog to only display fonts for the current printer. That errors out if you don’t have one.

I wrapped the GETFONT() calls in TRY blocks with a retry in the CATCH without the “P” flag. Here’s the updated code:

if THIS.FontCharSet = 0
*** DH 09/26/2012: wrap calls to GETFONT() with "P" switch in TRY and
*** if it fails, retry without that switch to avoid a "printer not ready"
*** error if there's no default printer
    try
        cFontString = getfont( ;
            THIS.FontFace, ;
            THIS.FontSize, ;
            THIS.StyleFlagsToChar( THIS.FontStyle)+"P", ;
            -1 )
    catch
        cFontString = getfont( ;
            THIS.FontFace, ;
            THIS.FontSize, ;
            THIS.StyleFlagsToChar( THIS.FontStyle), ;
            -1 )
    endtry
else
    try
        cFontString = getfont( ;
            THIS.FontFace, ;
            THIS.FontSize, ;
            THIS.StyleFlagsToChar( THIS.FontStyle)+"P", ;
            THIS.FontCharSet )
    catch
        cFontString = getfont( ;
            THIS.FontFace, ;
            THIS.FontSize, ;
            THIS.StyleFlagsToChar( THIS.FontStyle), ;
            THIS.FontCharSet )
    endtry
endif

(Yes, I realize this could be written more efficiently, but I wanted to make the minimum necessary changes to the code.)

Monday, September 24, 2012

More reasons to come to Southwest Fox/Xbase++ 2012

We have more reasons for you to attend Southwest Fox and Southwest Xbase++ 2012:

This year’s keynote address will be given by Jennifer Marsman of Microsoft Corporation. She’ll talk about “Industry Trends in Windows 8”. See http://www.swfox.net/sessionsswfox.aspx#Industry_Trends_in_Windows_8 for a description of this session.

All Southwest Fox attendees receive a free PDF version of the latest VFP book, “VFPX: Open Source Treasure for the VFP Developer,” by Rick Schummer, Tamar E. Granor, Doug Hennig, Jim Nelson, and Eric Selje, courtesy of the German FoxPro User Group, dFPUG.

All attendees receive a free one-year subscription to CoDe magazine, courtesy of EPS Publishing.

Add these to more than 40 different regular conference sessions (Southwest Fox sessions and Southwest Xbase++ sessions) and these concurrent conferences provide an opportunity you shouldn’t miss.

Tuesday, September 18, 2012

Creating iCalendar Files

Last year, we added something new to the Southwest Fox web site: links to iCalendar files on the Schedule page. The idea is that you can click the link for a session to add it to your calendar. It’s not meant as a replacement for Kokopelli, Dave Aring’s cool scheduling app, but so your calendar can remind you when, what, and where your next session is.

iCalendar files are pretty easy to create, as they’re just a text file with an ICS extension. Here’s the one for Steve Bondar’s HTML5 session:

BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VEVENT
DTSTART:2012-10-20T21:00:00Z
DTEND:2012-10-20T22:15:00Z
SUMMARY;ENCODING=QUOTED-PRINTABLE:HTML5 - Stephen J. Bodnar
DESCRIPTION;ENCODING=QUOTED-PRINTABLE:There is a lot of confusion and hype surrounding HTML5. (Rest of text removed for brevity.)
LOCATION;ENCODING=QUOTED-PRINTABLE:Flagstaff
UID:SWFOX20121020T210000Z
PRIORITY:3
END:VEVENT
END:VCALENDAR

The DTSTART and DTEND elements show the start and end date and time in UTC, SUMMARY is the title, DESCRIPTION contains the session abstract, LOCATION has the room name, and UID is a unique ID.

The code to generate this simply uses text merge to insert the appropriate values into a template string. The only wrinkle is getting the date in UTC. Since Phoenix is +7 hours at the time Southwest Fox is held, I cheated and hard-coded the offset value, then used TTOC() to convert the starting and ending date/time values to the desired format:

lnTimeZoneOffset = 7 * 60 * 60
    && Phoenix is 7 hours behind GMT.
lcStart = ttoc(tdStart + lnTimeZoneOffset, 3) + 'Z'
lcEnd   = ttoc(tdEnd   + lnTimeZoneOffset, 3) + 'Z'

A more generic approach is to ask Windows for the current time zone information:

* Declare the time zone information API function and get the time zone
* information.
 
#define TIME_ZONE_SIZE  172
declare integer GetTimeZoneInformation in kernel32 ;
    string @lpTimeZoneInformation
lcTimeZone = replicate(chr(0), TIME_ZONE_SIZE)
lnID       = GetTimeZoneInformation(@lcTimeZone)

* Determine the standard and daylight time offset.
 
lnStandardOffset = ctobin(substr(lcTimeZone,   1, 4), '4RS')
lnDaylightOffset = ctobin(substr(lcTimeZone, 169, 4), '4RS')

* Determine the total offset based on whether the computer is on daylight time
* or not.
 
if lnID = 2  && daylight time
    lnTimeZoneOffset = (lnStandardOffset + lnDaylightOffset) * 60
else   && standard time
    lnTimeZoneOffset = lnStandardOffset * 60
endif lnID = 2

While this works just fine with Microsoft Outlook, I found a problem when trying to add a session to the calendar on my iPhone. I found this blog post by Joe Bradford that suggested the problem might be the wrong MIME type for .ICS files. Checking the IIS settings confirmed I had the same issue as Joe. The easiest way to change the settings for me (since I didn’t have access to the IIS settings directly) was to create a web.config file that changed the MIME setting and add it to the root folder of the web site:

<configuration>
<system.webServer>
   <staticContent>
   <remove fileExtension=".ics" />
     <mimeMap fileExtension=".ics" mimeType="text/calendar" />
   </staticContent>
</system.webServer>
</configuration>

However, that still didn’t resolve the problem; while I didn’t get an error, the session simply didn’t show up in the calendar. Just for grins, I tried to import an ICS file into Google Calendar; while the session did appear in the calendar, it was in the wrong timeslot (almost a year off). I manually created a calendar item and exported it, and noticed a difference in how the start and end date/times were formatted: the same as mine but without dashes or colons:

DTSTART:20121020T210000Z
DTEND:20121020T221500Z

A quick change to the code generating the date/time values fixed that:

lcStart = chrtran(ttoc(tdStart + lnTimeZoneOffset, 3), '-:', '') + 'Z'
lcEnd   = chrtran(ttoc(tdEnd   + lnTimeZoneOffset, 3), '-:', '') + 'Z'

Now I can select the sessions I want (with Kokopelli’s help once it’s ready) and add them to my Outlook, iPhone, or Google Calendar so I’m reminded about each session.

Monday, September 10, 2012

Use Passive FTP

Stonefield Query has a built-in automatic update feature. It basically works like this:

  • Once every X days (where X is configurable by the user), download an XML file from our web server. The file contains the update version number, a list of files to download and install, and HTML describing the changes.
  • If the update version number is newer than the current version number, display the changes to the user and ask if they want to download it.
  • If they do, download and install the files listed in the XML file.

The last step is a little complicated. First, you obviously can’t overwrite the running EXE. Second, in Windows Vista and later, you can’t even write to the program folder without elevating privileges. We take care of that as follows:

  • Download the files to the user’s temporary files folder (which is writable).
  • Using ShellExecute with the “RunAs” parameter, launch an updater EXE and display the User Account Control (UAC) dialog requesting permission to elevate.
  • Quit so the main EXE is no longer running.
  • Have the updater EXE copy the downloaded files to the program folder, unzipping or running a setup program as necessary.
  • Have the updater EXE run the main EXE and then quit itself.

This has normally worked just fine. However, recently we had reports that Stonefield Query would take a long time to start for some users. We have great diagnostics built into Stonefield Query, so we quickly determined that the update checking, which runs at startup, was taking five minutes to execute. That sounded a lot like a timeout, which we confirmed by adding additional diagnostics to the FTP process. Another clue was that the problem only seemed to happen on Windows Server 2008 systems. Once again proving that Google is my friend, I found several possible solutions. The one that seemed most promising was to use passive mode for FTP transfers. Since I use Rick Strahl’s West Wind Client Tools, implementing this was easy: set the wwFTP object’s lPassiveFTP property to .T. Since we ourselves have a Windows Server 2008 server, it was easy to reproduce the problem and confirm that this fixed it.

Once again, Google and Rick save my bacon.

Tuesday, August 28, 2012

Southwest Fox/Xbase++ 2012 Early-Bird Deadline

One last quick reminder: you can save $50 by registering with the early-bird registration discount. The deadline is this Friday, August 31st. Every registered attendee gets admission to all regular conference sessions, whether part of Southwest Fox or Southwest Xbase++, and white papers for all Southwest Fox sessions. http://www.swfox.net

Monday, July 02, 2012

Southwest Fox/Xbase++ Super-Saver Deadline Extended

Great news! We've extended the deadline for SuperSaver registration for Southwest Fox and Southwest Xbase++ 2012. Register by Monday, July 9 and save $125 on your registration fee, and get one free pre-conference or post-conference session. Don't miss the chance to learn from the best and meet your colleagues face-to-face.

Wednesday, June 27, 2012

Southwest Fox/Xbase++ Deadline Looms

Hear that sound? Tick, tick, tick, tick...

That's the countdown clock at Geek Gatherings getting closer to the Super-saver deadline for Southwest Fox and Xbase++! July 1 is only a few days away and we thought we would pass along a reminder just in case you forgot to type it into your task list, or stick it on your monitor on a yellow sticky note.

The conferences take place October 18-21, 2012 in Gilbert, Arizona and we really hope you can be there. We would hate to see you miss out on the $125 discount and the free pre-conference or post-conference session. These sessions are more popular than ever this year. One person has registered for four pre-cons, and all three post-cons!

Already registered? Thanks. Can you help us remind your fellow developers who have been procrastinating that the deadline is looming? Anything else you can do to promote the conference would also be appreciated.

Also, if you sent in your registration and have not received your confirmation, please contact us to see what has happened. Everyone gets a confirmation and a paid invoice as a receipt when registration is processed.

Special drawings for people who register before July 1st:

  • Two White Light Computing Scholarships of $150
  • One Tomorrow's Solutions LLC Scholarship of $150 (only those who have not attended Southwest Fox since 2007 are eligible)
  • One license of Stonefield Query SDK (a $6,000 value; both conferences eligible)

Check out our list of amazing speakers and dig into our session tracks. Follow the news about the conference on our blog.

Tuesday, June 19, 2012

Only 2 More Days to be Eligible to Win a Tablet

There are only two more days (the deadline is June 21) to register for Southwest Fox or Southwest Xbase++ to be eligible for a drawing of a tablet: iPad 2 with 16GB of memory (value of $399), Kindle Fire (value of $199), or Samsung Galaxy Tab 2 (value of $399) (winner gets to pick).

Registering before June 21 also makes you eligible for the other goodies we’re offering (these drawings are from everyone who registers before July 1):

Plus you save $125 off the regular conference price, plus you get a free pre-conference or post-conference session, plus those registering for Southwest Fox get a free copy of Lianja App Builder Standard Edition (valued at $395, courtesy of Lianja Inc.), plus you get access to all the session materials (even those sessions you don’t attend), plus all the networking opportunities, plus … I could go on for a while here, but I think you get the point.

Tuesday, June 12, 2012

New Book on VFPX Coming Soon

Rick Schummer blogged about a new book on VFPX, VFPX: Open Source Treasure for the VFP Developer. He said it all, so I’ll just point you to his blog to read all about it.

Tuesday, June 05, 2012

Southwest Fox/Xbase++ 2012 Solstice Special

Geek Gatherings is adding an incentive to get you to register early. In addition to all the perks you get when registering before July 1st (a $125 discount, a free pre-conference or post-conference session, and a chance for a $150 scholarship or Stonefield Query SDK), one person who registers before June 21st wins a tablet!

The winner will select one of the following:

  • iPad 2 with 16MB of memory (value of $399)
  • Kindle Fire (value of $199)
  • Samsung Galaxy Tab 2 (value of $399)

Winner is selected on July 3, 2012 from the list of people registered before June 21st.

Monday, May 28, 2012

Southwest Fox Attendees Get Free Copy of Lianja

Lianja Inc. is offering a FREE COPY of Lianja App Builder Standard Edition, valued at $395, for all attendees of Southwest Fox. Build data-centric Apps on Windows, Mac or Linux using your Visual FoxPro, Python, PHP or JavaScript expertise and then deploy on the Desktop, Web and Mobile.

Tuesday, May 22, 2012

2012 Ceil Silver Ambassador Announced

Geek Gatherings is pleased to announce that the 2012 Ceil Silver Ambassador is Jun Tangunan. Jun is a well-known member of the Foxite VFP community site and has a great blog at http://sandstorm36.blogspot.com.

The Ceil Silver Ambassador Fund raises money from the VFP community to bring a developer to the Southwest Fox conference as an ambassador for the developers in his or her country. This gives the recipient the opportunity to meet and share experiences with developers attending Southwest Fox and gives other attendees the opportunity to learn about VFP development in the recipient's country.

The Fund is named in memory of Ceil Silver, a long-time member of the Visual FoxPro community, who passed away in January, 2009. Ceil served as Editor of FoxPro Advisor's Tips and Tricks column for many years and was the founder of the Westchester County FoxPro chapter of PADD, the Professional Association of Database Developers. She was also a contributing author to Special Edition Using Visual FoxPro 6. Ceil understood the value of attending professional conferences, and continued to attend them until her failing health prevented it.

Friday, May 18, 2012

Southwest Fox and Xbase++ 2012 News

A couple of announcements about the fall conferences:

First, registration is now open for both Southwest Fox and Southwest Xbase++. Registrations have been already been pouring in, which is great news.

I blogged about this last year, but I think it bears repeating. Last year was a tough, scary year for us. By mid-August, we were in full panic mode, as we were so far below breakeven that it looked like a five-figure loss for us. Fortunately, a larger-than-usual number of people signed up after September 1; that combined with an increase in sponsorship took us over the top. So, one thing I ask: if you love Southwest Fox like we do, and want to see it continue, do us a favor and register early this year. That would take out the panic for us and allow us to plan for the type of conference we really want to host.

Second, speakers and sessions for Southwest Xbase++ are now available. Remember, if you register for one conference, you’re free to attend sessions in the other conference as well: it’s BOGO (buy one, get one free). There are some sessions specifically intended for VFP developers, including Project PolarFox: State of the Union and Xbase++ 2.0 from a VFP Developer's Perspective. Also, some of the Southwest Fox session will appeal to Xbase++ developers, such as Advanced Topics in Mercurial: Taking it to the Next Level, jQuery 101, and Office Automation Without Office.

I think it’s cool that we’ll have a whole new set of attendees (the Xbase++ folks) at the conferences this year. It’ll give us more chances to talk to fellow developers and share cool ideas.

Tamar, Rick, and I are all looking forward to seeing you in Phoenix this October!

Wednesday, May 16, 2012

FoxPro Lifetime Achievement Award 2012

The FoxPro Lifetime Achievement Award honors those individuals who have contributed a great deal to the FoxPro community over the years. See http://fox.wikis.com/wc.dll?Wiki~FoxProCommunityLifetimeAchievementAward~VFP for previous award recipients. These recipients wish to continue the award and have created a committee to select a recipient for 2012. The committee consists of all 11 living previous recipients, Alan Griver (yag), and Sergey Berezniker representing the FoxPro community.

To submit your nominations for the 2012 recipients, please post a comment here by June 15, 2012.

Tuesday, May 01, 2012

Southwest Fox 2012 Speakers and Sessions Announced

Speakers and sessions for Southwest Fox 2012 have been announced. We’re glad to welcome back a couple of speakers who haven’t been to Southwest Fox in a long time: Rod Paddock and Kevin McNeish. And of course Cathy Knight, Kevin Cully, and Rick Strahl, who didn’t speak at the conference last year.

I saw Kevin McNeish’s iPhone/iPad app development track in Germany last year and these sessions are so good, we specifically asked Kevin to do a full-day of training at Southwest Fox this year. If you’re interested in iOS development, register before July 1 so you get half of the day for free!

Some of the sessions I’m personally looking forward to are:

  • Rod’s jQuery session. I’ve heard really good things about it from folks who’ve seen it.
  • Steve’s HTML5 session (notice I didn’t specify “Bodnar”; after having three Steves last year, we only have one this year). I haven’t had a chance to play with the new things in HTML 5 so this will be a good intro.
  • Rick Borup’s Advanced Mercurial session (to make up for the missing Steves, we have three Ricks). Last year, Rick did a killer intro session on Mercurial, so I’m looking forward to moving to the next level.
  • Tuvia’s licensing session. Licensing and updates are key components in Stonefield Query, so I’d like to compare Tuvia’s approach to ours.
  • Christof’s unit testing session. Christof is a speaker’s speaker: he’s the one all speakers attend because his sessions are always so thought-provoking. Also, I’ve really gotten into unit testing in the past year, so I’d like to see his approach.

I’m very excited by this year’s lineup and think you will be too. Registration opens in a couple of weeks with a new online registration site. See you in October!

Wednesday, April 04, 2012

2012 FoxPro Lifetime Achievement Award Committee

The FoxPro Lifetime Achievement Award honors those individuals who have contributed a great deal to the FoxPro community over the years. See http://fox.wikis.com/wc.dll?Wiki~FoxProCommunityLifetimeAchievementAward~VFP for previous award recipients. These recipients wish to continue the award and have created a committee to select a recipient for 2012. The committee consists of all 11 living previous recipients, Alan Griver (yag) of Microsoft, and one person from the FoxPro community.

If you wish to be considered for inclusion on the committee, please email me (dhennig@stonefield.com) by April 30, 2012. The existing committee will select the community member and announce their selection in early May. The committee will then issue a call for nominations for the 2012 recipient and will make their selection from the nominees.

2012 Ceil Silver Ambassador Nominees

The Ceil Silver Ambassador Fund brings a developer to the Southwest Fox conference in the United States as an ambassador for the developers in his or her country. This gives the recipient the opportunity to meet and share experiences with developers attending Southwest Fox and gives other attendees the opportunity to learn about VFP development in the recipient's country. For more information on the Ambassador Fund or to learn how to contribute to it, please see http://www.swfox.net/ambassador.aspx.

The Ambassador selection committee consists of Southwest Fox organizers Rick Schummer, Tamar Granor, and Doug Hennig, former Ambassadors Emerson Santon Reed, Cesar Chalom, Bernard Bout, and Borislav Borissov, and VFP community members Christof Wollenhaupt and Rick Bean.
We are looking for nominations from the VFP community for the 2012 recipient. To nominate someone you think is deserving to be selected, please email their name and a brief list of their contributions to the VFP community to ambassadorfund@swfox.net. Names must be submitted no later than April 30, 2012.

Thursday, March 29, 2012

The Internet (and my wife) Literally Saved my Life

A couple of weeks ago, I slipped on an icy sidewalk taking out the garbage and thought I’d sprained my ankle. (Nice timing: by the next day, all the ice and snow was gone!) Although I felt something go “pop” inside, I was sure it wasn’t broken because within five minutes I could put a little weight on it (I limped back into the house) and within an hour was able to put almost my full weight on it. I spent the morning elevating and icing it. At lunch, my wife came home from work and insisted she take me for an x-ray. The doctor assured us it wasn’t broken but took an x-ray just in case. Was he surprised to see a double break in the fibula just above where it meets the ankle. Also, the entire ankle was dislocated a few millimeters to the left. (And of course it was sprained too, but that goes with the territory.) I had surgery that night to screw a plate into place to hold things together and reset the ankle displacement.

Life is a hassle dealing with an immobilized leg and crutches: you can’t carry anything so someone has to fetch stuff for you, taking a shower is a major production, stairs are scary, and I have to keep my leg elevated a lot to keep my foot from swelling too much. So, that means only a couple of hours a day at the computer and sleeping in a spare bedroom on the main floor of our house. My poor wife Peggy: her work load about tripled: doing all of my household chores in addition to hers plus taking care of me. I’m going to owe her big time once I get back on my feet!

Fast forward almost two weeks. Feeling like my life is on hold for six weeks but getting through it OK. Virtually no pain in my ankle. We drove to Winnipeg for the Canada West Short Track Speed Skating Championships, which my son qualified for. After a day of watching skating on Saturday, I developed a low-grade fever and some back pain right after dinner. It cleared up Sunday, but then I awoke about midnight Sunday night to the most excruciating pain I’d ever felt. Every breath felt like someone was stabbing me with a knife in my left-side ribs. I took some muscle relaxants and after they kicked in, I was able to fall asleep sitting up (laying down was still too painful).

Monday was much better. Still had a low-grade fever but the rib pain was manageable. We drove back home from Winnipeg and Peggy and I discussed what could have caused the pain and fever. I was sure it was pulled muscles in my ribs: I’d been sitting in a cold arena for a couple of days, getting up and down the bleachers, probably straining muscles in the process. I had something similar happen about six months earlier: I sneezed while in an awkward position and pulled the muscles in my right ribcage, and this felt just like that. However, I couldn’t explain the fever, so Peggy had me Google “fever after surgery” on our iPad while I rested on the couch.

The most common cause is infection, but since I didn’t have any pain in my leg, I doubted that was it. A few others didn’t make sense in my case, but one thing did seem slightly reasonable: pulmonary embolism. Circulation in an immobilized leg is reduced and as a result, a clot can form. If part of the clot breaks off, it can travel up and get stuck in the lung, causing chest pain, especially when taking deep breaths, and low-grade fever. However, it’s also often accompanied by altered heart rhythm, shortness of breath, and other symptoms I didn’t have. Plus the pain really felt like it was in my ribs rather than in my lungs and I didn’t think muscle relaxants would relieve lung pain. I was about to write that one off too when a sentence caught my eye: pulmonary embolism is fatal if untreated. I mentioned that to Peggy and she insisted we go to the ER the next morning. I agreed, thinking we’d eliminate that possibility and find the real issue.

After some preliminary tests, the doctor figured it was either a clot or pneumonia. I told him “I hope I have pneumonia. Hmm, I doubt that’s a sentence that’s been said before”. He laughed but agreed with me. After more tests, x-rays, and even a CT scan, the diagnosis came back: pulmonary embolism. Crap.

Fortunately, the treatment is straight-forward: blood thinners for six months to prevent further clotting and eventually the existing clots will erode. Blood thinners have their own hassles—I have to inject my belly twice a day for the next four days with a fast-acting blood thinner; I need daily blood tests for at least a week to make sure the dosage of blood thinner pills is correct; certain foods, such as spinach, are off limits; bruises form easily; I have to wear a compression stocking after the cast comes off (like that won’t make me feel like I’m an 80 year-old); and alcohol is discouraged (nooooooooo!). However, the doctor and several nurses told me while I was unlucky to have this happen, I was lucky it was a small clot (a larger one could’ve caused sudden death) and that we came into the ER early (lots of people wait for days, hoping the symptoms will go away on their own).

So, there are two morals to this story (well, three: stuff happens, so deal with it):

  • Don’t be afraid to get an unlikely, even exotic-sounding, potential problem checked out. No one will laugh at you. Google is definitely your friend.
  • Always listen to your wife. Always. She is smarter than you.

Monday, March 19, 2012

Southwest Fox 2012 Session Proposals Due This Week

Just a reminder that session proposals for Southwest Fox 2012 are due by 8 AM EDT this Friday, March 23. If you’re interested in speaking, please download the Call for Speakers and the proposal application from http://www.swfox.net/CallForSpeakers.aspx. We look forward to hearing from you.

Tuesday, March 06, 2012

Southwest Fox 2012

Save the dates for Southwest Fox and Southwest Xbase++ 2012! The conferences take place October 18-21, 2012.

This year we have two conferences as one great event at the same location. Southwest Fox has always served Visual FoxPro developers an opportunity to learn and extend their skills, and network with fellow developers. Alaska Software is working on PolarFox, a product that keeps the Visual FoxPro language alive in their next generation tool. You get two conferences for the price of one!

The conferences take place at the San Tan Elegante Conference and Reception Center, the same great location as last year.

If you’re interested in presenting at Southwest Fox 2012, please visit http://www.swfox.net/callforspeakers.aspx, read the complete Call for Speakers document (linked from that page), and download the proposal submission application. Session proposals are due by March 23.

Finally, if there are any topics you hope will be covered this year, please send them to info@swfox.net, right away.

Friday, February 10, 2012

Automatic Property Testing

Suppose you have a class that looks like this:

public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}

private string _Phone;

public string Phone
{
get
{
return _Phone;
}
set
{
if (_Phone != value)
{
_Name = value;
OnPropertyChanged("Phone");
}
}
}

private string _Name;

public string Name
{
get
{
return _Name;
}
set
{
if (_Name != value)
{
_Name = value;
}
}
}
}


It’s a simple person class with Name and Phone properties. Because it implements INotifyPropertyChanged, the setter for every property should raise the PropertyChanged event. However, there are two bugs in this class:




  • The setter for Phone sets _Name rather than _Phone.


  • The developer forgot to raise PropertyChanged in the setter for Name.



We want to write some unit tests for this class. We need at least two tests for every property: one ensuring the value stored to the property is the one read from it and one ensuring that storing a value raises PropertyChanged. Here’s an example of the tests for Phone:



private string changedProperty;

public void PropertyChanged(object sender,
System.ComponentModel.PropertyChangedEventArgs e)
{
changedProperty = e.PropertyName;
}

[TestMethod()]
public void Phone_ValueTest()
{
Person target = new Person();
string expected = "555-555-5555";
target.Phone = expected;
string actual = target.Phone;
Assert.AreEqual(expected, actual);
}

[TestMethod()]
public void Phone_RaisesPropertyChanged()
{
Person target = new Person();
target.PropertyChanged += new
PropertyChangedEventHandler(PropertyChanged);
target.Phone = "555-555-5555";
string actual = changedProperty;
string expected = "Phone";
Assert.AreEqual(expected, actual);
}


As you can guess, it’s quickly going to get tedious writing these tests, especially if you have a lot of properties. Let’s automate this.



ClassTester is a project on CodePlex (http://classtester.codeplex.com) that automatically tests every property to ensure the value written is the value read and, if the class implements INotifyPropertyChanged, writing to the property raises PropertyChanged. Using ClassTester couldn’t be easier: replace all of the property test methods with this one simple method:



[TestMethod()]
public void AutomaticPropertyChangedTest()
{
PropertyTester tester = new PropertyTester(new Person());
tester.TestProperties();
}


Nice and (almost) generic: we can use this test forevery class; the only change we have to make is the name of the class to test.



When run, this test fails with the error “The get value of the 'Phone' property on the type 'AutomaticPropertyTesting.Person' did not equal the set value”. That points out the first bug, so we fix that by changing “_Name” to “_Phone” in the setter for Phone. (If this seems far-fetched, I actually ran into that today; the hazards of copy and paste coding!) Running the test again still gives a failure: “The property 'Name' on the type 'AutomaticPropertyTesting.Person' did not throw a PropertyChangedEvent”. Adding OnPropertyChanged(“Phone”) to the setter for Name doesn’t fix the problem; only the correct OnPropertyChanged(“Name”) allows the test to pass.



Let’s make the class a little more complex by adding an ID property that’s automatically set to a new Guid value when the class is instantiated. Note that the setter is private so only this class can change the value, such as when a person is loaded from a database, and that it doesn’t raise PropertyChanged because of this.



private Guid _id = Guid.NewGuid();

public
Guid ID
{
get
{
return _id;
}

private set
{
_id = value;
}
}

Now the test fails again: “The property 'ID' on the type 'AutomaticPropertyTesting.Person' did not throw a PropertyChangedEvent”. Fortunately, ClassTester has a mechanism to ignore certain properties: you can add this to the test method:

tester.IgnoredProperties.Add("ID");


Of course, you’d have to do that for every property you don’t want automatically tested (not only for this reason, but some others described on the Codeplex site, such as when a property’s type is an interface or a class with a non-default constructor). That can get a little tedious too. So, I created a couple of classes to further automate this.



The first class is a new attribute:



public class DontAutomaticallyTestAttribute : Attribute {}


The second class is a façade for PropertyTester. What it brings to the table is automatically adding properties marked with the DontAutomaticallyTest attribute to the IgnoredProperties list.



public class PropertyTest
{
private object _toBeTested;

public PropertyTest(object toBeTested)
{
_toBeTested = toBeTested;
}

public void TestProperties()
{
PropertyTester tester = new PropertyTester(_toBeTested);
PropertyInfo[] props = _toBeTested.GetType().GetProperties(
BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo prop in props)
{
if (DontTest(prop))
{
tester.IgnoredProperties.Add(prop.Name);
}
}
tester.TestProperties();
}

private bool DontTest(PropertyInfo property)
{
return property.GetCustomAttributes(
typeof(DontAutomaticallyTestAttribute), false).Length > 0;
}
}


Now you change the line of code in AutomaticPropertyChangedTest to use the new class:



PropertyTest tester = new PropertyTest(new Person());



and add the DontAutomaticallyTest attribute to those properties you don’t want automatically tested (you will write manual tests, won’t you?):



[DontAutomaticallyTest]
public Guid ID


Of course, you also have to add a reference to the project holding these two classes to both the project for your classes and your test project. However, for a couple of minutes work, you can now save tons of time creating tests for all the properties in your classes.

Sunday, February 05, 2012

Updating the VFPX ReportBuilder.APP

There are a couple of bugs in the VFP 9 Service Pack 2 version of ReportBuilder.APP, which provides the Report Designer dialogs and event handlers. I discussed the first bug, which causes the Printer Environment setting for a report to be turned on when you click the font button in the Field or Label Properties dialogs, in an earlier blog post. The other is a small one: using code like:

do (_reportbuilder) with 3, "TablePath.DBF"

to specify a custom registry table causes DELETED to be set off. The fix for this is simple: save the current setting of DELETED in FRXBuilder.PRG before setting it off and restore the setting near the end.

Several people suggested I actually implement these fixes in the copy of ReportBuilder.APP (and the corresponding source code) available on VFPX, so I did so today.