This tutorial shows how to create a new PDF document and add to it the first page from PDF files using the LEADTOOLS SDK in a C/C++ Windows API application.
Overview | |
---|---|
Summary | This tutorial covers how to create a new PDF document and add pages to it using SVG in a Windows C DLL Application. |
Completion Time | 30 minutes |
Visual Studio Project | Download tutorial project (19 KB) |
Platform | Windows C DLL Application |
IDE | Visual Studio 2017, 2019, 2022 |
Development License | Download LEADTOOLS |
Try it in another language |
|
Before working on the Create Documents with Document Writers - Windows C DLL tutorial, get familiar with the basic steps of creating a project by reviewing the Add References and Set a License tutorial.
Start with a copy of the 64-bit Windows API project created in the Add References and Set a License tutorial. If the project is not available, create it by following the steps in that tutorial.
In order to use SVG, Document Writers and image loading features, LEADTOOLS requires additional DLLs. Add the required libraries by opening the pre-compiled header file, either pch.h
or stdafx.h
depending on the Visual Studio version used, and add the following lines:
#include "C:\LEADTOOLS23\Include\ltdocwrt.h" //Document Writer
#pragma comment (lib, "C:\\LEADTOOLS23\\Lib\\CDLL\\x64\\Ltdocwrt_x.lib") //Document Writer
#pragma comment (lib, "C:\\LEADTOOLS23\\Lib\\CDLL\\x64\\Ltsvg_x.lib") // SVG
#pragma comment (lib, "C:\\LEADTOOLS23\\Lib\\CDLL\\x64\\Ltfil_x.lib") // file loading and saving
Note: For a complete list of which DLL files are required for a Document Writers application, refer to Document Writers – Files to be Included with your Application.
The License unlocks the features needed for the project. It must be set before any toolkit function is called. For details, including tutorials for different platforms, refer to Setting a Runtime License.
There are two types of runtime licenses:
Note: Adding LEADTOOLS references and setting a license are covered in more detail in the Add References and Set a License tutorial.
Now that the LEADTOOLS references have been added and the license has been set, coding can begin.
The steps below are for Visual Studio 2019; they could be different for other versions of Visual Studio.
Go to the Solution Explorer and double-click the resources file (.rc).
Expand the menu in the resources tree and double-click the menu resource to open it in the designer interface.
In the empty item below the Exit item, click and type Create &Document. Drag the new item above Exit. This should cause the item's ID to become ID_FILE_CREATEDOCUMENT
.
Go to the main CPP file of the project and navigate to the WndProc
function of the main window. Under the switch (wmId)
statement, that is below the WM_COMMAND
case, add a new case:
switch (wmId)
{
case ID_FILE_CREATEDOCUMENT:
CreatePdfDocument(hWnd);
break;
// Keep rest of the code as is
Add a CreatePdfDocument
function above the WndProc
function and add the following code to it:
void CreatePdfDocument(HWND hWnd)
{
TCHAR szFolderIn[1024] = TEXT(""); // Input files location
// Choose input files folder
if (SUCCESS != GetSourceFolder(hWnd, szFolderIn, ARRAYSIZE(szFolderIn)))
return;
TCHAR szFolderSearch[1000] = TEXT(""); // Input files search location and pattern
_tcscpy_s(szFolderSearch, ARRAYSIZE(szFolderSearch), szFolderIn);
_tcscat_s(szFolderSearch, ARRAYSIZE(szFolderSearch), TEXT("\\*.pdf"));
WIN32_FIND_DATA FindFileData = { 0 };
HANDLE hFind = FindFirstFile(szFolderSearch, &FindFileData);
if (INVALID_HANDLE_VALUE == hFind)
{
MessageBox(hWnd, TEXT("No PDF files found in folder"), TEXT("LEADTOOLS Demo"), MB_ICONERROR);
return;
}
TCHAR szFileOut[1000] = TEXT(""); // Output file name
// Choose output file name
if (SUCCESS != GetOutputName(0, szFileOut, ARRAYSIZE(szFileOut)))
return;
TCHAR szFileOutTemp[1000] = TEXT(""); // Temporary output file, so as not to affect folder search
_tcscpy_s(szFileOutTemp, ARRAYSIZE(szFileOutTemp), szFileOut);
_tcscat_s(szFileOutTemp, ARRAYSIZE(szFileOutTemp), TEXT(".tmp"));
DOCUMENTWRITER_HANDLE hDocument = NULL;
DOCWRTPDFOPTIONS pdf = { 0 };
pdf.FontEmbed = DOCWRTFONTEMBED_AUTO;
pdf.pwszCreator = (L_TCHAR*)TEXT("LEADTOOLS PDFWriter");
pdf.pwszProducer = (L_TCHAR*)TEXT("LEAD Technologies, Inc.");
pdf.bImageOverText = TRUE;
L_DocWriterInit(&hDocument, szFileOutTemp, DOCUMENTFORMAT_PDF, &pdf, NULL, NULL);
int n = 1;
do {
AddDocumentPage(hWnd, hDocument, szFolderIn, FindFileData.cFileName, n);
n++;
} while (FindNextFile(hFind, &FindFileData) != 0);
L_DocWriterFinish(hDocument);
MoveFile(szFileOutTemp, szFileOut);
InvalidateRect(hWnd, NULL, TRUE);
MessageBox(hWnd, TEXT("Finished creating PDF"), TEXT("LEADTOOLS Demo"), MB_ICONINFORMATION);
}
The GetSourceFolder()
function can be any function that fills the szFolderIn
variable with a valid folder name that contains PDF files. To display a Select Folder dialog to obtain the folder name, add the following code:
#include <shobjidl_core.h>
L_INT GetSourceFolder(HWND hWnd, TCHAR* pszFolder, rsize_t string_size)
{
L_INT nRet = FAILURE;
IFileOpenDialog* pFileOpenDialog = NULL;
IShellItem* pShellItem = NULL;
CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_IFileOpenDialog, (void**)&pFileOpenDialog);
if(pFileOpenDialog)
{
pFileOpenDialog->SetOptions(FOS_PICKFOLDERS);
if (SUCCEEDED(pFileOpenDialog->Show(hWnd)))
{
pFileOpenDialog->GetResult(&pShellItem);
LPWSTR pFolder = NULL;
pShellItem->GetDisplayName(SIGDN_FILESYSPATH, &pFolder);
if (pFolder)
{
_tcscpy_s(pszFolder, string_size, pFolder);
CoTaskMemFree(pFolder);
nRet = SUCCESS;
}
}
}
if (pShellItem)
pShellItem->Release();
if (pFileOpenDialog)
pFileOpenDialog->Release();
return nRet;
}
The GetOutputName()
function can be any function that fills the szFileOut
variable with a valid name for the PDF file to be created. To display a Save As dialog to obtain the file name, add the following code:
L_INT GetOutputName(HWND hwnd, TCHAR* pszFileName, DWORD nLen)
{
OPENFILENAME OpenFileName = { 0 };
OpenFileName.lStructSize = sizeof OPENFILENAME;
OpenFileName.hwndOwner = hwnd;
OpenFileName.lpstrFilter = TEXT("PDF File\0*.pdf\0");
OpenFileName.lpstrFile = pszFileName;
OpenFileName.nMaxFile = nLen;
OpenFileName.lpstrDefExt = TEXT("pdf");
OpenFileName.lpstrFileTitle = NULL;
OpenFileName.nMaxFileTitle = 0;
OpenFileName.lpstrInitialDir = NULL;
OpenFileName.Flags = OFN_OVERWRITEPROMPT;
// Show the File Save dialog box
if (!GetSaveFileName(&OpenFileName))
return FAILURE;
return SUCCESS;
}
Add a function named AddDocumentPage
that loads a PDF page as SVG then adds it to the PDF document, and add the following code to it:
void AddDocumentPage(HWND hWnd, DOCUMENTWRITER_HANDLE hDocument, TCHAR *pszFolderIn, TCHAR* pszFileName, int nDocNumber)
{
TCHAR szDocFile[1024] = TEXT(""); // Input file full location and name
_tcscpy_s(szDocFile, ARRAYSIZE(szDocFile), pszFolderIn);
_tcscat_s(szDocFile, ARRAYSIZE(szDocFile), TEXT("\\"));
_tcscat_s(szDocFile, ARRAYSIZE(szDocFile), pszFileName);
TCHAR szProgress[1024];
_stprintf_s(szProgress, ARRAYSIZE(szProgress), TEXT("Loading document number %d: %s"), nDocNumber, pszFileName);
HDC hDC = GetDC(hWnd);
RECT rect = { 50, 50, 2000, 100 };
FillRect(hDC, &rect, (HBRUSH)(COLOR_WINDOW + 1)); //erase previous progress text
TextOut(hDC, 50, 50, szProgress, _tcslen(szProgress));
ReleaseDC(hWnd, hDC);
DOCWRTSVGPAGE Page;
BITMAPHANDLE OverlayBitmap;
LOADSVGOPTIONS svgOptions = { 0 };
svgOptions.uStructSize = sizeof(LOADSVGOPTIONS);
L_LoadSvg(szDocFile, &svgOptions, NULL);
L_LoadBitmap(szDocFile, &OverlayBitmap, sizeof OverlayBitmap, 24, ORDER_BGR, NULL, NULL);
Page.hSvgHandle = svgOptions.SvgHandle;
Page.pOverlayBitmap = &OverlayBitmap;
L_DocWriterAddPage(hDocument, DOCWRTPAGETYPE_SVG, &Page);
L_SvgFreeNode(svgOptions.SvgHandle);
L_FreeBitmap(&OverlayBitmap);
}
Run the project by pressing F5, or by selecting Debug -> Start Debugging.
If the steps are followed correctly, the application runs and enables the user to select an input folder and an output file name. The application then creates a new PDF file and adds to it the first page of each PDF file in the given directory using SVG and Document Writers.
This tutorial showed how to create documents using the Document functions L_DocWriterInit()
, L_LoadSvg()
, L_DocWriterAddPage()
and L_DocWriterFinish()
.