examples/activex_cpp/barcodes/barcodes.cpp
197 lines
// ============================================================================
// barcodes -- C++ ActiveX (COM) port, following
// examples/activex/barcodes/barcodes.vbs
//
// Writes every supported barcode type onto a grid of pages.
//
// The Delphi/VB6 original drives the flat InsertBarcode with a TPDFBarcode2
// record whose Data/Primary members are POINTERS into caller memory. The COM
// object exposes InsertBarcodeStrA(PosX, PosY, W, H, HAlign, VAlign,
// BarcodeType, Data, ShowText) instead, taking the same TPDFBarcodeType values
// with the data string passed directly -- so that is what this port uses.
// The Primary field of composite codes has no equivalent in the Str variant
// and is dropped, exactly as the VBScript sibling documents.
//
// Per-barcode errors are TOLERATED: some types reject the sample data, and the
// original's error callback returned 0 to continue. RaiseExceptions turns those
// into C++ exceptions, so each insert is caught individually and the grid keeps
// going -- otherwise one bad sample would truncate the whole document.
// ============================================================================
#import "..\\..\\wrappers\\activex\\LumasPdfAX.tlb" no_namespace named_guids
#include <windows.h>
#include "axcommon.h"
#include <cstdio>
#include <string>
#include <vector>
struct Code {
long type;
const char* name;
const char* data;
};
static const Code CODES[] = {
{0x3F, "Australia Post", "12345678"},
{0x44, "Australia Redirect Code", "12345678"},
{0x42, "Australia Reply-Paid", "12345678"},
{0x43, "Australia Routing Code", "12345678"},
{0x5C, "Aztec binary mode", "123456789012"},
{0x5C, "Aztec GS1 Mode", "[01]03453120000011[17]120508[10]ABCD1234[410]9501101020917"},
{0x80, "Aztec Runes", "123"},
{0x04, "Code 2 of 5 IATA", "1234567890"},
{0x07, "Code 2 of 5 Industrial", "1234567890"},
{0x03, "Code 2 of 5 Interleaved", "1234567890"},
{0x06, "Code 2 of 5 Data Logic", "1234567890"},
{0x02, "Code 2 of 5 Matrix", "1234567890"},
{0x8C, "Channel Code", "1234567"},
{0x12, "Codabar", "A123456789B"},
{0x4A, "Codablock-F", "1234567890abcdefghijklmnopqrstuvwxyz"},
{0x01, "Code 11", "1234567890"},
{0x14, "Code 128", "1234567890"},
{0x3C, "Code 128", "1234567890"},
{0x17, "Code 16K binary mode", "[90]A1234567890"},
{0x17, "Code 16K GS1 mode", "[90]A1234567890"},
{0x81, "Code 32", "12345678"},
{0x08, "Code 39", "1234567890"},
{0x18, "Code 49", "1234567890"},
{0x19, "Code 93", "1234567890"},
{0x8D, "Code One", "1234567890"},
{0x5D, "DAFT Code", "aftdaftdftaft"},
{0x1D, "GS1 DataBar Omnidirectional", "0123456789012"},
{0x51, "GS1 DataBar Stacked", "[90]1234567890"},
{0x1F, "GS1 DataBar Expanded", "[90]1234567890"},
{0x1E, "GS1 DataBar Limited", "0123456789012"},
{0x4F, "GS1 DataBar Stacked", "0123456789012"},
{0x50, "GS1 DataBar Stacked Omni", "0123456789012"},
{0x47, "Data Matrix ISO 16022", "0123456789012"},
{0x73, "DotCode", "0123456789012"},
{0x60, "DPD Code", "1234567890123456789012345678"},
{0x16, "Deutsche Post Identcode", "12345678901"},
{0x15, "Deutsche Post Leitcode", "1234567890123"},
{0x10, "EAN 128", "[90]0101234567890128TEC-IT"},
{0x83, "EAN 128 Composite Code", "[10]1234-1234"},
{0x48, "EAN 14", "1234567890"},
{0x0D, "EAN X", "1234567890"},
{0x82, "EAN Composite Symbol", "[90]12341234"},
{0x0E, "EAN + Check Digit", "12345"},
{0x09, "Ext. Code 3 of 9 (Code 39+)", "1234567890"},
{0x31, "FIM", "d"},
{0x1C, "Flattermarken", "11111111111111"},
{0x70, "HIBC Aztec Code", "123456789012"},
{0x6E, "HIBC Codablock-F", "1234567890abcdefghijklmnopqrstuvwxyz"},
{0x62, "HIBC Code 128", "1234567890"},
{0x63, "HIBC Code 39", "1234567890"},
{0x66, "HIBC Data Matrix", "0123456789012"},
{0x6C, "HIBC Micro PDF417", "01234567890abcde"},
{0x6A, "HIBC PDF417", "01234567890abcde"},
{0x68, "HIBC QR Code", "01234567890abcde"},
{0x45, "ISBN (EAN-13 with validation)", "0123456789"},
{0x59, "ITF-14", "0123456789"},
{0x4C, "Japanese Postal Code", "0123456789"},
{0x5A, "Dutch Post KIX Code", "0123456789"},
{0x4D, "Korea Post", "123456"},
{0x32, "LOGMARS", "1234567890abcdef"},
{0x79, "Royal Mail 4-State Mailmark", "11210012341234567AB19XY1A"},
{0x39, "Maxicode", "1234567890abcdef"},
{0x54, "Micro PDF417", "1234567890abcdef"},
{0x61, "Micro QR Code", "1234567890abcdef"},
{0x47, "MSI Plessey", "12345678901"},
{0x4B, "NVE-18", "1234567890123456"},
{0x37, "PDF417", "1234567890abcdef"},
{0x38, "PDF417 Truncated", "1234567890abcdef"},
{0x33, "Pharmacode One-Track", "123456"},
{0x35, "Pharmacode Two-Track", "123456"},
{0x52, "PLANET", "12345678901"},
{0x56, "Plessey", "12345678901"},
{0x28, "PostNet", "12345678901"},
{0x34, "PZN", "1234567"},
{0x3A, "QR Code", "1234567890abcdef"},
{0x91, "Rect. Micro QR Code (rMQR)", "1234567890abcdef"},
{0x46, "Royal Mail 4 State (RM4SCC)", "1234567890abcdef"},
{0x86, "CS GS1 DataBar Ext. component", "[90]12341234"},
{0x8B, "CS GS1 DataBar Exp. Stacked", "[90]12341234"},
{0x85, "CS GS1 DataBar Limited", "[90]12341234"},
{0x84, "CS GS1 DataBar-14 Linear", "[90]12341234"},
{0x89, "CS GS1 DataBar-14 Stacked", "[90]12341234"},
{0x8A, "CS GS1 DataBar-14 Stacked Omni", "[90]12341234"},
{0x20, "Telepen Alpha", "1234567890abcdef"},
{0x90, "Ultracode", "1234567890abcdef"},
{0x22, "UPC A", "1234567890"},
{0x87, "CS UPC A linear", "[90]12341234"},
{0x23, "UPC A + Check Digit", "12345678905"},
{0x25, "UCP E", "1234567"},
{0x88, "CS UPC E linear", "[90]12341234"},
{0x26, "UCP E + Check Digit", "12345670"},
{0x8F, "UPNQR (Univ. Placilni Nalog QR)", "1234567890abcdef"},
{0x55, "USPS OneCode", "01234567094987654321"},
{0x49, "Vehicle Ident Number (USA)", "01234567094987654"},
};
static const int nCodes = (int)(sizeof(CODES) / sizeof(CODES[0]));
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->SetPageCoords(pcTopDown);
double pw = pdf->GetPageWidth() - 100;
double ph = pdf->GetPageHeight() - 100;
double w = 100, h = 120;
int nx = (int)(pw / w);
int ny = (int)(ph / h);
double incX = w + (pw - nx * w) / (nx - 1);
double incY = h + (ph - ny * h) / (ny - 1);
h = 100;
int i = 0;
while (i < nCodes) {
pdf->Append();
pdf->SetFontA(B("Helvetica"), fsRegular, 6.5, VARIANT_TRUE, cp1252);
pdf->SetLineWidth(0);
double y = 50;
for (int yy = 1; yy <= ny; ++yy) {
double x = 50;
for (int xx = 1; xx <= nx; ++xx) {
pdf->WriteFTextExA(x, y - 10, w, -1, taCenter, B(CODES[i].name));
pdf->Rectangle(x, y, w, h, fmStroke);
// On Error Resume Next: a type that rejects the sample data
// must not abort the grid.
try {
pdf->InsertBarcodeStrA(x, y, w, h, coCenter, coCenter,
CODES[i].type, B(CODES[i].data), VARIANT_TRUE);
} catch (const _com_error&) {
}
++i;
x = x + incX;
if (i == nCodes) break;
}
y = y + incY;
if (i == nCodes) break;
}
pdf->EndPage();
}
if (pdf->HaveOpenDoc())
if (!pdf->OpenOutputFileA(B(outFile))) return 1;
pdf->CloseFile();
std::printf("Barcodes \"%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/barcodes/barcodes.cpp.
The build fails if this page and that file ever differ.