The FoxTabs Challenge

 

The latest FoxRockX issue includes an article on FoxTabs by Rick Schummer. After months of neglect, that inspired me to get another release out, so you can now grab FoxTabs 0.9 beta from VFPX. My feeling is that FoxTabs is now “feature complete” for a 1.0 release, although I would not be surprised if there are a few more releases to shake out any remaining bugs. Please download the latest version and help us get to 1.0!

As Rick points out in the article, stability can be an issue, especially while testing your code in the ide. To that end, I added a pause button that removes all event bindings temporarily. If things get a little flaky during testing, or if you just don’t want to risk any interference from FoxTabs, press the pause button. When you’re done, press resume and you’re back in business.

Wikipedia says the following about observation:

One problem encountered throughout scientific fields is that the observation may affect the process being observed, resulting in a different outcome than if the process was unobserved.

Unfortunately, that can sometimes be the case with FoxTabs, making stability the number one challenge of this project. We have come a long way since the initial release of FoxTabs, but there is more work to do. Capturing and responding to the myriads of events flying around can sometimes cause unpredictable results.

This is compounded by the fact that the various VFP IDE windows are not exactly consistent in their behavior. For example, most IDE windows broadcast a WM_SETFOCUS message when activated, which FoxTabs uses to highlight the associated tab. But the Project Manager doesn’t send out a WM_SETFOCUS. Why not? I don’t know. Neither does the Properties window, but it’s different than the Project Manager, because each of its tabs sends out its own messages. I had to find the right combination of events and messages, so that FoxTabs responds consistently to all IDE windows. This can be frustrating, but it’s also interesting, because you get a tiny peek at what’s going on under the hood.

Of a more serious nature is when some amalgamation of events combined with FoxTabs produces unexpected results, or worse, a C5 crash. That’s when you get the sinking feeling that your productivity tool has just become an un-productivity tool. These can be difficult to track down.

A few months ago a developer reported crashes when opening the debugger. I was able to open the debugger without issue using set step on or a breakpoint. It took me a whole day, but I eventually traced this to the Call Stack window, which only caused a crash if you opened it after suspending a program. It was a very specific set of circumstances that led to the crash. Fortunately, I was able to find a workaround.

Another interesting case was fixed in the latest version. Opening the expression builder
using GetExpr() worked fine. However, if you opened it from the functions and expressions button in the view designer, boom! Fox crashed. I traced the problem to this code from the FoxTabs window event handler:

function wmeventhandler(hwnd as integer, msg as integer, wparam as integer, lparam as integer)

local oexception as exception
local lnreturn as integer
lnreturn = 0
***
black hole: hwnd and msg do not exist ***
…
* must pass the message on
lnreturn = callwindowproc(this.prevwndfunc, hwnd, msg, wparam, lparam)
return lnreturn

endfunc

Windows events pass four parameters to the event handler: hwnd, msg, wparam, and lparam. When opening the expression builder from the view designer, those variables don’t exist in the event handler. I don’t mean that they are not assigned a value, I mean that they do not exist! How is that possible given that the variables are clearly defined as parameters only a few lines earlier? It’s as if they were sucked into a black hole and out of existence. When you try to access the variables or pass the event on to its original destination (CallWindowProc), Fox crashes because nothing is there. It’s one of the strangest things I’ve seen in Fox. I was able to plug the hole by checking if the variables exist and simply returning if they do not. My hope is that this is the same hole causing other random C5 errors, and that those are now fixed.

So, yeah, there are some challenges, especially when you’re not a C/C++ programmer and you don’t deal with this kind of stuff every day. But I do have to say it is very satisfying to find solutions to these problems, and I learn a lot in the process. I guess this isn’t the best sales pitch
for using FoxTabs, but I think we’ll get there. I hope you give it a try and let us know how it works for you.

 

Credit Card Security

Credit card security is increasingly becoming an issue.  A couple of years ago, TJ Maxx reported theft of up to 45 million credit card numbers.  More recently, Heartland Payment Systems reported theft of 100 million numbers.  I used to think that stealing a credit card number would be relatively easy, but that purchasing something would lead the authorities right to the front door of the thief.  These days, it is a global problem, and criminals are finding ways to steal without getting caught.

I have a pretty good sense about these things, and in general, I stay out of trouble.  I avoid suspicious downloads, and I only purchase from sites I trust.  In over 20 years of computing, I can count on one hand the number of times I have been infected by a virus, yet in the past 3 months, I have had two fraudulent charges on two different cards.  Google found quite a few instances of other people receiving the same charges I did, and at the same time.  The image of some script kiddie in Nigeria doing this stuff has been erased.  These guys are sophisticated and organized.

It’s no surprise then that credit card companies are clamping down on security requirements for their merchants and software vendors.  We were in the process of adding credit card processing to our application, when our processing partner told us we would have to become PCI PA-DSS compliant.  Evidently, any application that “stores, processes, or transmits” credit card data must go through the compliance process.  That can cost up to $30,000 for the initial review, plus annual costs to keep it current.  The processor offered to walk us through the process and cut our costs to around $15,000.  Um… thanks, but no thanks.  I told them one reason we choose a partner like them is so we don’t have to go through crap like this, but they weren’t able to offer another solution.  Fortunately, we were able to find another partner (X-charge) that integrates with our app in a way that it never has to see a credit card number.  Problem solved.  If your app or web site collects or processes credit card info, chances are PCI will be knocking on your door.

VARIANTs on Fox

As I mentioned previously, I have been experimenting with integrating our application with Maximizer CRM.  Working with their SDK, it doesn’t take long to figure out that the com interfaces were designed with VB and C++ programmers in mind.  Most of it works with VFP, but there are a few exceptions.  I ran into a problem with an interface that accepts a variant variable by reference.  I was surprised to find out that Fox can’t create a variant.

Shirley I can’t be serious?  Everyone knows that all variables in Fox are variants.  While that may be true, Fox can’t create a variable of type variant that can be passed to com components.  Fox always assigns a type to a variable.  Even a simple local myvariable statement creates a logical variable.  Attempting to pass the variable by reference to a com component may result in a “type mismatch” error.

This isn’t entirely Fox’s fault.  After all, should a COM component assume that the calling environment can create a variant?  Microsoft concedes this is a problem in C++ with MFC components and recommends using ATL instead (see link below).

So, what can you do if you run into this situation?  Ideally, the COM interface would be changed not to use variants, but I doubt Maximizer will change their interfaces, in place for years, just so I can use VFP.  VB does allow you to create variables of type variant, so I created a VB wrapper component.  VFP passes a string to the VB component, the VB component converts that to a variant and passes it to the Maximizer component.  It’s not an ideal solution, but it works.

Prb: ActiveX controls passing variant* back to VFP cause error

VFPS: Visual FoxPro Stack

UPDATE: This article is now online for free at http://www.foxrockx.com/seite.htm.
——————-
The January 2009 issue of FoxRockX begins with an article by Ken Levy called “Visual FoxPro Stack”:

“VFPS is a Visual FoxPro Stack, an acronym used to define the key software components making up the Visual FoxPro platform and ecosystem. As a starting point, below is a list of components that comprise VFPS:  Visual FoxPro 9.0, Sedna and XSource, VFPX, VFPY. Also included are VFP 3rd Party products including tools related to .NET for Visual FoxPro such as VFP Studio, Guineu, .NET Extender for VFP, VFPCompiler for .NET, and VFPConversion.

These components represent the future of FoxPro development.  I guess I’ve considered VFPX to be the main effort in that regard, but these other third-party products should not be ignored, as many may find themselves working with them.  Besides, VFPX is primarily an effort for developers, wherease VFPS is aimed at business decision makers.  Ken compares it to LAMP (Linux, Apache, MySQL, PHP) as a marketing moniker and adds the following:

“Having an umbrella stack for evolving VFP community components adds awareness and enhanced branding…  While there will not be a VFP 10.0, there is great benefit from enhancing the mindset and perception by referring to VFPS as the latest bundle of VFP related components. This branding will often target businesses and decision makers of VFP based application development.”

Hopefully, they will put the entire article online for all to see.  I recommend subscribing to FoxRockX.  It will be interesting to see how this all develops.

VFPS Home Page (Fox Wiki)

DAO does VFP data natively

I ran across something interesting (albeit of limited use) recently.  We are considering integrating Maximizer CRM with our software, and I’ve been doing some proof-of-concept work along those lines.  One thing about CRM software creators is they know they won’t be replacing your core line of business applications, so they make sure there are plenty of ways to integrate with those apps.  Maximizer is no exception, and being around for quite a few years now, it includes some old-school (but new to me) integration techniques.

The first thing I wanted to do was import some Fox data into Maximizer.  While older products often included native support for dbase and FoxPro 2.x tables, virtually no products supported Visual FoxPro natively, so I was surprised to see FoxPro 3.0 in the list.  I use VFP 9.0, but I haven’t made use of any of the new database features added in versions 7.0 – 9.0.  So, I gave it a try and it worked like a charm.  “Wow, that was easy”, I thought, “I wish Microsoft products supported their own database this well.”

Well, it turns out, they used to.  To my surprise, this all led me to the fact that DAO 3.5 had native support for Visual FoxPro tables.  DAO (data access objects) was Microsoft’s data technology that preceded ado (ActiveX data objects) and was popular with access and VB developers at the time.  It is now deprecated, but some access developers still favor it over newer technologies.  It has been my assumption that Microsoft access got its name because it could “access” multiple databases in addition to its own jet database.  It has done this by means of “ISAM filters” for other databases, including FoxPro.  DAO 3.5 included a filter for Visual FoxPro.

Eventually, ado came along and superseded DAO as the recommended way to access data.  The ISAM filters became part of the Microsoft jet 4.0 engine, but the FoxPro filters were no longer included in the package.  WTF?  Yet another slight against our beloved Fox?  Perhaps, but also consider this: the ISAM filters suck.  While I am sure they work fine for FoxPro 2.x data, the VFP filters are limited and give you read-only access to data.  Compared to the FoxPro ODBC drivers, which give full read/write access as well as much improved performance, it became apparent that ODBC was the preferred way to access FoxPro data and I assume that’s why the ISAM filters were removed.

While I would never recommend DAO for new development, we often find ourselves working with older systems and technology.  It’s interesting what you run across.

Resources:

 

Grid Header Checkbox

Here’s a little goodie for readers of my blog.  I have several grids that contain a checkbox column to select items in the grid.  I wanted an easy, consistent way to select/deselect all checkboxes in the column, so I created a custom grid header class to do that.  hdrCheckBox.zip is attached (Download).

I initially tried to use a standard checkbox.  VFP doesn’t let you put a control inside a header, so I tried to overlay it on the grid.  That turned out to be too flaky and limited, so I opted to use pictures of a checked and unchecked box, which VFP does do.  The only downside is that the checkbox is a themed control, and Windows XP checkboxes may look slightly different than pictures of the Windows Vista checkboxes I used.  Still, I think the checkbox will look good in any theme.

Another limitation is that the header cannot receive focus like a real checkbox, so no keyboard support.  To get around that, the header Click() is performed when the user presses “A” while the grid column has focus.  I actually tried to use Ctrl+A, but KeyPress() would not detect that combination, I assume because it’s already assigned to the Edit menu.

To make sure the user would know that they could check the box, I put a tooltip on the grid header.  Header tooltips don’t work in VFP9 SP2, so I had to put some workaround code in the class to make the grid tooltip appear.  Hopefully, Microsoft will eventually release a fix for this, but I’m not holding my breath.

To use the class:

  • Change the column HeaderClass to hdrCheckBox in hdrCheckBox.prg.  You may already be done.
  • If you want the box to be checked initially, change the Value property to .T.  Even though this is a PRG-based class, you can use the property sheet and override methods on the form just like you would with any class.  NOTE: Setting this initial value will not check all the boxes in the grid.  You will need to do that in the Grid.RecordSource query.
  • If you want to change the header checkbox back to its original value (for example, if you requery the grid), then call the Reset() method on the class.
  • Another VFP9 SP2 bug!  If you open this form from the menu, you have to use the menu “Procedure” to open the form instead of “Command”.  Otherwise, VFP9 will crash when you open the form.  See Emerson Reed’s blog entry for more info.

Here are the requirements to use the class (which, of course, you could change):

  • Grid.RecordSource is required.
  • Column.ControlSource is required.
  • The column field must be a logical field.
  • Column.CurrentControl must be a checkbox.

Disclaimer: This code is provided AS-IS.  If it doesn’t work for you, fix it!

FoxTabs Reloaded

Rewind to 2004 when VFP 9.0 was in beta. Microsoft added the ability to bind to windows events from FoxPro. The first thing that came to my mind was the ability to hook into VFP IDE windows. I like to work with my code windows maximized and with several windows open at the same time. Constantly going to the VFP window menu to switch windows got tedious. If I could create something like the windows task bar for the VFP ide, that would make life easier and probably be valuable to other people as well. So, I started to ask around about how this could be accomplished. Calvin Hsia put together a sample that he showed at his advisor DevCon (2004?) session. It is now part of the VFP 9 solution samples. I used that as the basis for my utility, and “FoxTaskbar” was born.

I learned a lot about windows events and the FoxPro window system, but I also learned how to crash VFP frequently. Alas, I couldn’t get FoxTaskbar to function stably. After several attempts, I eventually retreated from binding to windows events and tried to use fox’s standard windowing system. I couldn’t get that to work well either, so FoxTaskbar never saw the light of day.

Fortunately, Scott Scovell and Craig Bailey were working on an almost identical tool called “FoxTabs”. Even the internal architecture was similar to FoxTaskbar. I guess great minds think alike <g>, but greater minds actually make it work, and that’s what Scott and Craig did. FoxTabs does exactly what I wanted with FoxTaskbar, and as a bonus, it doesn’t crash VFP every 30 seconds <g>.

In the meantime, Craig and Scott have moved on to other things (Craig is currently looking for his next big adventure), so FoxTabs hasn’t been in development for a couple of years. I had some issues with it, so I recently contacted Craig to see if FoxTabs was still in development. Neither Craig nor Scott has time to continue working on it, so they graciously offered to turn the project over to VFPX. I volunteered to be the project manager, and FoxTabs is now in development again.

FoxTabs 0.5 is now available on the VFPX web site. Please download and start using this handy little utility and help us get to a 1.0 release. I’ve already received bug reports from several developers (that’s a good thing <g>) and progress is being made. Please report any bugs you find on the VFPX issue tracker, and be sure to include “FoxTabs” in the title.

 

Diving In…

After the excitement of the Southwest Fox conference, I decided to get more involved in VFP community efforts and start a blog. Confession… That was how I felt after SW Fox 2007. A year and another excellent SW Fox conference later, I’m finally getting around to doing it. So, here it is. The content will be mostly fox related, forward looking, and hopefully relevant to you. If I have my way, it will be updated on a regular basis. Enjoy!