The first Beta release of ParallelFox is now on VFPX, along with a couple of training videos. The plan is to provide more videos, but there is a lot to cover and it is slow going. In the meantime, there should be enough info on VFPX to get you started. Please download ParallelFox, play with it, and let me know what you think.
I know… I’ve been seriously neglecting my FoxTabs duties… again. After a long delay, FoxTabs 0.9.2 has just been released. There have only been a few issues since the last release over a year ago. Unless new issues are introduced in this version (very possible), I expect this version will become a release candidate, and then version 1.0.
One of the reasons for the delay was an issue discovered by Greg Green, and I wasn’t sure of the best way to handle it. Greg has created several replacements for the standard VFP editors and designers. (If you are interested in Greg’s work, go to the Universal Thread Downloads page and enter GKK in the Search field.) FoxTabs and Greg’s editors were conflicting with each other. We were eventually led to this statement in the VFP Help for BindEvent():
When binding to Windows message (Win Msg) events, only one hWnd to Windows message pairing can exist.
Greg and I were trying to bind to the same Windows events, but “there can be only one”, so we were stepping on each other’s bindings. Greg developed a small framework to work around the limitation, and I made some modifications to that for the latest FoxTabs release.
VFP does support multiple bindings for standard FoxPro events. The solution we came up with adds an object to a collection for each Windows event and binds to that event, effectively translating the Win Msg to a standard Fox event. BindEvent() is called again to bind the collection object to the intended event handler/delegate. This design allows as many bindings as you want. The code includes two functions: BindWinEvent() and UnBindWinEvents().
BindWinEvent() has the same interface as the standard BindEvent() function:
BindWinEvent(hWnd | 0, nMessage, oEventHandler, cDelegate [, nFlags])
UnBindEvents() is similar to the standard UnBindEvents() function, but adds a couple of parameters. Since multiple bindings are now possible, you have to specify which event handler/delegate you want to unbind:
UnBindWinEvents(hWnd | 0, nMessage | 0, oEventHandler, cDelegate)
You can pass 0 to nMessage if you want to unbind all the messages for a hWnd, such as when a window is closed/destroyed. The following syntax is also supported if you want to unbind all events from an event handler object:
Clear as mud? The bottom line is that it is recommended you use these functions instead of the standard VFP functions when binding to Windows events. If everyone does that, then we won’t step on each others toes. Unfortunately, that is a requirement. There is nothing we can do to prevent another program from taking over your events with the standard VFP functions.
The code is included in FoxTabs 0.9.2 and is attached. If you find any problems, please let me know.
Sunday rolled around, and I couldn’t believe it was already the last day of the conference. Sleep deprivation was starting to set in, and I had more sleep than most. Still, I wasn’t about to miss any sessions.
VFP and MySQL: Case Study for Remote Data
For the purposes of this session, “Remote Data” meant using a database server that resided anywhere, on a local server or out on the internet. Rick started off with some client/server basics and the various ways you can access remote data from VFP. It’s common knowledge that SQL Passthrough is the fastest method for accessing remote data, or is it? Rick showed that in some cases, remote views can actually be faster. It depends on your scenario, and as VFP has improved, statements about performance that were true in previous versions may no longer be true. So, you should test performance for yourself, rather than making assumptions based on past results or what you heard from someone else.
Rick then demonstrated connecting to a MySQL server hosted on GoDaddy.com for his site blameitonrick.com. Even through a slow connection at the conference, performance was quite good. An upsizing wizard for MySQL is available called Stru2MySQL_2.
Developing and Extending the Visual FoxPro Grid Object
Jody is one of the excellent people I met at Southwest Fox this year. This was Jody’s first time speaking at a Fox conference, and she did a great job. Her grid class is awesome, or “full of awesome” because nowadays awesome is apparently measured in quantity (get off my lawn!). Anyway, it’s good. Not only does is make building grids a snap at development time, but you can give it to your customers to add/remove columns, sort, filter, export, slice, dice, and do pretty much anything you can do with a grid. No more waiting for the next release to add a column to the grid. They can do it right now. Sweet.
Practical Uses for GDIPlusX
Being the last regular session of the conference, I was hoping to see some cool stuff to keep me awake. Doug did not disappoint. After a brief introduction to GDIPlusX, Doug demonstrated several practical things you can use it for: scaling/rotating images, properly measuring text width/height, creating images from text and adding effects (shadows, etc.), fully justified text in reports, gradients, lightboxes, screenshots, etc.
Tamar Granor, Doug Hennig, Rick Schummer
The closing session is usually brief at Southwest Fox. There were some giveaways and Southwest Fox 2010 was announced. One of the slides was titled “Fun, Fun, Fun”, and Doug said this was the funnest conference ever. For me, that was definitely true, and others have said the same thing. That is in no small part because the Feltman’s opened their suite to attendees, so special thanks to Mike and Toni for doing that.
The party was by no means over. The speaker dinner was at room 709, after which attendees started to cycle in. Since I didn’t have an early flight, I hung out until about 3:00 AM. Overall, I had a great time this year. The Fox community is a tight-knit group, but it seems even tighter after this conference. I can’t wait until next year!
Saturday morning started off with three sessions on architectural/OOP topics, so I was looking forward to it.
Data Driving Applications
Toni M Feltman
Toni is another of my favorite speakers and I love her speaking style. There have been previous sessions about using meta data in frameworks, but this session was more about refactoring legacy code (there’s that subject again) into data. A real-world example she gave was code that ran for specific users. The users were defined by an IF INLIST(“USER1”, “USER2”, etc.) command that was duplicated many times throughout the code. If that sounds ridiculous, perhaps you have seen CASE statements that run custom code for specific clients. The problem is the same: the users/customers are hard-coded into the app. The first thing Toni did was pull the user list into a separate function. This was easy and low risk, and when users changed, they only had to change the list in one place. Later the user list was refactored into a table with the appropriate permissions. Rather than have someone manually add all the users to the table, she did it right in the function and added users automatically with default permissions. The session eventually led to creating memo fields where users could create their own code or expressions without having to touch the main EXE. Another good session.
Getting Your Head Around Business Objects
Tamar E Granor
Business objects are a concept that can be hard to grasp. All too often the technical benefits are highlighted of separating your code into tiers, but what makes it a “business” object? Tamar asserted that the architectural benefit of consolidating your business rules into an appropriate place is more important than the technical benefits. She talked about a fascinating project that used FoxPro to manage network hardware. Since the interface was not tightly bound to data, it forced her to think about how code should be separated into business objects. She then demonstrated the concepts using a Suduko game. There were a lot of objects flying around, but there was a clear separation of concerns and it was interesting to see all the objects interact. Tamar emphasized the idea that business objects are the “engine of your app”.
Advanced Principles of Solid Object Oriented Design
This was originally going to be my last session of the conference, but being a “big idea” session, I knew it would be better if I tweaked KOKOPELLI to move it sooner before my brain was completely melted. 🙂 SOLID is an acronym coined by Robert Martin for key OOP design concepts. I won’t go into the details here, but Alan did a good job of driving home the ideas with both metaphors and code.
FoxCharts – Great Looking, Modern Charts in Pure VFP Code
All I can say is “Wow!” I had no idea how far along this project had come. Jim demonstrated some impressive charts and functionality, and it is all done in a FoxPro style. FoxCharts is every bit as good as commercial options, if not better.
One of the most popular tools for working with data is Excel, which is ironic considering it is not a database. Nevertheless, our clients demand it and we provide. VFP, of course, has built-in commands that make this a snap, but the result is not exactly presentation quality. COM Automation can be used control the formatting and works pretty well, but it can be very slow. Christof presented another option: XMLSS (XML Spreadsheet), a format introduced in Excel XP (a downloadable plug-in is available for Excel 2000). It allows you control over formatting, but since it is just XML, you get VFP’s text handling speed. There are limitations, but if you can work within them, the result is orders of magnitude faster than automation.
Microsoft Virtual PC for VFP Developers
I have heard good things about virtual machines. I’ve never taken the time to try one, so I was ready to see the technology in action. Doug presented Microsoft Virtual PC 2007, which is available for free. As you might guess by the name, it runs an emulated PC inside a window on your desktop. It’s an emulated 32-bit machine with a hard drive, network card, sound card… the basics of what you expect in a typical computer. That being the case, the answer to just about every “How would you do this or that in VPC?” question is “How would you do it on a standard computer?” When you boot up a VM for the first time, you install the OS, service packs, updates, anti-virus software, and any other applications you want.
VM’s are good for testing software, testing installations, and isolating your development environment. Basically, if you don’t want something screwing up your main Windows install, set up a VM and do it there. VPC includes good tools for managing it all. As always, Doug gave an excellent presentation, and now I can really see the value of using virtual machines.
Several speakers and attendees went go-cart racing at a local track. I will let the winners gloat over their respective victories. 🙂 Rather than embarrass myself on the track, I headed back to the room to get a little bit of work done and to post on this blog, with the intent of meeting everyone back at Club 709 after the races. By the time 11:00 PM rolled around, I couldn’t keep my eyes open. I wimped out and went to bed, but still a good day.
In spite of staying up too late, I woke up well before the alarm went off. That’s a common story at the conference as everyone tries to adjust to the time zone difference.
Open Source Tools
I saw Menachem for the first time last year, and based on that, I knew this session would be both entertaining and informative, a good start to the day. I was not disappointed. The intent was to introduce several tools and overall to recognize how much good free and open source stuff is out there, just waiting for you to try it. We looked at Notepad++, MantisBT (bug tracking), VirtualBox, and others. Menachem has an obvious passion for open source, but he hasn’t abandoned VFP and other Microsoft software out of spite. He commonly connects VFP to MySQL databases. He also was very clear that “free” tools still have a cost in terms of time and resources, and it may still make sense to pay for software that meets your needs. It was a balanced discussion and I enjoyed it.
Enhancing the Visual FoxPro IDE with VFPX Tools
I knew this would be a good session. Rick’s passion for VFPx is contagious. This session was focused on VFPx tools for the IDE vs. things you would use in an application. He showed ClassBrowserX, PEM Editor, FoxTabs, Tabbing Navigation, Control Renamer, ProjectHookX, and probably a few others I missed. It is just insane how much Jim Nelson has done with the PEM Editor in a short time. Tamar’s Control Renamer does more than the name suggests, going through the source code and changing references to the old name, in effect becoming a refactoring tool. In case your wondering how it felt to see my contribution (FoxTabs) being featured in front of an audience, the answer is PRETTY DAMN GOOD! Get involved. You won’t regret it.
Top 10 (or more) Reasons to Use the VFP Toolbox
Tamar E Granor
I love Tamar’s teaching style. She has a way of making things so clear and easy to understand. I admit I rarely use the toolbox. I’ve been using the form controls toolbar for so long, it’s hard to break the habit. Besides, the toolbox is just a better controls toolbar made to look like the toolbox in Visual Studio, right? Wrong! There are so many cool features that help avoid all those little extra things you have to do and overall make your life easier, and you can use it right now. If you aren’t using the toolbox, take another look.
Simulating Multithreaded Processes in VFP
We have a project coming up where a dashboard type interface needs to update itself automatically in the background every few minutes without tying up the rest of the app, so this topic is definitely relevant. Steve showed a couple of different techniques for simulating multi-threaded behavior. The first involves using functionality already built into VFP: AutoYield, DoEvents, Sleep WinAPI, and Timers. These are all things I have used before, but looking at them from a multi-threaded point of view revealed a better understanding of how they work. The second technique uses a separate EXE for running the long process while the main UI is completely responsive. I heard Steve won the award for the longest white paper at 200 pages, so we have plenty of material to help us with the implementation.
Refactoring Legacy Code
Dealing with legacy code has been a common theme throughout the conference, evidence that both speakers and attendees are having to deal with projects written by someone else. I enjoyed Paul’s approach to the material, not academic at all, but he still got the concepts across. I also appreciated the idea of taking small, low-risk steps to refactor the code, but making steady progress. As with other discussions on refactoring, there was emphasis on testing. Apparently, there is a whole discussion on “Unit Testing” vs. “Integration Testing”. Paul’s response: “I don’t care. Just test it.” My favorite quote of the session.
Bonus Session: VFPX Users Meeting
This session was well attended by both VFPX project managers/coordinators and users. There were several topics, but the main discussion centered around better deployment of VFPX files, and getting the word out to more Fox developers. You can watch the meeting at http://www.ustream.tv/channel/swfoxtv.
Bonus Session: Stonefield Query Users Meeting
Doug Hennig puts together a meeting every year to show off new and upcoming features of Stonefield Query, as well as take requests. As an existing user, I like to go. This is awesome software, and the features coming in version 4.0 are going to make things SO much easier for our customers. If you have been considering a report writer, take a good look at Stonefield Query.
The party continued at the Feltman’s for the second night and there were even more people this time. It was good to see YAG there. I met a lot of cool people and had some good discussions.
The keynote is always a major highlight. This year was a bit of a departure from previous SW Fox conferences. A well known person from outside of the FoxPro community was brought in to deliver the keynote: Sara Ford. Well, Sara isn’t completely outside. She works on Microsoft’s Codeplex web site and worked closely with members of the Fox community to host VFPx, one of the first projects on Codeplex. You can watch the keynote and other SW Fox videos at http://www.ustream.tv/channel/swfoxtv.
Attendance this year is 88 attendees and 17 speakers. That’s a drop from last year, but most conferences have dropped due to the economy. It doesn’t feel much smaller to me.
The keynote was followed by a trade reception. Sorry vendors, I was too busy talking to the cool folks at the conference to visit the booths. Maybe later in the conference.
The party continued at Club 709 (a.k.a the Feltman suite), just hanging out with Sara Ford and other attendees. It was a lot of fun. I stayed til almost midnight (2AM to me), but I couldn’t hang with the rest of the veterans. I think I’m going to pay for this…
I arrived in Phoenix yesterday (Wednesday) and had no problems getting to the Arizona Golf Resort or getting checked in. There will probably be some late nights later in the conference, so I made sure to get plenty of rest before.
One of the new features this year is free wireless throughout the hotel. The connection is excellent in the conference facilities, but not so great in my room. It brings back bad memories of the dial-up days (if I get a connection at all), and there is no longer a wired option. Getting any work done over the internet is a challenge.
On the plus side, using a laptop during sessions is easy. At previous conferences, I used pen & paper to take notes in the conference binder, and after the conference, that’s where they stayed. This year, I decided to try taking notes on the laptop, with the hopes that I will get more use out of them afterwards. So far, it’s working great. The organizers have made plenty of power strips available and easily accessible.
Break it Down: Dealing with Legacy Code
I attended Alan Stevens’ pre-conference seminar. Alan is a self-proclaimed “enthusiast”, and I have to agree. He obviously has a passion for what he speaks about, and it makes for a good session. I enjoyed it.
I chose this session because I deal with legacy code every day. One thing I have to think about every time we make a change is the risk of breaking something. So, I was glad that testing was a major focus during the discussion, but skeptical at the same time. Discussions about unit testing in the past have fallen apart when you start talking about data. In my app, I don’t need to know if a coffee pot turns on and off, I need to know that the data is accurate after a process is run. “That’s not unit testing, that’s acceptance testing.” “That’s integration testing.” “Unit tests should never touch data.” Never touch the data? I’m a FoxPro programmer. It’s all about the data! Needless to say, I didn’t walk away with a good feeling about unit testing. I figured it was good for testing framework code, but not real-world business rules.
Things are clearer this time around, and we have better ideas for unit testing in FoxPro than a few years ago. Alan demonstrated testing code that adds records to a table (yes, data!) using FoxUnit. In the test setup, he created temporary cursors to house the data then ran the code to be tested. Afterwards, he ran a couple of SQL statements and verified those contained the expected values. Using temporary cursors ensures a clean set of data, but I don’t think that is an absolute necessity. It may be difficult to do if using a framework (commercial or otherwise) that expects real data, but the important thing is to make sure the data is clean and isolated from other processes that may affect the results of the test. In any case, I certainly walked away with some new ideas for how we can approach automated testing, so the session was worthwhile.
Next up is the keynote tonight. I’m looking forward to it.
So, I was pleasantly surprised to find out my boss is sending me to the Southwest Fox conference. I didn’t expect to go this year, and I’m really looking forward to it. It gives me a boost every time, and this year looks to be no exception. As usual, there are so many good sessions and speakers, I can’t possibly see every session I want, but that’s a good problem.
My first conference was the 2001 Advisor DevCon in San Diego. One thing I liked about that conference were the many sessions on architectural subjects like OOP, n-Tier, Design Patterns, Refactoring, etc. I had a lot of “aha” moments at that DevCon. Since then, the focus turned to .NET, especially at the Advisor conferences, and I put “Need More OOP” on the conference eval ever year. This year, not a problem. There are sessions on refactoring, data-driven architecture, business objects, and advanced OOP design. Let the noodle baking commence!
My Fox tank is refilling already. 🙂
The obvious solution is to do just that and buy 32-bit Windows. Of course, you aren’t going to receive a call from your client until after they buy the machine, and wiping the machine may not be a good option. You could use Virtual PC or other virtualization software to install 32-bit Windows on top of the x64 version and run the app inside that environment indefinitely. I think that will be a common choice. If you’re lucky, maybe the client will realize it’s finally time to get off of DOS/Windows 3.x and upgrade the app. Unless a complete rewrite is in order, the easiest and cheapest path will be to use VFP 9, which works just fine on 64-bit Windows.
Can we use the lifetime of 16-bit computing to predict the lifetime of 32-bit? Not really, but let’s do it anyway :). It’s hard to pinpoint the “beginning” of 16-bit, but let’s go with the dawn of the IBM PC in 1980. 32-bit computing clearly became mainstream with the release of Windows 95. In 2010, whether or not 64-bit will be considered “mainstream” is debatable, but it certainly presents a problem for 16-bit apps. With that in mind, it appears that desktop computing shifts to the next level roughly every 15 years. Again, this is just conjecture, but if that pattern holds true, 32-bit Windows apps (like those written in VFP) would continue to function until 2025. Virtualization may extend that further. That doesn’t mean they will be acceptable in the marketplace, any more than 16-bit apps are now, but they may at least still run.
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.