Examples / personalize / activex_cpp

Personalize

A complete, runnable activex_cpp program — 113 lines, shipped in your download.

Demonstrates Text

Same example, other languages: c cpp cpp_linux csharp delphi python vbnet

examples/activex_cpp/personalize/personalize.cpp 113 lines
// ============================================================================
//  personalize -- C++ ActiveX (COM) port, following
//  examples/activex/personalize/personalize.vbs
//
//  Imports a German tax form and fills it in -- not through form fields, but by
//  writing text straight onto the imported page at the coordinates the form's
//  boxes sit at. BeginContinueText/AddContinueText/EndContinueText walks down
//  the form line by line using the current leading, which is why the leading
//  and character spacing are changed mid-run to line up with different parts of
//  the layout.
//
//  The form UI of the original is dropped; errors surface via RaiseExceptions.
// ============================================================================
#import "..\\..\\wrappers\\activex\\LumasPdfAX.tlb" no_namespace named_guids

#include <windows.h>

#include "axcommon.h"

#include <cstdio>
#include <ctime>
#include <string>

static const char* IN_FILE = "E:\\LUMASPDFSDK\\examples\\test_files\\taxform.pdf";

// VBScript's CStr(Now) -- the system short-date + long-time patterns, which is
// also what the Delphi original's DateTimeToStr produces.
static std::string NowStr() {
    SYSTEMTIME st;
    GetLocalTime(&st);
    char d[128] = {0}, t[128] = {0};
    GetDateFormatA(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, nullptr, d, (int)sizeof(d));
    GetTimeFormatA(LOCALE_USER_DEFAULT, 0, &st, nullptr, t, (int)sizeof(t));
    return std::string(d) + " " + t;
}

int main() {
    ChdirToExe();
    ComInit com;
    if (!com.ok()) return 1;
    int rc = 0;
    try {
        ILumasPDFPtr pdf;
        if (FAILED(pdf.CreateInstance(L"LumasPdf.PDF"))) _com_issue_error(E_FAIL);
        pdf->RaiseExceptions = VARIANT_TRUE;

        std::string outFile = OutFile();

        pdf->CreateNewPDFA(B(""));
        pdf->SetViewerPreferences(vpDisplayDocTitle, avNone);
        pdf->SetImportFlags(ifImportAll | ifImportAsPage);
        if (pdf->OpenImportFileA(B(IN_FILE), ptOpen, B("")) < 0) {
            std::printf("Could not open taxform.pdf!\n");
            return 1;
        }
        pdf->ImportPDFFile(1, 1.0, 1.0);

        pdf->EditPage(1);
        pdf->SetFontA(B("Courier"), fsBold, 14.0, VARIANT_FALSE, cp1252);
        pdf->WriteTextA(72.5, 748.5, B("X"));
        pdf->WriteTextA(74.0, 701.0, B("Musterstadt"));
        pdf->WriteTextA(74.0, 677.0, B("252/1062/3323"));
        pdf->BeginContinueText(74.0, 628.0);
        pdf->SetLeading(24.0);
        pdf->SetCharacterSpacing(5.8);
        pdf->AddContinueTextA(B("Mustermann"));
        pdf->AddContinueTextA(B("Hermann"));
        pdf->AddContinueTextA(B("22021963keineKaufmann"));
        // Chr(223) is the cp1252 sharp s in "Musterstrasse".
        pdf->AddContinueTextA(B(std::string("Musterstra") + (char)223 + "e 145"));
        pdf->AddContinueTextA(B("12345Musterstadt"));
        pdf->SetCharacterSpacing(0.0);
        pdf->SetFontA(B("Courier"), fsBold, 10.0, VARIANT_FALSE, cp1252);
        pdf->SetLeading(48.0);
        pdf->AddContinueTextA(B("04.05.1994"));
        pdf->SetFontA(B("Courier"), fsBold, 14.0, VARIANT_FALSE, cp1252);
        pdf->SetCharacterSpacing(5.8);
        pdf->AddContinueTextA(B("Sabine"));
        pdf->SetLeading(47.5);
        pdf->AddContinueTextA(B("18121966 ev  Hausfrau"));
        pdf->EndContinueText();
        pdf->WriteTextA(72.5, 365.0, B("X"));
        pdf->WriteTextA(396.0, 365.0, B("X"));
        pdf->BeginContinueText(74.0, 316.0);
        pdf->SetLeading(24.0);
        pdf->AddContinueTextA(B("2346256780     76834560"));
        pdf->AddContinueTextA(B("Sparkasse Musterstadt"));
        pdf->EndContinueText();
        pdf->WriteTextA(72.5, 269.0, B("X"));
        pdf->SetCharacterSpacing(0.0);
        pdf->SetFontA(B("Courier"), fsNone, 10.0, VARIANT_FALSE, cp1252);
        pdf->WriteTextA(53.0, 48.0, B(NowStr()));
        pdf->SetFillColor(RGB(0xFF, 0x66, 0x66));
        pdf->SetFontA(B("Helvetica"), fsBold, 22.0, VARIANT_FALSE, cp1252);
        pdf->WriteTextA(340.0, 70.0, B("www.dynaforms.de"));
        pdf->SetLineWidth(0.0);
        pdf->SetLinkHighlightMode(hmPush);
        pdf->SetAnnotFlags(afReadOnly);
        pdf->WebLinkA(340.0, 64.0, 204.0, 22.0, B("http://www.dynaforms.de"));
        pdf->EndPage();

        if (pdf->HaveOpenDoc())
            if (pdf->OpenOutputFileA(B(outFile)))
                if (pdf->CloseFile())
                    std::printf("PDF file \"%s\" successfully created!\n", outFile.c_str());
    } catch (const _com_error& e) {
        const _bstr_t d = e.Description();
        std::fprintf(stderr, "%ws\n", d.length() ? (const wchar_t*)d : L"COM error");
        rc = 1;
    }
    return rc;
}

This file is in the SDK at examples/activex_cpp/personalize/personalize.cpp. The build fails if this page and that file ever differ.