|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThe main purpose of this paper is to demonstrate how to create a PDF writer by using the Virtual Printer Method, which gives your applications an ability to generate PDF files through simply "printing". I am pretty sure there are many PDF writers using the same technique, like PrimoPDF. However, you probably wish to create your own PDF writer some day. Here, I give an example to uncover the whole process of creating such a kind of PDF writer. Background
The main idea is actually simple. What you need to do is install a PostScript printer and let RedMon work as a bridge between the printer and Ghostscript. Using the codeBefore jumping to the demo projectYou have to first download Ghostscript. My demo requires AFPL Ghostscript 8.53. Don’t install it at this time. You are encouraged to use WinRAR or WinZip (I didn’t try WinZip) to unzip it to “C:\\UTReportPrerequisite\\gs\\”. You need to copy pdfwrite.rsp (a text file, which can be found in the demo project) to the folder as well. You may download RedMon from its website, but I suggest you use a replacement that is packed in the demo project. There is a folder “redmon17” in the demo project, please copy this folder to “C:\\UTReportPrerequisite\\”. The last thing you need is a printer driver. By chance, I chose HP color LaserJet 8550 PostScript driver. Don’t install it at this time. Instead, use WinRAR to unzip all files to “c:\\UTReportPrerequisite\\Driver”. The final folder structure should be like below:
Running the demo projectThe demo project is very straightforward. Clicking buttons from "Setp1", "Step2", "Step3" to "Setp4" sequentially, you will have a printer named "UTReport PDF Writer " installed if each step has been done successfully, as shown in the figure below. I want to point out here that "Step3" and "Step4" are a little bit time consuming so more patience should be paid.
Now is the right time to test our PDF writer. Open WordPad.exe, type in whatever you want, then print it using "UTReport PDF Writer". Check C:\SampleOut.PDF, which is your output PDF file. "Step5" to "Setp8" let you have a chance to uninstall the printer you installed just now. Points of interest
Based on MSDN: Before an application calls the //Install Driver void CInstallPrinterDlg::OnBnClickedButtonStep3() { CString msg="Failed"; if (CopyPrintDriverFiles2System() && AddPrinterDriver()) msg = "Add Printer Driver Successfully"; AfxMessageBox(msg); return ; } The other tricky thing is the DRIVER_INFO_3 di3; ... di3.pDependentFiles = TEXT("hpbafd32.dll\0hpbftm32.dll\0HPLJ8550.cfg\" "0hpcdmc32.dll\0hpbcfgre.dll\0hpdcmon.dll\0\0"); In order to let our PDF writer work like a charm, we have to update the registry info for both Ghostscript and RedMon. For RedMon: //#define PORT_KEY TEXT("SYSTEM\\ControlSet001\\Control\\" // "Print\\Monitors\\Redirected Port\\Ports\\UTReportPDFPort:") if ((rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, PORT_KEY, 0, KEY_ALL_ACCESS, &hkey)) != ERROR_SUCCESS) { /* failed to open key, so try to create it */ rc = RegCreateKey(HKEY_LOCAL_MACHINE, PORT_KEY, &hkey); } if (rc == ERROR_SUCCESS) { lstrcpy(buffer, "@c:\\UTReportPrerequisite\\gs\\pdfwrite.rsp -"); RegSetValueEx(hkey, TEXT("Arguments"), 0, REG_SZ, (CONST BYTE *)buffer, lstrlen(buffer)+1); lstrcpy(buffer, "C:\\UTReportPrerequisite\\gs\\gs8.53\\bin\\gswin32c.exe"); RegSetValueEx(hkey, TEXT("Command"), 0, REG_SZ, (CONST BYTE *)buffer, lstrlen(buffer)+1); dwValue =2; RegSetValueEx(hkey, TEXT("ShowWindow"), 0, REG_DWORD,(CONST BYTE *)&dwValue, 4); dwValue =0; RegSetValueEx(hkey, TEXT("RunUser"), 0, REG_DWORD, (CONST BYTE *)&dwValue, 4); dwValue =300; RegSetValueEx(hkey, TEXT("Delay"), 0, REG_DWORD, (CONST BYTE *)&dwValue, 4); RegCloseKey(hkey); } For Ghostscript: //#define GHOSTSCRIPT_KEY2 TEXT("SOFTWARE\\AFPL Ghostscript\\8.53") if ((rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, GHOSTSCRIPT_KEY2, 0, KEY_ALL_ACCESS, &hkey)) != ERROR_SUCCESS) { /* failed to open key, so try to create it */ rc = RegCreateKey(HKEY_LOCAL_MACHINE, GHOSTSCRIPT_KEY2, &hkey); } if (rc == ERROR_SUCCESS) { lstrcpy(buffer, TEXT("C:\\UTReportPrerequisite\\gs\\gs8.53\\bin\\gsdll32.dll")); RegSetValueEx(hkey, TEXT("GS_DLL"), 0, REG_SZ, (CONST BYTE *)buffer, lstrlen(buffer)+1); lstrcpy(buffer, TEXT("C:\\UTReportPrerequisite\\gs\\gs8.53\\lib;C:\\" "UTReportPrerequisite\\gs\\fonts;C:\\UTReportPrerequisite" "\\gs\\gs8.53\\Resource")); RegSetValueEx(hkey, TEXT("GS_LIB"), 0, REG_SZ, (CONST BYTE *)buffer, lstrlen(buffer)+1); RegCloseKey(hkey); } pdfwrite.rsp is actually a parameter file used to control the PDF generation, i.e., page size, resolution etc. -Ic:\UTReportPrerequisite\gs\gs8.53\lib;c:\UTReportPrerequisite\gs\fonts
-sDEVICE=pdfwrite
-r600
-dNOPAUSE
-dSAFER
-sPAPERSIZE=letter
-sOutputFile="c:\SampleOut.PDF"
AcknowledgementFirst of all, thanks to all open source projects. Special thanks should be extended to Ghostscript and RedMon. History
|
||||||||||||||||||||||