FoxPro Document Display
Een snelle documentviewer voor bestaande FoxPro-applicaties, zonder dat de omringende applicatie eerst gemoderniseerd hoeft te worden.
Platform
Visual FoxPro / ActiveX
Technologie
C++, ATL, COM, GDI, WIC en PDFium
Doel
JPG-, PNG- en PDF-bestanden snel binnen een formulier bekijken
Projectoverzicht
Dit project lost een bekend probleem bij oudere software op: gebruikers willen moderne documentweergave binnen een applicatie die daar nooit voor is ontworpen. De omgeving is Visual FoxPro. De oplossing moest zich dus gedragen als een klassieke ActiveX-component, een behoudende COM-interface bieden, strikt 32-bits blijven en geen instabiliteit veroorzaken die de hele applicatie kon laten vastlopen.
Het resultaat is FoxDocViewer, een native C++-documentviewer die direct in een FoxPro-formulier kan worden opgenomen. PDFium verzorgt pdf’s, Windows Imaging Component de beeldformaten. De hele verwerking is verpakt in een interface die FoxPro betrouwbaar kan aanroepen met vertrouwde typen zoals BSTR, LONG, DOUBLE en VARIANT.
Hoe de implementatie werkt
De architectuur is bewust in gerichte lagen verdeeld. Zo blijft de COM-interface klein en de weergavelogica uitbreidbaar.
1. Een COM-interface die bij FoxPro past
De ActiveX-component is gebouwd met ATL en biedt een dual-interface voor late binding en vtable-toegang. In de praktijk kan FoxPro de viewer met eenvoudige aanroepen bedienen: een documentenlijst laden, door pagina’s gaan, zoomen en informatie opvragen, zoals het aantal pagina’s of het pad van het actieve document.
Een subtiel onderdeel is de verwerking van bestandspaden. FoxPro kan arrays in onverwachte vormen doorgeven, waaronder een- en tweedimensionale varianten. Daarom normaliseert de component binnenkomende SAFEARRAY -waarden, volgt verwijzingen in by-ref-varianten, zet waarden om naar tekst en negeert onbruikbare items veilig in plaats van volledig vast te lopen.
2. Een controller voor navigatie, zoom en toestand
Achter de ActiveX-laag staat een afzonderlijke viewercontroller. Deze klasse weet niets van Win32-tekenwerk of COM, zodat de logica helder blijft. Ze beheert het huidige document, de pagina, zoommodus, zoompercentage en de levensduur van de cache. De component geeft commando’s aan de controller door en ontvangt voorbereide beeldgegevens terug.
Die scheiding maakt van een traditioneel lastig componenttype een voorspelbaar toestandsmodel. Wisselen van document zet de actieve pagina terug, passende weergavemodi berekenen de zoom uit het beschikbare venstervlak en foutinformatie wordt op één plek bewaard in plaats van over meerdere lagen verspreid.
3. Formaatadapters voor pdf’s en afbeeldingen
De viewer gebruikt aparte adapters voor verschillende bestandstypen. Windows Imaging Component decodeert JPG en PNG, zet beelden om naar een uniform 32-bits BGRA-formaat en schaalt met de hoogwaardige interpolatie van WIC. PDFium verwerkt pdf’s en wordt tijdens uitvoering dynamisch geladen, niet statisch met de component gekoppeld.
Dat dynamische laden is belangrijk voor installatie. Als pdfium.dll ontbreekt, blijft de component afbeeldingen tonen en meldt deze een specifieke fout van de PDF-engine wanneer een pdf wordt gevraagd. De applicatie blijft draaien. Installatiefouten worden herstelbare meldingen tijdens gebruik, in plaats van mislukte registratie of een startfout.
4. Snelle weergave met caching en vooraf laden
Snel renderen was een kernvereiste. De implementatie gebruikt een begrensde paginacache die de langst niet gebruikte pagina’s als eerste verwijdert, met sleutels voor document, pagina en zoomgroep. Zoomwaarden worden bewust gegroepeerd, zodat de cache niet bij iedere kleine zoomwijziging opnieuw gevuld hoeft te worden. Dat heeft veel invloed op de ervaren snelheid.
Een lichte timer rendert daarnaast aangrenzende pagina’s vooraf wanneer de interface niets anders hoeft te doen. Daardoor staat de volgende of vorige pagina vaak al in het geheugen wanneer de gebruiker navigeert. Bladeren voelt direct aan, terwijl achter de schermen decodering en rasterisatie in native code plaatsvinden.
5. Flikkervrij tekenen in een oudere applicatie
De laatste stap is de renderengine. Deze gebruikt een onzichtbare achterbuffer en GDI-blitting om zonder flikkeren in het componentvenster te tekenen. Schuifbalken volgen de logische canvasgrootte, pagina’s worden gecentreerd als ze kleiner zijn dan het venster en de achterbuffer groeit alleen wanneer nodig om formaatwijzigingen efficiënt te houden.
Dit is techniek op laag niveau, maar juist hier wordt vertrouwen in desktopsoftware gewonnen of verloren. Een viewer met scheurende beelden, flitsen, verkeerde hertekeningen of haperingen bij vensterwijzigingen voelt meteen kwetsbaar. Deze implementatie voorkomt dat door tekenen als een gecontroleerde keten te behandelen, in plaats van als losse Win32-aanroepen.
Belangrijkste uitdagingen
Moderne weergave verbinden met een ouder applicatiemodel
De applicatie verwacht klassiek COM-gedrag, geen ingebouwde moderne browser of beheerde runtime. Daardoor vielen veel eenvoudige oplossingen af en moest de implementatie passen binnen ActiveX, 32-bits hosting en de berichtgestuurde levenscyclus van een traditioneel Windows-component.
FoxPro-gegevensstructuren voorspelbaar maken
FoxPro-arrays kunnen lastig zijn wanneer waarden de COM-grens passeren. De implementatie moest verschillende vormen van VARIANT en SAFEARRAY accepteren. De voorbeeldintegratie liet zien dat dit geen theoretisch probleem was. Goede interoperabiliteit moest rekening houden met hoe FoxPro arrays daadwerkelijk doorgeeft, niet alleen met hoe de COM-specificatie zegt dat het hoort.
Snelheid en geheugengebruik in balans
Pdf’s en afbeeldingen met hoge resolutie gebruiken na rasterisatie snel veel geheugen. De paginacache heeft daarom een vaste bovengrens en verwijdert oude items. Het groeperen van zoomwaarden voorkomt een overvloed aan vrijwel identieke bitmaps. Het doel was niet zo veel mogelijk cachen tegen elke prijs, maar stabiel en vlot reageren bij realistisch desktopgebruik.
Veilig omgaan met fouten binnen het applicatieproces
Een harde crash in de viewer zou ook FoxPro laten crashen. Daarom meldt de component fouten via toestand en gebeurtenissen, houdt deze oude inhoud zichtbaar als een nieuw document niet kan worden geladen en geeft deze systeemresources op vaste momenten vrij. Stabiliteit was geen extraatje, maar onderdeel van de productdefinitie.
Resultaat
FoxDocViewer geeft een oudere bedrijfsapplicatie moderne documentweergave zonder het platform te herschrijven. Gebruikers openen pdf’s en afbeeldingen binnen hun bestaande werkproces, bladeren snel door pagina’s, zoomen vloeiend en wisselen met minimale vertraging tussen documenten.
Technisch laat het project zien hoe praktische modernisering werkt: houd de interface behoudend, isoleer formaatspecifieke logica, optimaliseer de weergave waar dat telt en behandel interoperabiliteit en foutafhandeling vanaf het ontwerp als kerneisen.
Kenmerken
Native ActiveX-component voor Visual FoxPro. Dynamische PDFium-koppeling. Beelddecodering via WIC. GDI-weergave met dubbele buffering. COM-ontwerp met foutafhandeling als uitgangspunt om het applicatieproces te beschermen.