Wednesday, June 24, 2015

Southwest Fox 2015 Super-Saver Deadline Approaches

The countdown clock is ticking! The Super-Saver deadline for Southwest Fox and Southwest Xbase++ 2015 is June 30th, less than a week away. We still need people to register to make the conferences happen.

The conferences take place October 15-18, 2015 in Gilbert, Arizona and we really hope you can be there. We would hate to see you miss out on the $125 discount, the FREE pre-conference session, and an opportunity to win a scholarship or a license of Stonefield Query SDK (a $6,000 value).

After checking out our list of amazing speakers and digging into our session tracks for VFP and Xbase++, head over to the registration Web site today:

Friday, June 12, 2015

Listen to the FoxShow #80

Andrew MacNeill posted the latest version of the FoxShow featuring an interview with Rick, Tamar, and I about Southwest Fox and Southwest Xbase++ 2015.

Wednesday, June 10, 2015

Displaying Balloon Tips with Listboxes

Stonefield Query makes it very simple to create a report: select the fields you want, set the properties of those fields as necessary, and click Preview to run the report. However, sometimes it’s hard to tell exactly what the report will look like until you do preview it: you may have grouped on one field, summed another, changed the font for a third, and so on. You have to go into the Properties dialog for each field to see how it’s formatted in the report. For example, in this report, you can’t immediately tell how each field appears in the report:


One of the things we wanted to add is the ability to see the formatting for each field without having to go into the Properties dialog for each one. We decided to do that using balloon tips.

ctl32_BalloonTip is a class created by Carlos Alloatti that’s part of his ctl32 library. It provides the ability to display balloon tips in a VFP form. Balloon tips are similar to tool tips but are much more attractive, give you greater control over their appearance, and can display a lot more text. I discussed this class in detail in the July 2011 issue of FoxRockX. Here, you can see that the Freight field is summed at group breaks, displays the percentage of the total, and is formatted as a currency value. All you have to do is hover your mouse over the field in the list and the balloon tip tells you what you need to know.


Getting the balloon tip to display the settings for the field under the mouse pointer was a little tricky. The biggest issue is how to know what “line” the mouse is over in the list. There isn’t a property of the Listbox class that tells you that so you have to calculate it using the following factors:
  • The current mouse position. If you do this in the MouseMove event like I do, the X and Y coordinates are passed as parameters; it’s the Y value we need. However, the Y value is relative to the form, so we have to subtract the location of the top of the Listbox. We can’t use the Top property because the Listbox may be inside a container (in this case, it is), so we’ll use OBJTOCLIENT() to get the top of the Listbox relative to the form.
  • The height of a line. We can get that using FONTMETRIC(1) to measure the height using the Listbox’s FontName and FontSize properties. We’ll then divide the calculated mouse Y position by the height to get the line number.
  • Where the Listbox is scrolled to. If the user scrolls the list, the line number of the item under the mouse needs to be adjusted by how far down the user scrolled. Fortunately, the TopIndex property of Listbox tells us that, so we’ll add that to the value calculated above.
Here’s the code for the MouseMove method of the Listbox:

lparameters tnButton, ;
     tnShift, ;
     tnXCoord, ;
local lnHeight, ;
    lnLine, ;
    lcLine, ;
    lcField, ;
lnHeight = fontmetric(1, This.FontName, This.FontSize) + 2
lnLine   = int((tnYCoord - objtoclient(This, 1))/lnHeight) + ;
lcLine   = transform(lnLine)
lcField  = This.List[lnLine, 2]
if This.Tag <> lcLine and not empty(lcField)
      loField = Thisform.oReport.oFieldsCollection.Item(lcField)
      if vartype(loField) = 'O'
      endif vartype(loField) = 'O'
      This.Tag = lcLine
endif This.Tag <> lcLine ...

A few things about this code:
  • There’s a little space between lines in the list, so we have to adjust the value returned by FONTMETRIC(1). I thought adding FONTMETRIC(4) (the leading) would be reasonable but that ended up being too high. I hate using a constant like “2” here but am not sure what the adjustment value can be derived from.

  • Not everyone knows this, but the List and ListItem members of Listbox can be 2-dimensional arrays. In this case, the first column of the current row contains the caption of the field displayed to the user and the second column contains the field name, which is used as an index into a collection of the fields in the report. To add a second column to List and ListItem, use code like:

    list.AddListItem(lcFieldName, list.NewItemID, 2)

  • MouseMove fires when the mouse moves even a pixel. We really only need to update the balloon tip when the user moves the mouse to a new line, so we put the line number into the Tag property (I could’ve added a specific property to a Listbox subclass but didn’t want to change the class used in the existing form) and only call the form’s HandleBalloonTip method when the line changes.

  • HandleBalloonTip does the actual work of displaying the balloon tip. I’m not going to show the code here because it’s fairly lengthy and specific to Stonefield Query. Basically, the code consists of building a string of the contents to display in the balloon tip and then displaying it using:

    This.oBalloonTip.ctlShow(6, lcText, toField.cCaption, 1)

    6 means display the balloon tip at the mouse location and 1 means use the information icon in the balloon tip.
That’s it. Not a lot of code, but it took a few minutes to work out the calculations to get the item under the mouse. Hopefully, this blog post inspires you to look at Carlo’s balloon tip control and saves you some time if you want to use it with listboxes.

Monday, June 01, 2015

Registration for Southwest Fox 2015 now available

Registration for Southwest Fox ( is now available. See for a list of speakers and for a list of sessions. Super-Saver Registration, which saves you $125, is available only through June 30th, so don't wait.

Putting on a conference is a risky endeavor. Conference centers require a guaranteed minimum income to block the dates of a conference; for a conference like Southwest Fox, that minimum is in the tens of thousands of dollars. We have to commit to the conference center by July 2nd and need your support by July 1st to make that commitment. We will not send out any "We need your help" appeals so please do not wait; register by June 30th! We know most of you like to wait until the last minute to avoid the credit card bill arriving too soon. We will not charge any attendee credit cards or cash any checks until we have committed to going forward (sometime after July 2), so this is not is a reason to wait.

Rick, Tamar, and I look forward to seeing you in October!