Examples / collections / activex_cpp

Collections

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

Demonstrates Core SDK

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

examples/activex_cpp/collections/collections.cpp 113 lines
// ============================================================================
//  collections -- C++ ActiveX (COM) port, GENERATED by
//  tools/gen_activex_cpp_examples.py from examples/cpp/collections/collections.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/collections/collections.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);
}

// collections -- C++ port of examples\Vb6\collections\collections.bas
// Imports a cover page, creates a PDF portfolio (collection) and attaches
// three files to it.

#include "repo_root.h"
#include <cstdio>
#include <string>



static const char* TF = LUMAS_REPO_ROOT "/examples/test_files/";

// The Delphi original passes Delphi `string` (UnicodeString) to CreateNewPDF,
// OpenImportFile, AttachFile and OpenOutputFile, so every one of those calls
// resolves to the WIDE overload rather than the *A twins used here before.
// 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());
}



int main(int argc, char** argv) {
    (void)argc; (void)argv;
    if (FAILED(CoInitialize(nullptr))) return 1;
    int _rc = 0;
    try {
    ILumasPDFPtr pdf;
    if (FAILED(pdf.CreateInstance(L"LumasPdf.PDF")))
        _com_issue_error(E_FAIL);
    pdf->RaiseExceptions = VARIANT_TRUE;
    pdf->CreateNewPDFW(W_(""));            // The output file is opened later

    // The page of this file is shown when opening the file with an older Acrobat.
    pdf->SetImportFlags(ifImportAll | ifImportAsPage);
    std::string cover = std::string(TF) + "collection_en.pdf";
    if(pdf->OpenImportFileW((wchar_t*)WS(cover).c_str(), ptOpen, "") < 0){

        printf("Input file \"%s\" not found!\n", cover.c_str());
        return 0;
    }
    pdf->ImportPDFFile(1, 1.0, 1.0);
    pdf->CloseImportFile();
    pdf->CreateCollection(civTile);

    std::string taxform = std::string(TF) + "taxform.pdf";
    std::string emf     = std::string(TF) + "fulltest.emf";
    std::string txt     = std::string(TF) + "sample.txt";

    long ef = pdf->AttachFileW((wchar_t*)WS(taxform).c_str(), W_("A PDF file..."), 1);
    pdf->SetColDefFile(ef);            // Opened when viewing with Acrobat 8 or later
    pdf->AttachFileW((wchar_t*)WS(emf).c_str(), W_("An EMF file..."), 1);
    pdf->AttachFileW((wchar_t*)WS(txt).c_str(), W_("A text file..."), 1);

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

            return 0;
        }
    }
    pdf->CloseFile();
    printf("PDF Collection \"%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/collections/collections.cpp. The build fails if this page and that file ever differ.