Examples / bookmarks / activex_cpp

Bookmarks

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

Demonstrates Annotations

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

examples/activex_cpp/bookmarks/bookmarks.cpp 198 lines
// ============================================================================
//  bookmarks -- C++ ActiveX (COM) port, GENERATED by
//  tools/gen_activex_cpp_examples.py from examples/cpp/bookmarks/bookmarks.cpp
//
//  DO NOT EDIT BY HAND unless you also fix the generator: the next run
//  overwrites this file. If a case cannot be expressed mechanically, teach the
//  generator the rule -- that is what keeps the other 87 honest.
//
//  This drives the SAME engine as examples/cpp/bookmarks/bookmarks.cpp, but through the COM
//  object wrappers/activex exposes rather than the flat C API, so it exercises
//  the marshalling layer no compiled language exercised before.
// ============================================================================
#import "..\\..\\..\\wrappers\\activex\\LumasPdfAX.tlb" no_namespace named_guids

#include <windows.h>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>

// Output goes beside the EXECUTABLE, at the same relative path delphi's lands
// at, because tools/compare_lang_outputs.py keys on exactly that.
static std::string exeDir() {
    char buf[MAX_PATH];
    GetModuleFileNameA(nullptr, buf, MAX_PATH);
    std::string s(buf);
    size_t p = s.find_last_of("\\/");
    return p == std::string::npos ? std::string(".") : s.substr(0, p);
}

// bookmarks -- C++ port of examples\Vb6\bookmarks\bookmarks.bas

#include <cstdio>
#include <string>

// The Delphi original passes Delphi `string` (UnicodeString) to SetFont,
// WriteText, WriteFTextEx, AddBookmark and OpenOutputFile, so every one of
// those calls resolves to the WIDE overload. The *A twins used here before
// kept the text in WinAnsi and never reached the engine's Unicode pipeline --
// visible in the output as the missing Type0/Identity-H fallback font for the
// two WriteFTextEx blocks (the Delphi reference is 20,682 bytes with an /F2
// PMVDKQ+ArialMT; this file was 2,943 bytes with /Helvetica only). wchar_t is
// wchar_t on Windows and char16_t elsewhere, so literals must use the header's
// own () macro: a bare u"..." does not convert to wchar_t* under MSVC
// and a bare L"..." is 4 bytes wide off Windows.
#define W_(s) ((s))
static std::basic_string<wchar_t> WS(const std::string& s){
    return std::basic_string<wchar_t>(s.begin(), s.end());
}

// VCL TColor values (COLORREF, R in low byte) used by SetBookmarkStyle.
static const long clRed    = 0x0000FF;
static const long clGreen  = 0x008000;
static const long clBlue   = 0xFF0000;
static const long clMaroon = 0x000080;





int main(int argc, char** argv) {
    (void)argc; (void)argv;
    if (FAILED(CoInitialize(nullptr))) return 1;
    int _rc = 0;
    try {
    long act, lnk, f, bmk, root;
    double x, y;

    ILumasPDFPtr pdf;
    if (FAILED(pdf.CreateInstance(L"LumasPdf.PDF")))
        _com_issue_error(E_FAIL);
    pdf->RaiseExceptions = VARIANT_TRUE;

    pdf->CreateNewPDFW(W_(""));

    pdf->SetPageCoords(pcTopDown);

    pdf->SetPageHeight(500.0);
    pdf->SetPageWidth(800.0);

    pdf->Append();
        f = pdf->SetFontW(W_("Helvetica"), fsRegular, 20, 0, cp1252);
        pdf->WriteTextW(50, 50, W_("Bookmark destination type dtFit"));
        root = pdf->AddBookmarkW(W_("DestType dtFit"), -1, 1, 1);
        pdf->SetBookmarkDest(root, dtFit, 0, 0, 0, 0);
        pdf->SetBookmarkStyle(root, fsItalic, clRed);
    pdf->EndPage();

    pdf->Append();
        pdf->ChangeFont(f);
        pdf->WriteTextW(50, 50, W_("Bookmark destination type dtXY_Zoom"));
        pdf->WriteTextW(50, 70, W_("Zoom factor 3, Top position 50 (TopDown coordinates)"));
        bmk = pdf->AddBookmarkW(W_("DestType: dtXY_Zoom, zoom factor 3"), root, 2, 0);
        pdf->SetBookmarkDest(bmk, dtXY_Zoom, 50, 50, 3, 0);
        pdf->SetBookmarkStyle(bmk, fsBold, clMaroon);
    pdf->EndPage();

    pdf->Append();
        pdf->ChangeFont(f);
        pdf->WriteTextW(50, 50, W_("Bookmark destination type dtXY_Zoom"));
        pdf->WriteTextW(50, 70, W_("Zoom factor 0.5, Top position 50 (TopDown coordinates)"));
        bmk = pdf->AddBookmarkW(W_("DestType: dtXY_Zoom, zoom factor 0.5"), root, 3, 0);
        pdf->SetBookmarkDest(bmk, dtXY_Zoom, 50, 50, 0.5, 0);
        pdf->SetBookmarkStyle(bmk, fsBold | fsItalic, clGreen);
    pdf->EndPage();

    pdf->Append();
        pdf->ChangeFont(f);
        pdf->WriteTextW(50, 50, W_("Bookmark destination type dtXY_Zoom"));
        pdf->WriteTextW(50, 70, W_("Zoom factor not defined (unchanged), Top position 50 (TopDown coordinates)"));
        bmk = pdf->AddBookmarkW(W_("DestType: dtXY_Zoom, zoom factor unchanged"), root, 4, 0);
        pdf->SetBookmarkDest(bmk, dtXY_Zoom, 50, 50, 0, 0);
        pdf->SetBookmarkStyle(bmk, fsRegular, clBlue);
    pdf->EndPage();

    pdf->Append();
        pdf->ChangeFont(f);
        pdf->WriteTextW(50, 50, W_("Bookmark destination type dtFitH_Top"));
        pdf->WriteTextW(50, 70, W_("Top position 50 (TopDown coordinates)"));
        bmk = pdf->AddBookmarkW(W_("DestType: dtFitH_Top (50)"), root, 5, 0);
        pdf->SetBookmarkDest(bmk, dtFitH_Top, 50, 0, 0, 0);
        pdf->SetBookmarkStyle(bmk, fsRegular, 0xFF8080);
        pdf->WriteTextW(50, 200, W_("Bookmark destination type dtFitH_Top"));
        pdf->WriteTextW(50, 220, W_("Top position 200 (TopDown coordinates)"));
        bmk = pdf->AddBookmarkW(W_("DestType dtFitH_Top (200)"), root, 5, 0);
        pdf->SetBookmarkDest(bmk, dtFitH_Top, 200, 0, 0, 0);
        pdf->SetBookmarkStyle(bmk, fsRegular, 0xC08080);
    pdf->EndPage();

    pdf->Append();
        pdf->ChangeFont(f);
        pdf->WriteTextW(200, 50, W_("Bookmark destination type dtFitV_Left"));
        pdf->WriteTextW(200, 70, W_("Left position 200. FitV has no effect if the width of the page"));
        pdf->WriteTextW(200, 90, W_("is not greater as the height."));
        bmk = pdf->AddBookmarkW(W_("DestType: dtFitV_Left (200)"), root, 6, 0);
        pdf->SetBookmarkDest(bmk, dtFitV_Left, 200, 0, 0, 0);
        pdf->SetBookmarkStyle(bmk, fsRegular, 0x808FFF);
    pdf->EndPage();

    pdf->Append();
        pdf->ChangeFont(f);
        pdf->WriteTextW(50, 50, W_("Bookmark destination type dtFit_Rect"));
        x = (pdf->GetPageWidth() - 90.0) / 2.0;
        y = (pdf->GetPageHeight() - 65.0) / 2.0;

        pdf->WriteFTextExW(x, y, 90.0, -1, taCenter, W_("We zoom into the rectangle"));
        pdf->Rectangle(x, y, 90.0, 65.0, fmStroke);

        pdf->SetLinkHighlightMode(hmInvert);
        lnk = pdf->PageLink(x, y, 90, 65, 7);
        act = pdf->CreateGoToAction(dtFit_Rect, 7, x - 5.0, y - 5.0, x + 100.0, y + 70.0);
        pdf->AddActionToObj(otPageLink, oeOnMouseUp, act, lnk);

        bmk = pdf->AddBookmarkW(W_("DestType: dtFit_Rect"), -1, 7, 0);
        pdf->AddActionToObj(otBookmark, oeOnMouseUp, act, bmk);
        pdf->SetBookmarkStyle(bmk, fsRegular, 0x80FF);
    pdf->EndPage();

    pdf->SetPageFormat(pfDIN_A4);
    pdf->Append();
        pdf->ChangeFont(f);
        pdf->WriteFTextExW(50.0, 50.0, pdf->GetPageWidth() - 100.0, -1.0, taLeft, W_("Destination type dtFit. This variant scales the page so that both sides fit into the viewer window."));
    pdf->EndPage();

    root = pdf->AddBookmarkW(W_("DestType dtFit"), -1, 8, 0);
    pdf->SetBookmarkDest(root, dtFit, 0, 0, 0, 0);

    bmk = pdf->AddBookmarkW(W_("DestType: dtXY_Zoom, zoom factor 3"), root, 2, 0);
    pdf->SetBookmarkDest(bmk, dtXY_Zoom, 50, 50, 3, 0);
    pdf->SetBookmarkStyle(bmk, fsBold, clMaroon);

    pdf->SetPageLayout(plOneColumn);

    if(pdf->HaveOpenDoc() != 0){
        std::string outFile = exeDir() + "/out.pdf.";
        if(pdf->OpenOutputFileW((wchar_t*)WS(outFile).c_str()) == 0){

            return 0;
        }
        if(pdf->CloseFile() != 0)
            printf("PDF file \"%s\" successfully created!\n", outFile.c_str());
    }

    return 0;
    } catch (const _com_error& e) {
        const _bstr_t d = e.Description();
        if (d.length())
            std::fprintf(stderr, "COM error 0x%08lx: %ws\n",
                         (unsigned long)e.Error(), (const wchar_t*)d);
        else
            std::fprintf(stderr, "COM error 0x%08lx: %s\n",
                         (unsigned long)e.Error(), e.ErrorMessage());
        _rc = 1;
    }
    CoUninitialize();
    return _rc;
}

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