Goodbye My Friend – Lance Washington (1967-2016)

Lance Washington 1967-2016

I met my best friend, Lance Washington, while we were working at QVC shopping channel almost thirty years ago.  We worked the overnight shift, answering telephones and taking orders.  I had relocated to Pennsylvania from Tennessee, and kept to myself at work (my southern accent meant I had to repeat everything I said – people just loved listening to my accent – so I stayed pretty quiet).  I typically sat alone, read books during my shift, ate lunch alone, took breaks alone.

One night, I heard some boisterous laughter from the row behind me.  There was Lance, standing and laughing with everyone around him.  He towered over everyone. There was a group of people around him, literally waiting to hear what he would say next.

I wondered to myself, “Who is this guy, and why is he so popular?”

I didn’t know at the time that he was wondering about me, “Who is this guy, and why is he always in a shell by himself?”

Eventually, Lance introduced himself to me, and we discovered we had a shared passion – we both loved movies.  We quickly became friends, and we often went to the movies together, usually at least once a week.  We did have our differences, though.  Lance was a Star Trek person – I’m Star Wars all the way.

A few years later, I relocated back to Tennessee, and we lost touch.  I often wondered how Lance was doing, and where he was, but almost twenty years had passed.  I wondered if he ever thought about me.

Then one night I got a comment on my blog.  A simple, one-line comment: “Have you ever danced with the devil in the pale moonlight?” (The original Batman movie in 1989 was one of my favorites.)  I knew immediately it was Lance.  After twenty years, he had found me, and our friendship was reborn.

He met my son Nicholas – now an adult.  Lance had not seen Nick since Nick was a baby, yet took him in like he was family. Nick has called him Uncle Lance ever since.

This past July, Lance was spending a week in Gatlinburg, TN, and invited us to come out and spend some time with him.  Nicholas went, and I took my youngest son Jonathan and his friend Kason.  Jonathan and Kason were instantly taken with Lance, and started calling him “Uncle Lance” immediately.

We spent a few days in Gatlinburg, and though he had several health issues Lance spent a day with us walking through Gatlinburg, going to museums and posing for an old-time photo.  It was a great day.  On the last day together, we had pancakes at one of the pancake restaurants in Pigeon Forge, then said our goodbyes (and started planning a trip for next year).

Unfortunately, Lance won’t be there in person next year.  He passed away last Friday (September 16, 2016) at the age of 48.

In this day of Facebook and other social media, it seems everyone has thousands of friends.  But there’s usually just a very special one or two people in our lives we consider to be our closest, truest friends.  The kind of friends you can count on one hand.  The stars of your own personal movie.

Lance was, for me, that one true friend.

I’m the kind of person who remembers “events” – I remember going places, who went with me, but the details of the events usually leave my memory over time.

Lance remembered “moments” – he recalled details of events we shared almost thirty years ago to my boys, all the way down to the weather of the day.  He had an incredible memory, and as he told the stories of our times together – complete with his infectious laugh – I could see those times were as important to him as they were to me.

There are some people you meet in life and you know your life is better simply because they were a part of it.  The world seems dimmer today, as it has truly lost a shining light.

Goodbye my friend.  Thank you for allowing me to be a part of your life. Thank you for being such an important part of my life. I will miss you and love you for the rest of my days.

Rest in peace.

Kevin, Lance, Kason, Jonathan

Windows 10, IE Web Browser Control, and FEATURE_BROWSER_EMULATION

I’ve got a Visual FoxPro app that uses the Microsoft Web Browser ActiveX control as the primary UI.

A few years ago, I needed to “upgrade” the pages being rendered by the Web Browser Control to a more modern look and feel (think HTML5), and found that many of the changes I had made simply weren’t working – all thanks to the Web Browser Control using IE7 rendering mode.

That’s when I discovered the FEATURE_BROWSER_EMULATION registry key (thanks to Rick Strahl). Rick has written about this key several times on his blog:

Web Browser Control – Specifying the IE Version (May 11, 2011 – Updated 7/19/2014)

Make Your CHM Help Files Show HTML5 and CSS3 Content (February 15, 2012)

HTML5 and CSS3 Editing in Windows Live Writer (July 8, 2013)

After reading Rick’s original post, I took the “clever” way out by adding the registry key to my InnoSetup script, and setting the Value of the key to zero (0). Setting the key to zero tells the Web Browser Control to render pages using the currently installed version of IE on the users computer.

This has worked well for me the past couple of years.

Until this weekend.

On Saturday, I updated my Windows 10 virtual machine to Build 10130, and started up my app.

The app loaded fine, but instead of rendering the “home” page as it should, there was nothing but a blank white area where the Web Browser Control sits. Even worse, when I closed the app, the EXE continued running in Windows Task Manager. This is a problem, since I prevent more than one instance of the app from running on a machine. Double-clicking the icon to start the app again did nothing, as the EXE was still running – but was invisible.

After trying several different things to get the page to load, I finally removed the registry key for FEATURE_BROSWER_EMULATION for the application EXE – I restarted the app, and it rendered the pages perfectly.

I’ve jumped through several different values for the registry key, and it seems no matter which value I choose the Web Browser Control (in Windows 10 Build 10130) renders the pages based on the version of Internet Explorer that is installed (in my case, IE 11).

This piqued my curiosity for other versions of Windows, and it appears I can set the decimal value for FEATURE_BROWSER_EMULATION to 11000 (IE11 Standards mode) for all OSes from XP forward to ensure the Web Browser Control will render pages based on the version of Internet Explorer that is installed. In Windows XP (which can only go to IE8, the pages rendered as I expected them to render for IE8).

Southwest Fox 2015 Speakers and Sessions

Speakers and sessions for the Southwest Fox and Southwest Xbase++ conferences have been announced!

The Southwest Fox 2015 Conference has fewer speakers and tracks this year (eight and two, respectively), but there is a chance that more speakers could be added, depending on the number of registrations by July 1st.

The list of speakers for 2015 is impressive:

  • Toni Feltman
  • Tamar Granor
  • Doug Hennig
  • Cathy Pountney
  • Rick Schummer
  • Phil Sherwood
  • Rick Strahl
  • Christof Wollenhaupt

You can view specific session details at the Southwest Fox 2015 Sessions page. Two sessions I’m really interested in are Tamar’s “Can’t This Application Go Any Faster?” and Doug’s “50 Shades of Grey: Whipping Your Application’s UI Into Shape“.

Southwest Fox 2015 is the only Visual FoxPro developer’s conference in North America. If you’ve never been, I highly recommend making an effort to go this year. It’s a great learning experience, shared with fellow Visual FoxPro developers.

A few of the Southwest Xbase++ sessions for 2015 have piqued my interest, too.

The conferences will be held October 15-18 at the SanTan Elegante Conference Center in beautiful Gilbert, Arizona.

Registration starts June 1st, with the same registration fee as last year!

I’m looking forward to going this year. Hope to see you there!

I Need Some SUBSTR() Help, Please!

Last week, I presented a session titled, “Unicode Made Easier with SQLite” at the Southwest Fox 2014 conference.

At the end of the session, an attendee asked about manipulating strings, specifically using SUBSTR() on UTF-8 encoded strings.

Last night, I played around with creating my own SUBSTR() function to deal with UTF-8 encoded strings, and I think I may have been successful, but I’m not sure.

If there are any readers that can tell me if the image below looks correct for a SUBSTR(2,3) on the Russian phrase in the textbox, I would appreciate it very much.

On the other hand, if you think I’m going down a rabbit hole that doesn’t need to be traveled, please let me know. I would hate to think I’ve wasted time “substringing” a phrase for which there is really no need for “substringing.”

Thank you in advance for any help!

Unicode SUBSTR() Example

Southwest Fox 2014

There’s only a few days left…

Registration for Southwest Fox 2014 and Southwest Xbase++ 2014 is open, and there’s only a few days left to save $125 and receive a free half-day pre-conference session.

Pre-conference sessions are three-hours long, which provide a great opportunity to dive deeper into the session topic.

There are four pre-conference sessions for Southwest Fox 2014:

  • Desktop to the Web? No Need to Eat that Elephant in One Bite (Bo Durban)
  • Lessons Learned: SQL Server (Christof Wollenhaupt)
  • PostgreSQL vs Microsoft SQL Server (Frank Perez)
  • Web APIs: Getting Paid, Making Calls and Other Cool Tricks (Steve Bodnar)

Pre-conference sessions for Southwest Xbase++ 2014 include Frank’s and Steve’s sessions above, and:

  • eXpress++ Pre-Conference Workshop (Roger Donnay)
  • Xbase++ 2.0 Workshop (Steffan Pirsig)

I’m very excited to be coming back this year. It will be my first trip back to Southwest Fox since 2011. I’ll be presenting two conference sessions: More Multi-threading with Visual FoxPro, and Easier Unicode with SQLite.

Remember, just a few more days are left to save some money and receive a free pre-conference session, so visit the registration page today to learn more about these awesome conferences!

A Hyperlink Class: Subclassing the Label Control

Updated December 18, 2013: Source code for lblHyperlink is available here, parent class (lblLabel) source is available here.

The lblHyperlink label subclass

One of the more popular movements in desktop applications is “webification.” Users have become so used to the web interface via their browser, more and more desktop apps have added clickable hyperlinks as an important part of their UI. I’ve created a subclass of the lblLabel Visual FoxPro Label Control class to mimic a hyperlink.

This subclass of the contains the following properties which override the parent class:

MousePointer = 15
ForeColor = RGB(0,102,204)
Name = "lblHyperlink"

I set the ForeColor to a “blue”, simply for the visual cue in design time that I’m working with a “hyperlink” instead of a plain old label.

Plus a couple of other properties, for the ForeColor (we’ll change the ForeColor when the user hovers over the link):

nForeColor = 0
nHoverColor = 0

We’ll change the MousePointer to 15 (Hand), as a visual indication that it’s a link. I want the ForeColor of the link to be whatever Windows says the COLOR_HOTLIGHT (from GetSysColor()) should be for a hyperlink, and when the user hovers over the link I’ll change it to the COLOR_MENUHILIGHT value.

We’ll set the ForeColor (and hover color) in the Init event:

PROCEDURE Init
  DODEFAULT()

  ** Use GetSysColor to get the hyperlink color
  DECLARE INTEGER GetSysColor IN "user32" INTEGER nIndex

  This.nForeColor = GetSysColor(26)  && COLOR_HOTLIGHT
  This.nHoverColor = GetSysColor(29) && MENU_HOTLIGHT
ENDPROC

We’ll also add some code to the MouseEnter and MouseLeave events:

PROCEDURE MouseEnter
  LPARAMETERS nButton, nShift, nXCoord, nYCoord
  WITH THIS
    .ForeColor = .nHoverColor
    .FontUnderline = .T.
    .Caption = .Caption
  ENDWITH
ENDPROC

We set the ForeColor to the COLOR_MENUHILIGHT color and underline the label, just to provide an additional visual cue to the user at runtime that this is a hyperlink.

Notice the .Caption = .Caption line? I’ve seen “bleeding” with some form controls (including labels from time to time, when the app is minimized then restored) which have a BackStyle = 0 (Transparent). This line corrects the problem with “bleeding.”

The MouseLeave event looks like this:

PROCEDURE MouseLeave
  LPARAMETERS nButton, nShift, nXCoord, nYCoord
  WITH THIS
    .ForeColor = .nForeColor
    .FontUnderline = .F.
    .Caption = .Caption
  ENDWITH
ENDPROC

Once again we reset the ForeColor back to the COLOR_HOTLIGHT value in GetSysColor(). Then we remove the underline, and do the “bleeding” fix, just in case.

This is, of course, just basic functionality. To really make this shine, I recommend viewing Tamar Granor’s presentation “BindEvents for Better Applications” from the Online Visual FoxPro Users Group (OFUG) meeting (recorded on Tuesday, February 19, 2013).

And we’re done with the hyperlink!

Well, almost done. Since the hyperlink control is based on a Label, the link cannot get focus by using the keyboard. We need a way to be able to select (and click) the link without a mouse.

Enter, a container object.

The cntHyperlink container class

The cntHyperlink container class consists of a container object which contains the aforementioned lblHyperlink label and a CommandButton.

It is a subclass of cntContainer (shown below).

cntContainer has a custom abstract method named OnClick, which is called in the Click event:

DEFINE CLASS cntContainer AS Container
  Width = 194
  Height = 75
  BackStyle = 0
  BorderWidth = 0
  Name = "cntContainer"

  PROCEDURE onclick
    ** Abstract method called by the Click() event
  ENDPROC

  PROCEDURE Click
    This.OnClick()
  ENDPROC
ENDDEFINE

The cntHyperlink class has a custom property named cHotKey, which you could use as a hot key for the hyperlink:

cHotKey = ""

It also contains a lblHyperlink label. It remains the same, except we’ll add the following code in the OnClick() method which will “bubble up” to the parent container:

PROCEDURE lblHyperlink.OnClick
  This.Parent.OnClick()
ENDPROC

cntHyperlink container also has an OnClick() method, inherited from cntContainer.

We also have a CommandButton subclass added to the container. It contains the following events: LostFocus, GotFocus, and Init. It also contains a method named OnClick() (as do most of the controls in my base classes).

PROCEDURE cmdButton.LostFocus
  This.Parent.LostFocus()
ENDPROC

PROCEDURE cmdButton.GotFocus
  This.Parent.GotFocus()
ENDPROC

PROCEDURE cmdButton.Init
  This.Height = 0
  This.Width = 0
ENDPROC

PROCEDURE cmdButton.OnClick
  This.Parent.OnClick()
ENDPROC

Since it’s a hyperlink control, I don’t want the button to be visible on the form. In the Init event, we’ll size it to zero height and zero width. The GotFocus, LostFocus, and OnClick events simply “bubble up” to the parent container.

We’re done with the label and button, so all we have left is the container itself. In the Init, we add the following code which sets the Caption of the button to the cHotKey if it has been set:

PROCEDURE Init
  DODEFAULT()

  IF !EMPTY(This.cHotKey)
    This.cmdButton.Caption = "<" + This.cHotKey
  ENDIF
ENDPROC

Since we’re “bubbling up” events from the command button, we’ll add the following code to the GotFocus and LostFocus events:

PROCEDURE GotFocus
  WITH THIS
    .lblHyperlink.ForeColor = .lblHyperlink.nHoverColor
    .lblHyperlink.FontUnderline = .T.
  ENDWITH
ENDPROC

PROCEDURE LostFocus
  WITH THIS
    .lblHyperlink.ForeColor = .lblHyperlink.nForeColor
    .lblHyperlink.FontUnderline = .F.
  ENDWITH
ENDPROC

And now we’re finally ready to place the instance of the cntHyperlink class on a form, complete with Tab Order functionality, hot key functionality, etc.

All we’ll need is to add the instance code for the container OnClick() method to handle the actual clicks on the hyperlink.