Monday, March 2, 2009

From DOS to Windows - Using MFC and a specialized class

At one of the companies I worked for in recent years, I was given an interesting assignment. They had some utilities written in C under a DOS platform (the real DOS, not Windows!), and they wanted them converted over to run under Windows. As you will see below, this was not a trivial task.

The lead programmer had enumerated the areas in which code had to be modified as a result of trying to run the DOS programs under a Windows (XP) system. My focus, at first, was two utilities which needed to be modified (rewritten, and newly compiled under a modern, Windows-based C++ compiler) in order to run properly under Windows. The first utility I worked on was the basic control and data collection module, which involved the following issues in the DOS mode: calls to specific memory I/O ports are typically disallowed in non-kernel Windows operation. Those calls would now have to be made through Windows drivers, or better yet, utilize Windows-specific timers and services within the Windows API. This took quite a bit of design & research work to determine the most appropriate times to use. Another major problem was that the code assumed eight bit ints! At least, this is the impression I get from following the logic of the code. You can imagine the cleanup that had to be done to this code to fix this problem! This emphasizes that, in C/C++, when engineering code, we should use typedefs to encapsulate memory sizes of numerical types rather than assuming the sizes of standard types since these are not necessarily portable across machine and OS boundaries.

With all the design reviews I was asked to be part of and provide documentation for, the management decided that the time frame of the project was too short for a single person to handle within the time allotted for development and debugging work, and the team lead was asked to continue the conversion of the aforementioned utility. My responsibility would be a different utility which was responsible for handling the graphing (and printing of the graphs) for the data which was produced through files saved in the other utility, the control and data collection module.

What exactly was the challenge involved here, and what were they trying to achieve by giving me this work? Their motivation in converting from a DOS application to Windows here was being able to utilize Windows drivers and Windows filenames, printers, etc. Otherwise, the code really was already written for a DOS machine, so why would they want to change it? Windows C/C++ compilers do not support the type of libraries available to the old DOS compilers. Programs that are dependent on Graphics.lib (or is it graph.lib?) may have to be totally rewritten to work with a Windows C++ compiler. Then the graphing support would need to be provided via another mechanism, be it a commercial solution or some type of shareware (open source?).

You can imagine that this was an involved operation with required design reviews at every step of the journey; I was asked to detail how I was going about creating each step of the compatibility for them. The first major issue was the replacement of the graphing solution which was provided by DOS Microsoft C libraries available to be used by their compilers. This library is not available to Windows. We had to come up with a solution that would work in a similar way so that graphing commands which worked under DOS could be converted to similar functions which would "work" for our Windows compiler, perhaps via bridge functions possibly in combination with some other changes when these were necessary. An "open source" solution which I had found was rejected by my management because they did not like the licensing terms of the library. So we went with a commercial solution which my team lead found as a viable replacement for the old DOS graph library which was compatible with C++ for Windows and was implemented as an ActiveX control which came with a C++ wrapper API. I set to work to make the old graph functions work under the new API.

As I was working out the details of my design for the design review, I figured that the management wanted to keep the old functionality but to implement it using the Windows UI structure (with appropriate dialogs, etc.). I figured that this could yield multiple graphing windows whereas the old system supported just one (something that might involve incompatibilities with some of the old features but these were not insurmountable). In this area, I found myself "dead wrong". These guys wanted something that would work JUST LIKE the old DOS code, down to the key presses being the same! The only thing that could be different is that they understood that the graph under Windows will look different than the graph under DOS. As you can imagine, this preservation of functionality took some time and design work to produce, as (1) Windows programs are not typically written to traverse menus via keystrokes, (2) Windows programs are primarily written to be event-based, and (3) the program was written and organized in such as way as to accomodate its menu-based structure, and this is not necessarily a typical object-oriented or event-based Windows programming approach.

I came out with a solution for preserving the code base and not entirely rewriting the original code, but enabling the event-based Windows programming structure to carry on its activities and to interact with the original menu-based program structure: this involved multi-threading and a new STL queue-based object which provided an interface between the two parts of the code. This was difficult to sell the management even though it turned out to be quick and did not introduce any defects into the system; they were not convinced that a two-threaded solution should be needed. However, I showed that the alternatives were less palatable, and that my solution would not introduce any structural inefficiencies, since it was used to handle a user interface issue, and those tend to not require heavy-duty data structures which need to be lossless for large amounts of high-speed data. I chugged ahead with my solution, coming out with other interesting solutions for handling screen which were text-only, combined text with graphics/graphing and other issues.

I was able to handle the last wave of redesign requests and bug fixes for my application as I was in the process of leaving the company voluntarily for another company that was providing me challenging assignments in both the leadership and technology realms. I could not oversee the completion of integration testing for my application before I left the company, but after I left, I found out from a second-hand source that my application passed muster and that my team lead had admitted that I had handled the assignment very well and the application, as I ported it from DOS to Windows, fulfilled the expectations that the company had for it.

Thursday, February 26, 2009

Introduction

With the caveat "all beginnings are difficult", I undertake to start the new blog "Code Chronicles". What is the inspiration for this blog, you ask? With over 15 years of programming experience behind me, I believe I have had interesting coding experiences and have developed interesting ways to look at and solve problems. Maybe they are not novel, and maybe there are other alternate approaches to these problems, but I think readers will find them instructive nonetheless. There is a situational backdrop as well; as a professional who works for other people I often find myself thrust into situations not of my own making. As a result of the current economic climate, my last company, which valued my services immensely, went out of existence and, as a result, I have been laid off and am currently unemployed. I will have to approach companies now from ground zero, with no previous shared experiences (at least not on the same exact projects), and convince them that I am the resource that they absolutely must have, despite the existence of many other similar resources competing for the same companies.

I must have a positive approach, and believe that efforts that I am taking part in now WILL move me forward towards the goal of finding employment even though it is eluding me currently. The best way forward is to take stock of myself and present what I have to offer the software community; by dwelling on my solutions of the past, I can at least provide insight to some possible trajectories in my future. Therefore, this blog will not engage in self-pity, but will only touch on the aspects of the situation (or former situations) that will be uplifting to others. Mostly, however, this blog will be about coding problems and solutions, and I plan to provide fragments of code as examples where possible to illustrate the solution (but nothing that would entail legal liabilities, in giving away company secrets, for example). I will try to keep the problems as context-free as I can, while being able to demonstrate the usefulness of a solution to a particular application. When one is given lemons, they tell you to make lemonade. I hope the lemonade that I offer here is tasty, thirst-quenching, and also healthy for all customers!