View PDF in VFP Form

MS Web Browser control can be used to display contents of different type of files, including PDF.

The information on Web Browser Control can be found on MSDN at http://msdn2.microsoft.com/en-us/library/aa752040.aspx


Note 1 If PDF is displayed in the separate window outside of the Web Browser control, launch Adobe Acrobat/Reader and check 'Display PDF in Browser' under Internet in the Preferences. To fix the same problem for other file types (.DOC, .XLS, etc.) go to Folder Options -> File Types -> DOC-> Click Advanced button -> Choose Action: open and uncheck 'Confirm open after download' and check 'Browse in same window'.


Note 2 There are other ways to view a PDF:

  • You can open PDF in the default PDF viewer using code from Opening URL in default Web Browser and putting PDF file name into lcUrl.
  • Alternatively, you can use IE instead of Web Browser Control
loIE = Createobject("internetexplorer.application")
loIE.Visible = .T.
loIE.Navigate("file://" + lcPdfFileName)
...


Note 3 Optionally, PDF display can be adjusted by calling methods of PDF ActiveX control after PDF is loaded as shown in AdjustPdfView method posted separately after sample form. More info on PDF ActiveX control can be found in Interapplication Communication API Reference from Acrobat 8.1 SDK at http://www.adobe.com/devnet/acrobat/?navID=downloads. Free registration is required.


Note 4 The code below has been generated by Class Browser from a form. To create a form (.SCX) use following steps

  1. Create a form
  2. Add Property cPdfFileName to the form and assign empty string (=SPACE(0)) to it.
  3. Drop olecontrol on the form and pick Microsoft Web Browser.
  4. Change its name to oWB.
  5. Create method ShowPdf on the form and copy code from PROCEDURE ShowPdf there.
  6. Drop a command button on the form and copy code from command1.Click into its click method.
  7. In VFP8 and earlier put NODEFAULT into REFRESH event to prevent an error.

This is sample code. Add error handling and adjust to your requirements as necessary.

PUBLIC oform1
 
oForm1=NEWOBJECT("form1")
oForm1.Show()
RETURN
 
DEFINE CLASS form1 AS form
 
	Autocenter = .T.
	Height = 520
	Width = 741
	Caption = "Form1"
	Name = "Form1"
 
	&& PDF file name
	cPdfFileName = "=SPACE(0)"
	&& How long to wait for PDF to load
	nPdfLoadTimeout = 30 			
 
	ADD OBJECT txtpdfname AS textbox WITH ;
		Top = 471, Left = 108, Height = 23, Width = 492, ;
		ReadOnly = .T., Name = "txtPdfName"
 
	ADD OBJECT command1 AS commandbutton WITH ;
		Top = 469, Left = 623, Height = 27, Width = 84, ;
		Caption = "View PDF", Name = "Command1"
 
	ADD OBJECT owb AS olecontrol WITH ;
		Top = 24, Left = 12, Height = 433, Width = 709, ;
		OleClass = "Shell.Explorer.2", Name = "oWB"
 
	ADD OBJECT label1 AS label WITH ;
		Height = 17, Left = 36, Top = 474, Width = 63, ;
		Caption = "PDF Name", Name = "Label1"
 
	PROCEDURE Refresh
		&& Required in VFP8 and earlier to prevent an error
		NODEFAULT
	ENDPROC
 
	PROCEDURE ShowPdf
		LOCAL lnSeconds
		&& Clear Web browser control by loading blank page
		Thisform.oWB.OBJECT.Navigate2("About:Blank")
		&& Wait for load to complete
		lnSeconds = SECONDS()
		DO WHILE (Thisform.oWB.OBJECT.Busy OR Thisform.oWB.OBJECT.ReadyState <> 4) ;
				AND (SECONDS() - lnSeconds) < This.nPdfLoadTimeout
			DOEVENTS
		ENDDO
 
		&& Load PDF
		WAIT WINDOW NOWAIT "Loading PDF ..."
		Thisform.oWB.OBJECT.Navigate2(Thisform.cPdfFileName)
		&& Wait for PDF to load
		lnSeconds = SECONDS()
		DO WHILE (Thisform.oWB.OBJECT.Busy OR Thisform.oWB.OBJECT.ReadyState <> 4) ;
				AND (SECONDS() - lnSeconds) < This.nPdfLoadTimeout
			DOEVENTS
		ENDDO
		WAIT CLEAR
 
		&& PDF display can be adjusted as shown in AdjustPdfView method 
 		&&   Uncomment next line if you want to do that and add AdjustPdfView method to the form/class
		&&This.AdjustPdfView()
 
	ENDPROC
 
	PROCEDURE command1.Click
		&& Get PDF file name
		Thisform.cPdfFileName = GETFILE("pdf")
 
		&& Display the name in the textbox
		Thisform.txtPdfName.Value = Thisform.cPdfFileName
		IF NOT EMPTY(Thisform.cPdfFileName)
			&& Display PDF
			Thisform.ShowPdf()
		ENDIF
	ENDPROC
 
ENDDEFINE
	PROCEDURE AdjustPdfView
		&& PDF control PEMs can only be accessed after it's loaded
		&&  TRY...ENDTRY will prevent crash in case when it's not loaded
		TRY
			loDoc = Thisform.oWB.oBJECT.Document
			WITH loDoc 
				&& PageMode: 
				&&	none — does not display bookmarks or thumbnails (default)
				&& 	bookmarks — displays the document and bookmarks
				&& 	thumbs — displays the document and thumbnails
				.setPageMode("none")
 
				&& LayoutMode:
				&&	DontCare — use the current user preference
				&&	SinglePage — use single page mode (as it would have appeared in pre-Acrobat 3.0 viewers)
				&&	OneColumn — use one-column continuous mode
				&&	TwoColumnLeft — use two-column continuous mode with the first page on the left
				&&	TwoColumnRight — use two-column continuous mode with the first page on the right
				.setLayoutMode("OneColumn")
 
				&& ViewMode:
				&&	Fit — Fits the entire page within the window both vertically and horizontally.
				&&	FitH — Fits the entire width of the page within the window.
				.setView("FitH")
 
				&& Zoom %, overrides ViewMode and vise verse. 
				.setZoom(50)
 
				&& Toolbar On/Off
				.setShowToolbar(.F.)
				&& Scrollbars On/Off
				.setShowScrollbars(.T.)
			ENDWITH
		CATCH TO oErr	
		FINALLY 	
			loDoc = null
		ENDTRY	
	ENDPROC

Where is the location of the actual documentation for the methods you're using in AdjustPdfView for setting PageMode, LayoutMode, etc.? I'm having trouble getting this to work... settings seem to be ignored for PageMode.

Laurie,

See Note 3 above the code.

Yes, there it is. Thanks for this post, btw, it is most helpful!