Chapter 8: Integrating PDF Technology  11 
this.oPDFPrinter.FileNameOptions=;
IIF(this.lPrompt,0,ccPDF_NOPROMPT+ccPDF_USEFILENAME)+;
IIF(this.lBookmarks,ccPDF_BROADCASTMESSAGES,0)+;
IIF(this.lConcatenate,ccPDF_CONCATENATE,0)+;
IIF(this.lCompression,0,ccPDF_DISABLECOMPRESSION)+;
IIF(this.lEmbedFonts,ccPDF_EMBEDFONT,0)
*SavethecurrentWindowsdefaultprinter
*sowecanrestoreitlater.
this.oPDFPrinter.SetDefaultPrinter()
ELSE
*HandlesettingsviatheFLL.
ENDIF
RETURN
Now the driver is ready to produce the PDF file. At this point you have made settings to 
have the user not prompted for a filename (default in this example), whether bookmarks are 
generated (FLL option only), if the contents are concatenated with previous output, if the PDF 
is compressed (a default for PDFs), and if fonts are embedded. This is not that much work. 
The Visual FoxPro report can now be generated with the following code: 
*SettheVFPprinternametothePDFprinter,andprintthereport.
this.cOldPrinterName=SET("printer",2)
SETPRINTERTONAME(THIS.cAmyuniDriver)
REPORTFORM(this.cReportName)NOEJECTNOCONSOLETOPRINTER
The class also handles the resetting of the original printer driver and cleans up the object 
references in the Destroy method of the object. Modifications or enhancements to this class 
could also forward a text file or HTML output generated from your applications to a PDF file 
as well. Amyuni has other drivers available to support creation of HTML and text (via the 
Rich Text Format). 
If you are using the Amyuni FLL interface you will need the FllIntf.fll file provided by 
Amyuni. This file is installed in the same directory as the Amyuni ActiveX controls and 
sample files. Even if you are not using the FLL interface you will need to include this directory 
in the Visual FoxPro path to recompile the class since the code is included for this option and 
the FLL is referenced. 
How do I email a Visual FoxPro report? 
(Example: MailPDFBatch.prg)
One question that gets asked frequently on the support forums is: How can I email the results 
of a report? One approach is to run the Visual FoxPro report to a PDF file and have the 
application attach it to an email. There are a number of email components available that 
integrate with Visual FoxPro. It is beyond the scope of this chapter to get into the nuts and 
bolts of automating a MAPI compliant email client, but we wanted to reveal one of the most 
useful implementations of Acrobat PDFs in our applications. There are numerous examples of 
integrating email with Visual FoxPro in Chapter 4: Sending and Receiving E-mail. This 
example will leverage another class from West Winds called wwIPStuff. 
Listing 8.1 A program that uses the wwIPStuff class and DLL from West Wind to email 
a Visual FoxPro report as a PDF file. 
Pdf text box font size - Compress reduce PDF size in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
C# Code & .NET API to Compress & Decompress PDF Document
pdf change font size; reader compress pdf
Pdf text box font size - VB.NET PDF File Compress Library: Compress reduce PDF size in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
VB.NET PDF Document Compression and Decompression Control SDK
change paper size in pdf document; pdf reduce file size
12  MegaFox: 1002 Things You Wanted to Know About Extending Visual FoxPro 
LPARAMETERStlEmail
#INCLUDEfoxpro.h
SETEXCLUSIVEOFF
SETDELETEDON
SETPROCEDURETOwwPDFADDITIVE
SETPROCEDURETOwwAPIADDITIVE
SETPROCEDURETOwwUtilsADDITIVE
SETPROCEDURETOwwEvalADDITIVE
SETCLASSLIBTOwwIPStuffADDITIVE
OPENDATABASEpdfsample
SETDATABASETOpdfsample
IFNOTUSED("curMailing")
USEpdfsample!v_geekscontactlistIN0AGAINALIAScurMailing
ELSE
REQUERY("curMailing")
ENDIF
IFNOTUSED("curList")
USEpdfsample!v_geekscontactlistIN0AGAINALIAScurList
ELSE
REQUERY("curMailing")
ENDIF
IFNOTUSED("EmailInfo")
USEpdfsample!EmailInfoIN0AGAINALIASEmailInfo
ENDIF
IFNOTUSED("EmailHistory")
USEpdfsample!EmailHistoryIN0AGAINALIASEmailHistory
ENDIF
loIPMail=CREATEOBJECT('wwIPStuff')
loPDF=CREATEOBJECT('wwPDF40')
SELECTcurMailing
SCAN
lcFileName=ALLTRIM(curMailing.First_Name)+;
ALLTRIM(curMailing.Last_Name)+;
ALLTRIM(STR(curMailing.Contact_Id))+".pdf"
lcOutputFile=ADDBS(SYS(2023))+lcFileName
*GeneratethePDFfile
SELECTcurList
loPDF.PrintReport("ContactListing",lcOutputFile)
loIPMail.cMailServer=ALLTRIM(emailinfo.cMailServe)
loIPMail.cSenderEmail=ALLTRIM(emailinfo.cSender)
loIPMail.cSenderName=ALLTRIM(emailinfo.cSenderName)
loIPMail.cRecipient=ALLTRIM(curMailing.Email_Name)
loIPMail.cSubject=ALLTRIM(emailinfo.cSubject)
loIPMail.cMessage=ALLTRIM(emailinfo.cMessage)+;
ALLTRIM(emailinfo.cSignature)
*HereiswhereweattachthePDFfile
C# PDF Annotate Library: Draw, edit PDF annotation, markups in C#.
Provide users with examples for adding text box to PDF and edit font size and color in text box field in C#.NET program. C#.NET: Draw Markups on PDF File.
change page size of pdf document; change font size in pdf form field
C# PDF insert text Library: insert text into PDF content in C#.net
Powerful .NET PDF edit control allows modify existing scanned PDF text. Ability to change text font, color, size and location and output a new PDF document.
best way to compress pdf; change font size pdf comment box
Chapter 8: Integrating PDF Technology  13 
IFFILE(lcOutputFile)
loIPMail.cAttachment=lcOutputFile
ENDIF
lcSentMsg="To:"+loIPMail.cRecipient+;
CHR(13)+"From:"+loIPMail.cSenderEmail+;
IIF(EMPTY(loIPMail.cCCList),SPACE(0),CHR(13)+"CC:"+;
loIPMail.cCCList)+;
IIF(EMPTY(loIPMail.cBCCList),SPACE(0),CHR(13)+"BCC:"+;
loIPMail.cBCCList)+;
CHR(13)+"Subject:"+loIPMail.cSubject+;
CHR(13)+loIPMail.cMessage
*Onlysendthelistofproduced
IFFILE(lcOutputFile)
*Sendonlyifpassingparameter,allowstesting
*withoutsendingtheemail
IFtlEmail
llResult=loIPMail.SendMail()
ELSE
llResult=.F.
ENDIF
ELSE
llResult=.F.
ENDIF
IF!llResult
WAITWINDOW"Noemailmessageto"+loIPMail.cRecipient+"("+;
loIPMail.cErrorMsg+")"NOWAIT
lcSentMsg=lcSentMsg+CHR(13)+CHR(13)+;
IIF(tlEmail,"Intendedtoemail","Notintendedtoemail")+;
CHR(13)+;
"ERROR:"+loIPMail.cErrorMsg
INSERTINTOemailhistory(tTimeStamp,lSentEmail,mMessage,cRecipient);
VALUES(DATETIME(),.F.,lcSentMsg,curMailing.Email_Name)
ELSE
WAITWINDOW"Sentmessageto"+loIPMail.cRecipientNOWAIT
lcSentMsg=lcSentMsg+CHR(13)+CHR(13)+"Messagesentsuccessfully"
INSERTINTOemailhistory(tTimeStamp,lSentEmail,mMessage,cRecipient);
VALUES(DATETIME(),.T.,lcSentMsg,curMailing.Email_Name)
ENDIF
ENDSCAN
loPDF=.NULL.
loIPMail=.NULL.
USEIN(SELECT("curMailing"))
USEIN(SELECT("curList"))
USEIN(SELECT("emailhistory"))
USEIN(SELECT("emailinfo"))
USEIN(SELECT("contacts"))
RETURN
##WEB ICON 
C# PDF Text Box Edit Library: add, delete, update PDF text box in
Support to change font color in PDF text box. Ability to change text size in PDF text box. Adding text box is another way to add text to PDF page.
adjust pdf size; .pdf printing in thumbnail size
VB.NET PDF insert text library: insert text into PDF content in vb
Save text font, color, size and location changes to Other robust text processing features, like delete and remove PDF text, add PDF text box and field.
change file size of pdf; best pdf compressor
14  MegaFox: 1002 Things You Wanted to Know About Extending Visual FoxPro 
The example code list is only a partial list of the code in the example program. 
The wwIPStuff included in the chapter downloads is a shareware version that is 
available on the West Wind website (www.west-winds.com). It demonstrates the 
simple implementation of the wwIPStuff class and corresponding DLL file, which 
are included in Web Connect, or can be purchased separately. The shareware 
version will display a WAIT WINDOW, but allows complete concept/prototype 
testing before purchasing the commercial product. 
The base idea is to generate the PDF file and attach it to an email. Since this 
implementation directly sends the email via Simple Mail Transfer Protocol (SMTP), it 
bypasses all email clients. This means that there will be no audit trail of the sent mail item in a 
Sent Item folder. While it is nice to trust that the email is safely transferred via the Internet, our 
customers like to have a record that the email was sent and some details to what was included. 
The second half of the program provides a basic audit trail of the email, if it was sent 
successfully, and if not, what error occurred. 
To test this program out you will need to change a few columns in the EmailInfo table. 
The cMailServer is the SMTP server for your email account, cSender is your email address, 
cSenderName is your name, cMessage is the narrative contents of the message in the email, 
and cSignature allows for an optional signature line for the message. 
We set up the program with a parameter (tlEmail) so the program can be run without 
actually sending the email. If you run this program with the parameter set to .T., please change 
the email addresses in the Contacts table to something you will receive and not the chapter 
author and his partners. 
How can I replace the Visual FoxPro Report print 
preview? 
(Example: AltPreview.scx)
If you poll Visual FoxPro developers and have them note one weakness in Visual FoxPro, my 
guess is that a big percentage of them would point to the Report Designer Preview mode. It has 
not had a major enhancement since the days of version 2.x. There are plenty of issues with the 
display depending on the printer drivers, video drivers and the monitor resolution. The zoom 
feature has limited percentage settings. It has no drill down capability and shows its age by not 
displaying hyperlinks. One day I thought, why not use Acrobat to act as the report print 
preview instead of the standard Visual FoxPro method? 
Previously in this chapter we demonstrated a method to generate the PDF file without user 
interaction. Now all we need is a method of displaying the document in the Acrobat Reader. 
Not a problem, the following line of code works just fine on our PC: 
RUN/n1;
"C:\ProgramFiles\Adobe\Acrobat5.0\Acrobat\Acrobat.exe";
"C:\MyDocuments\MemberList200008.PDF"
So now we need a way to make the call generic. There are several solutions to this. We 
can store the location in a configuration table or INI file. While this works it is just one more 
thing that the users need to maintain and can possibly set up wrong, which potentially will lead 
to another support call. So how can you determine the location of Acrobat? Fortunately, 
C# PDF Convert to Word SDK: Convert PDF to Word library in C#.net
PDF document, keeps the elements (like images, tables and chats) of original PDF file and maintains the original text style (including font, size, color, links
can a pdf file be compressed; pdf compress
VB.NET PDF delete text library: delete, remove text from PDF file
Functionality to remove text format by modifying text font, size, color, etc. Other PDF edit functionalities, like add PDF text, add PDF text box and field.
change font size in pdf file; adjust size of pdf file
Chapter 8: Integrating PDF Technology  15 
Acrobat registers itself in the Windows registry and the executable is stored in several keys. 
The key that seems appropriate for this exercise is: 
[HKEY_CLASSES_ROOT\AcroExch.Document\shell\print\command]
The results will differ based on which version of Acrobat is installed, full product or just 
the Reader and the OS platform you are using. It is important to note that you will need the full 
product to generate the PDF files to start with unless you have a product like the Amyuni PDF 
Converter. On our computers the registry entry consists of the following values: 
Acrobat (full): 
C:\Program Files\Adobe\Acrobat 5.0\Acrobat\Acrobat.exe 
Acrobat Reader: 
C:\Program Files\Adobe\Acrobat 5.0\Reader\AcroRd32.exe 
So with this functionality we can now use a registry class to grab the location of the 
executable. The example created (AltRptPreview.scx:: RptPreview() method) will use the 
same technique as the Acrobat hands free example (including the wwPDF50 classes from Rick 
Strahl). It uses the Registry class that comes as part of the Fox Foundation Classes (FFC) to 
determine the location of Acrobat and executes the reader with the PDF file as the parameter.  
lcRegFile=HOME(2)+"classes\registry.prg"
lcAppKey=""
lcAppName=""
loPDF=CREATEOBJECT('wwPDF40')
*Checkfortheexistenceoftheregistryclass
IFNOTFILE(lcRegFile)
MESSAGEBOX("Registryclasswasnotfound("+lcRegFile+")")
RETURN
ENDIF
*InstancetheRegistryobject
loReg=NEWOBJECT("FileReg",lcRegFile)
*GetApplicationpathandexecutable
lnErrNum=loReg.GetAppPath("PDF",@lcAppKey,@lcAppName)
IFlnErrNum!=0
MESSAGEBOX("NoinformationavailableforAcrobatapplication.")
RETURN
ENDIF
*Removeswitcheshere(i.e.,C:\EXCEL\EXCEL.EXE/e)
IFATC(".EXE",lcAppName)#0
lcAppName=ALLTRIM(SUBSTR(lcAppName,1,ATC(".EXE",lcAppName)+3))
IFASC(LEFT(lcAppName,1))=34&&checkforlongfilenameinquotes
lcAppName=SUBSTR(lcAppName,2)
ENDIF
ENDIF
C# PDF delete text Library: delete, remove text from PDF file in
Functionality to remove text format by modifying text font, size, color, etc. Other PDF edit functionalities, like add PDF text, add PDF text box and field.
pdf font size change; batch reduce pdf file size
C# PDF Sticky Note Library: add, delete, update PDF note in C#.net
Allow users to add comments online in ASPX webpage. Able to change font size in PDF comment box. Able to save and print sticky notes in PDF file.
pdf page size limit; adjust pdf size
16  MegaFox: 1002 Things You Wanted to Know About Extending Visual FoxPro 
Now that you have the location of the Acrobat executable you can proceed with the 
building of the file and shell out to Acrobat in “preview mode”. 
*BuildthefilenameforthePDF
lcFileName="ContactList"+lcNow+".pdf"
lcOutputFile=ADDBS(SYS(2023))+lcFileName
*GeneratethePDFfile
loPDF.PrintReport("ContactListing",lcOutputFile)
*RunAcrobatorAcrobatReader
RUN/n1;
&lcAppName;
&lcOutputFile
The RUN command does not wait for the Acrobat application to be shut down. This is 
important in the fact that any code that follows the preview will execute. Therefore do not run 
code to clean up the PDF file because they are open.  
##NOTE ICON 
It should be noted that repeated calls to run any version of Acrobat will open up 
another PDF file in the one single instance of Acrobat. This has no effects on the 
ability for the user to review any of the files. As with anything in the computing 
world, the limits are memory, file handles, and other system resources. 
Another way to do this is: 
*Examplecall:
DOshellWITH"ContactListing.PDF",;
"C:\MyDocuments\",;
"open"
*Program:Shell.prg
*WinApi:ShellExecute
*Function:Opensafileintheapplication
*thatit'sassociatedwith.
*Pass:lcFileName-Nameofthefiletoopen
*
*Return:2-BadAssociation(ie,invalidURL)
*31-Noapplicationassociation
*29-Failuretoloadapplication
*30-Applicationisbusy
*
*Valuesover32indicatesuccess
*andreturnaninstancehandlefor
*theapplicationstarted(thebrowser)
LPARAMETERStcFileName,tcWorkDir,tcOperation
LOCALlcFileName,;
lcWorkDir,;
lcOperation
IFEMPTY(tcFileName)
RETURN-1
ENDIF
Chapter 8: Integrating PDF Technology  17 
lcFileName=ALLTRIM(tcFileName)
lcWorkDir=IIF(TYPE("tcWorkDir")="C",;
ALLTRIM(tcWorkDir),"")
lcOperation=IIF(TYPE("tcOperation")="C"AND;
NOTEMPTY(tcOperation),;
ALLTRIM(tcOperation),"Open")
*ShellExecute(hwnd,lpszOp,lpszFile,lpszParams,;
*lpszDir,wShowCmd)
*
*HWNDhwnd-handleofparentwindow
*LPCTSTRlpszOp-addressofstringforoperationtoperform
*LPCTSTRlpszFile-addressofstringforfilename
*LPTSTRlpszParams-addressofstringforexecutable-fileparameters
*LPCTSTRlpszDir-addressofstringfordefaultdirectory
*INTwShowCmd-whetherfileisshownwhenopened
DECLAREINTEGERShellExecute;
INSHELL32.DLL;
INTEGERnWinHandle,;
STRINGcOperation,;
STRINGcFileName,;
STRINGcParameters,;
STRINGcDirectory,;
INTEGERnShowWindow
RETURNShellExecute(0,lcOperation,lcFilename,SPACE(0),lcWorkDir,1)
So what are some of the advantages of this reporting alternative? In our opinion, it 
addresses some of the Visual FoxPro Report Writer drawbacks. It mainly addresses the 
weakness of the preview zoom (or as it is really known as, “lack of zoom”). The Acrobat 
Reader provides super zoom capability (12.5% up to 1600%). Other nice to have features are 
having multiple pages visible at one time with continuous mode, a search feature, and a true 
What-You-See-Is-What-You-Get (WYSIWYG). You can also view multiple PDF reports 
since the Acrobat Reader can open multiple PDF files. 
Visual FoxPro developers have been challenged by the Visual FoxPro Report Designer 
and have not been bashful about voicing these issues. Microsoft has repeatedly noted that there 
will be little to nothing addressed with the existing Report Designer in future versions of 
Visual FoxPro. Microsoft has also noted that we live in a component world. This is a beautiful 
example of that component world reaping benefits for our clients. The example uses Rick 
Strahls wwPDF class to avoid the user interaction when the PDF file is generated before it is 
previewed in Acrobat. The code can be altered to use any one of the other PDF generators that 
are available to developers. 
How do I present Acrobat PDFs in a Visual FoxPro Form? 
(Example: PdfDisplay5.scx, PdfDisplay5a.scx)
If you have Acrobat or the Acrobat Reader product you will also have the ActiveX control that 
will display a PDF file in a Visual FoxPro form. There are two controls that appear in the 
Tools |Options dialog on the Controls page. The control you want to work with is Acrobat 
control for ActiveX. The other control, Adobe Acrobat document only allows you to hard code 
the PDF file that is displayed. 
18  MegaFox: 1002 Things You Wanted to Know About Extending Visual FoxPro 
We want to give you a word of caution before moving into development with this control. 
We originally developed the samples with the control included in Acrobat 4.0. These samples 
have worked flawlessly. In March of 2001 Acrobat 5.0 version was release. We have crashed 
Visual FoxPro 6 and Visual FoxPro 7 a number of times with the newest version. The 
examples presented have worked around the C5 errors. Adobe states specifically on their 
website that this control was designed specifically to work with Microsoft’s Internet Explorer, 
yet discusses its use with developer tools like Visual Basic. So tread carefully with the 
examples and implementation in applications. 
Like all ActiveX controls, first you will need to select the Acrobat Control for ActiveX in 
the Controls tab of the Visual FoxPro Options dialog. 
##IMAGE: MF08005.tif 
Figure 8.5 The Acrobat Control for ActiveX is available in the Controls tab of the 
Visual FoxPro Options dialog. 
Building the form is straightforward. Drop the control from the ActiveX palette on the 
Visual FoxPro Form Controls toolbar to a Visual FoxPro form. 
Chapter 8: Integrating PDF Technology  19 
##IMAGE: MF08006.tif 
Figure 8.6 The Acrobat Control is the middle toolbar button (with Acrobat symbol). 
The property that needs to be set and/or bound to a Visual FoxPro control is SRC. This 
tells the Acrobat control which PDF file to load and display. The SRC property can be set 
dynamically which reloads the selected PDF file in the viewer (this worked fine in Acrobat 4 
and causes OLE errors in Acrobat 5 unless set in the form Init method). The example form 
(PdfDisplay5.scx, included in the downloads available from www.Hentzenwerke.com) takes a 
parameter, which is the PDF file name and sets the SRC property of the PDF ActiveX control. 
*PdfDisplay5.scxInit()
LPARAMETERStcPdfFileName
this.Resize()
IFVARTYPE(tcPdfFileName)="C"ANDFILE(FULLPATH(tcPdfFileName))
this.olePDF.SRC=FULLPATH(tcPdfFileName)
ELSE
this.olePDF.SRC=FULLPATH(this.olePDF.SRC)
ENDIF
this.olePDF.setFocus()
this.olePDF.setZoom(150)
RETURN
The sample form has a couple of things you should note before trying to run it. The first is 
that you must have the ActiveX control registered on your PC. The second is that we have 
hard coded the PDF filename in the SRC property. There is a good chance that your directory 
structure does not match ours so some changes will need to be implemented before running the 
form or you will need to pass in the parameter, which is the PDF file name (fully pathed or 
available on the Visual FoxPro path). If the PDF is not available the form is displayed empty 
since Acrobat cannot load the PDF. 
The form is displayed (see Figure 8.7.) with the PDF visible. Do not be surprised by the 
Acrobat splash screen. This is displayed when the Acrobat ActiveX control is instanced (the 
same behavior is displayed when a PDF file is opened in Internet Explorer). All of the toolbars 
that are included in the Acrobat Reader (or full version if this is what is loaded on the PC) are 
available in your Visual FoxPro form including tools to zoom in and out, print the document, 
search for text, change pages, and save it off to another file. Even items like Bookmarks and 
Thumbnails are available in the ActiveX control.  
20  MegaFox: 1002 Things You Wanted to Know About Extending Visual FoxPro 
##IMAGE: MF08007.tif 
Figure 8.7 This is a PDF file displayed in a Visual FoxPro form. The Print command 
button will display the printer selection dialog for the user. 
There are a number of methods that can be called to change the behavior of the PDF 
viewer. Unfortunately there is no documentation in the ActiveX control properties dialog that 
describes the method parameters nor is there an associate help file. We can open up the 
ActiveX control (PDF.OCX) or the control’s typelib file (PDF.TLB) to see what the 
parameters are. Still, there is no specific documentation that we could find before assembling 
this chapter. In Visual FoxPro 6 you need to use the Class Browser (see Figure 8.8), in Visual 
FoxPro 7 you will need to use the new Object Browser (see Figure 8.9). 
Documents you may be interested
Documents you may be interested