Nieuws

FoxPro Document Display

Een snelle documentviewer voor bestaande FoxPro-applicaties, zonder dat de omringende applicatie eerst gemoderniseerd hoeft te worden.

FoxPro Document Display

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.
Terug naar nieuws

Meer

Gerelateerde artikelen

14 apr 2026

We bouwden een nieuwe website. Dit hebben we gedaan.

Rose Development heeft een nieuwe website. In plaats van een algemene aankondiging leggen we de technische keuzes erachter uit, want de site laat in de praktijk zien hoe we ieder project aanpakken.

16 jan 2026

De valkuil van programmeren met AI: waarom het dit keer niet anders is

Om de paar jaar verschijnt in de softwarewereld een hulpmiddel dat programmeurs minder noodzakelijk belooft te maken. In de jaren tachtig waren dat 4GL- en CASE-tools, in de jaren negentig visueel programmeren, in de jaren tweeduizend offshoreontwikkeling en in de jaren tien low-code en no-code. In de jaren twintig is het codegeneratie met AI.

23 okt 2025

DataBridge ontwikkelen in C#

DataBridge is ontwikkeld als herbruikbaar synchronisatieplatform om bedrijfsgegevens uit een lokale administratieomgeving naar externe systemen te verplaatsen, zoals HTTP-services, Microsoft SQL Server en MySQL. Het is geen eenmalig exporthulpmiddel, maar een duurzame verbinding tussen uiteenlopende technische omgevingen, flexibel genoeg om ook te werken als de precieze gegevensstructuur vooraf nog niet bekend is.

Wilt u met ons samenwerken?

Neem contact op, dan bespreken we uw project.