FoxPro Document Display
Building a high-speed document viewer for legacy FoxPro applications without asking the host application to modernize first.
Read moreNews
Sometimes software maintenance is a clean, predictable job. And sometimes it is ten hours of staring into Visual FoxPro, legacy ActiveX controls, temporary DBF files, scrambled compiled code, hidden viewers, crashing PDF components, and one very stubborn transport management system that refuses to explain itself.

Sometimes software maintenance is a clean, predictable job. And sometimes it is ten hours of staring into Visual FoxPro, legacy ActiveX controls, temporary DBF files, scrambled compiled code, hidden viewers, crashing PDF components, and one very stubborn transport management system that refuses to explain itself.
Yesterday was the second kind.
We spent almost an entire working day investigating a severe stability problem in TransportMaster TMS running inside AccountView. The symptoms were not subtle. After browsing through a few dozen PDF documents, AccountView would start spinning out of control. Temporary FoxPro files would pile up. Internal state appeared to become unstable. In the worst moments, AccountView would no longer start correctly and reported errors such as missing internal objects and corrupted class definitions. In practical terms: the environment became unusable.
The first workaround was painfully simple: delete the files in the user temp directory and try again. That made AccountView start again, but of course that is not a solution. That is the digital equivalent of turning the building power off and back on because one light switch is haunted. Useful in an emergency, not exactly something you want to document as a support procedure.
The root of the issue was the old PDF viewing pipeline inside AccountView. AccountView still contained its original hidden PDF viewer, based around legacy components such as PDFVIEW.OCX and HiQPdf.rda. These components were being used in a Visual FoxPro host environment where window ownership, COM callbacks, timers, temp files, docking panels, and ActiveX lifecycle behavior all matter.
Replacing the visible viewer alone was not enough. The old viewer was still being created behind the scenes, still receiving paths, still resizing, still participating in the form lifecycle, and still capable of destabilizing AccountView. That was the important discovery: the new viewer was not a replacement for the old one. It was an additional plugin placed on the form. The original AccountView PDF viewer was hidden, but still alive.
That explained the strange behavior: the new viewer could be stable, but the old hidden viewer could still corrupt the session. It was like fixing the front door while the back door was still wide open.
The session started with an error in AccountView’s PDF-to-TIFF path:
PROCEDURE PDF_MANAGER.WRITE_PDF_AS_TIFF Error number: 1429 Cannot set the operation command. Cannot write. Error 0xE8.At first, the suspicion was that the HiQPdf stub was incomplete. Logging was added so we could see whether AccountView was calling into functions or command paths that our stub did not yet implement. Then the PDF viewer control was replaced and tested. For a short time it looked stable. Then, after scrolling through enough documents, AccountView started spinning again.
We then inspected the FoxPro temp directories, the loaded procedure stack, the AccountView add-in code, and the new FoxDocViewer integration. The more we looked, the clearer it became that this was not one single bug. It was a chain reaction:
Several times we thought the system was stable. Several times AccountView immediately proved otherwise. At one point the application appeared to be “fixed,” only to spin out of control moments later. At another point it no longer started and showed:
Object TMS_LIC is not found.That was not exactly the motivational message one hopes for after hours of debugging. But it did point us toward the real issue: AccountView’s startup and add-in registration state had become unstable. Once we repaired and reindexed the relevant internal registration/system tables, AccountView started again. That was the first major turning point.
The final solution was not one magic line. It was a hardening pass across the whole boundary between AccountView, FoxPro, the old viewer, and the new viewer.
The most important changes were:
We also hardened a related ActiveX control, the FileDropArea component, for the same reason. A control that behaves nicely in its own window can still be dangerous inside AccountView. Hosted ActiveX components must be extremely conservative: no unexpected modal dialogs, no unguarded COM callbacks, no unsafe drag/drop assumptions, no resize exceptions, and no lifecycle surprises.
After the final fixes, the system was tested heavily on Windows 11 Pro with multiple windows, docked and undocked PDF viewer panels, repeated scrolling through documents, missing documents, real PDF paths, resize actions, and normal TransportMaster workflows.
The result: stable like a rock.
No spinning. No temp-file explosion. No hidden viewer fighting for the top layer. No AccountView startup failure. No random corruption-like behavior after scrolling through records. The new FoxDocViewer showed the documents correctly and remained stable through the stress tests.
After roughly ten hours of debugging, testing, breaking, fixing, breaking again, reindexing, recompiling, and occasionally questioning all life choices involving legacy COM controls, we ended with a stable solution and clean source packages.
The biggest lesson is that legacy integration work is not just about replacing the visible component. In a framework like AccountView, hidden controls, old COM identities, form lifecycle hooks, docking managers, timers, and FoxPro temp tables can all continue to participate long after you think you have replaced something.
In other words: if an old component is still registered, still instantiated, and still receiving resize or navigation calls, it is still part of the system. Even if nobody invited it to the meeting.
We also learned that Visual FoxPro applications can be impressively resilient and deeply unforgiving at the same time. One wrong assumption at the COM boundary can look like a database problem. One hidden viewer can make a new viewer look broken. One modal dialog or unguarded callback can destabilize an otherwise correct integration.
The work has now been cleaned up into proper technical handoff material:
It was one of those sessions where every answer created two new questions, and every “this must be it” was followed five minutes later by “no, wait, it is still spinning.” But in the end, the system was stabilized, the root causes were isolated, and the final components are now much better suited to survive inside the AccountView framework.
Not bad for a Friday debugging session that started with a PDF viewer and briefly turned into a full expedition through legacy COM, Visual FoxPro, AccountView internals, and the emotional limits of coffee.
More
Building a high-speed document viewer for legacy FoxPro applications without asking the host application to modernize first.
Read moreRose Development has a new site. Rather than write a generic announcement, we thought we would explain the technical decisions behind it — because the site itself is a working example of how we approach every project.
Read more