Dokumentanzeige in FoxPro
Ein schneller Dokumentbetrachter für bestehende FoxPro-Anwendungen — ohne dass die Hostanwendung dafür zuerst modernisiert werden muss.
Plattform
Visual FoxPro / ActiveX
Technologien
C++, ATL, COM, GDI, WIC, PDFium
Ziel
Schnelle Anzeige von JPG-, PNG- und PDF-Dateien direkt im Formular
Projektüberblick
Dieses Projekt löst ein häufiges Problem älterer Software: Benutzer benötigen eine moderne Dokumentanzeige innerhalb einer Anwendung, die dafür nie ausgelegt wurde. Die Hostumgebung ist hier Visual FoxPro. Die Lösung musste sich daher wie ein klassisches ActiveX-Steuerelement verhalten, eine bewusst schlichte COM-Schnittstelle bereitstellen, strikt bei 32 Bit bleiben und jede Instabilität vermeiden, die den Hostprozess zum Absturz bringen könnte.
Das Ergebnis ist FoxDocViewer, ein nativer Dokumentbetrachter in C++, der direkt in ein FoxPro-Formular eingebettet werden kann. Er unterstützt PDFs über PDFium und Bildformate über Windows Imaging Component. Die gesamte Verarbeitung ist hinter einer Schnittstelle gekapselt, die FoxPro mit vertrauten Typen wie BSTR, LONG, DOUBLE und VARIANT zuverlässig aufrufen kann.
So funktioniert die Umsetzung
Die Architektur ist bewusst in klar abgegrenzte Schichten aufgeteilt. So bleibt die COM-seitige Hülle klein und die Darstellungslogik erweiterbar.
1. Eine COM-Hülle für FoxPro
Das ActiveX-Steuerelement ist mit ATL entwickelt und stellt eine duale Schnittstelle für späte Bindung und vtable-Zugriff bereit. FoxPro kann den Betrachter damit über einfache Aufrufe steuern: Dokumentlisten laden, zwischen Seiten wechseln, den Zoom ändern sowie Zustände wie Seitenzahl oder Pfad des aktiven Dokuments abfragen.
Ein anspruchsvolles Detail ist die Übernahme von Dateipfaden. FoxPro kann Arrays in teils wenig intuitiven Formen ausgeben, darunter ein- und zweidimensionale Varianten. Deshalb normalisiert das Steuerelement eingehende SAFEARRAY-Werte, löst per Referenz übergebene Varianten auf, wandelt Werte in Zeichenketten um und ignoriert unbrauchbare Einträge sicher, statt mit einem schwerwiegenden Fehler abzubrechen.
2. Ein Controller für Navigation, Zoom und Zustand
Hinter der ActiveX-Schicht liegt ein eigener Viewer-Controller. Diese Klasse kennt weder Win32-Zeichenoperationen noch COM, was die Logik übersichtlich hält. Sie verwaltet das aktuelle Dokument, die aktuelle Seite, den Zoommodus, den Zoomprozentsatz und den Lebenszyklus des Caches. Das Steuerelement leitet Befehle an diesen Controller weiter und liest vorbereitete Bilddaten daraus aus.
Diese Trennung macht aus einer traditionell schwer überschaubaren Komponente einen berechenbaren Zustandsautomaten. Ein Dokumentwechsel setzt die aktive Seite zurück, Anpassungsmodi berechnen den Zoom anhand der verfügbaren Anzeigefläche neu, und Fehlerzustände werden zentral verwaltet, statt sich über mehrere Schichten zu verteilen.
3. Formatadapter für PDFs und Bilder
Der Betrachter verwendet getrennte Adapter für die verschiedenen Dateitypen. JPG und PNG werden mit Windows Imaging Component dekodiert, in ein einheitliches 32-Bit-BGRA-Format umgewandelt und mit der hochwertigen Interpolation von WIC skaliert. PDFs verarbeitet PDFium, das zur Laufzeit dynamisch geladen und nicht statisch in das Steuerelement eingebunden wird.
Dieses dynamische Laden ist für die Bereitstellung wichtig. Fehlt pdfium.dll, funktioniert das Steuerelement weiterhin für Bilder und meldet beim Öffnen eines PDFs einen konkreten Fehler der PDF-Engine. Der Hostprozess läuft weiter. Bereitstellungsfehler erscheinen so als behebbare Laufzeitmeldungen statt als gescheiterte Registrierung oder Startfehler.
4. Schnelle Darstellung durch Caching und Vorladen
Hohe Darstellungsgeschwindigkeit war eine Kernanforderung. Die Umsetzung nutzt einen größenbegrenzten Seitencache nach dem Least-Recently-Used-Prinzip, dessen Schlüssel aus Dokument, Seite und Zoomstufe besteht. Zoomwerte werden bewusst zu Gruppen zusammengefasst, damit nicht jede minimale Zoomänderung einen Austausch der Cache-Inhalte auslöst. Dieses Detail wirkt sich stark auf die wahrgenommene Geschwindigkeit aus.
Zusätzlich aktiviert das Steuerelement einen schlanken Timer, der benachbarte Seiten vorab rendert, wenn die Oberfläche gerade nichts zu tun hat. Die nächste oder vorherige Seite liegt dadurch häufig schon vorbereitet im Speicher, wenn der Benutzer weiterblättert. Der Seitenwechsel wirkt unmittelbar, obwohl Dekodierung und Rasterung im Hintergrund in nativem Code stattfinden.
5. Flimmerfreies Zeichnen innerhalb einer älteren Hostanwendung
Die letzte Stufe bildet die Render-Engine. Sie verwendet einen nicht sichtbaren Hintergrundpuffer und GDI-Blitting, um flimmerfrei in das Fenster des Steuerelements zu zeichnen. Bildlaufleisten richten sich nach der logischen Zeichenflächengröße. Seiten werden zentriert, wenn sie kleiner als der sichtbare Bereich sind. Der Hintergrundpuffer wächst nur bei Bedarf, damit häufige Größenänderungen wenig Aufwand verursachen.
Das klingt hardwarenah, doch genau hier entscheidet sich das Vertrauen in Desktopsoftware. Ein Betrachter mit zerrissenen Bildern, Aufblitzen, fehlerhaftem Neuzeichnen oder Aussetzern bei Größenänderungen wirkt sofort instabil. Unsere Umsetzung verhindert das, indem sie Zeichenoperationen als kontrollierte Verarbeitungskette organisiert statt als Folge spontaner Win32-Aufrufe.
Die wichtigsten Herausforderungen
Moderne Darstellung mit einem älteren Anwendungsmodell verbinden
Die Hostanwendung erwartet klassisches COM-Verhalten, keinen modernen eingebetteten Browser und keine verwaltete Laufzeitumgebung. Damit schieden viele einfache Lösungen aus. Die Umsetzung musste innerhalb der Grenzen von ActiveX, 32-Bit-Hosting und dem nachrichtengesteuerten Lebenszyklus eines traditionellen Windows-Steuerelements funktionieren.
FoxPro-Datenstrukturen berechenbar machen
Das Verhalten von FoxPro-Arrays kann beim Übergang über die COM-Grenze überraschend umständlich sein. Die Umsetzung musste verschiedene Formen von VARIANT und SAFEARRAY akzeptieren. Die Beispielintegration zeigt, dass das keine theoretische Anforderung war. Praktische Interoperabilität bedeutete, die tatsächliche Array-Ausgabe von FoxPro zu berücksichtigen — nicht allein das, was laut COM-Spezifikation zu erwarten wäre.
Geschwindigkeit und Speicherverbrauch ausbalancieren
Hochauflösende PDFs und Bilder können nach der Rasterung schnell viel Arbeitsspeicher belegen. Deshalb ist die Kapazität des Seitencaches begrenzt, und ältere Einträge werden bei Bedarf verdrängt. Die Gruppierung von Zoomwerten verhindert zugleich eine Flut nahezu identischer zwischengespeicherter Bitmaps. Ziel war keine maximale Zwischenspeicherung um jeden Preis, sondern eine dauerhaft reaktionsfähige Oberfläche unter realistischen Desktop-Arbeitslasten.
Fehler im Hostprozess sicher behandeln
Ein Absturz des Betrachters würde auch FoxPro selbst zum Absturz bringen. Deshalb meldet das Steuerelement Fehler über Zustände und Ereignisse, lässt den bisherigen Inhalt sichtbar, wenn ein neues Dokument nicht geladen werden kann, und gibt Systemressourcen zu festgelegten Zeitpunkten frei. Stabilität war keine optionale Zusatzfunktion, sondern Teil der Produktanforderungen.
Das Ergebnis
FoxDocViewer ergänzt eine bestehende Unternehmensanwendung um eine moderne Dokumentanzeige, ohne die Hostplattform neu zu schreiben. Benutzer können PDFs und Bilder im gewohnten Arbeitsablauf öffnen, schnell zwischen Seiten wechseln, flüssig zoomen und mit minimaler Verzögerung durch Dokumente navigieren.
Aus technischer Sicht zeigt das Projekt eine pragmatische Modernisierung: die Schnittstelle bewusst einfach halten, formatspezifische Logik abgrenzen, entscheidende Darstellungsschritte optimieren und Interoperabilität sowie Fehlerbehandlung von Anfang an als zentrale Entwurfsaufgaben behandeln.
Besonderheiten
Natives ActiveX-Steuerelement für Visual FoxPro. Dynamische PDFium-Einbindung. Bilddekodierung mit WIC. GDI-Darstellung mit doppeltem Puffer. COM-Entwurf mit konsequenter Fehlerbehandlung zum Schutz des Hostprozesses.