View PDF in VFP Form

MS Web Browser control

can be used to display contents of different type of files, including PDF.


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
1
2
3
4
5
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 or Acrobat 9.0 SDK at http://www.adobe.com/devnet/acrobat.html?navID=downloads.
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.
$SAMPLECODE$
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
	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

Comments

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 <b><i>Note 3</i></b> above the code.

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

Laure,
Where did you find you find the Methods to call. I am looking to select all text on a pdf and copy it to clipboard so that I can extact the text I need.

Thanks,
Bill

Nice bit of VFP coding works a treat not problems at all

Thanks

John

Congratulations, it is a site with many high quality articles on VFP !

Thanks for the article.
I am just wondering what else have to be pre-installed on the computer running this code above.
I mean: if it is an XP, Vista, 7 does it need Acrobat Reader to be installed in order to work?
If it is clean operating system, not having any Adobe stuff, do I need to copy, or register something, somewhere in order to work?
Thank you very much for your response!

Yes it requires Acrobat PDF ActiveX control to be installed on PC. It's a part of Acrobat Reader or Acrobat installation.

And...in the case that in the procedure showpdf() I "Navigate2" an .html file for example ( not to a .pdf file ), I will not need to register any .dll -s, because Windows has all the necessary stuff for html viewing...Is that right?
My program will be used by users, so I just wanted to be sure that they will not have any problems at installation and running the .exe,
in fact I dont want any further ocx or dll registrations in Windows in order to work. (these registrations might be "complex" operations for them...)
THNX!

The Web Browser control is part of IE. IOW, it'll be available as long as you have IE installed on PC. It can display HTML and some other file types natively but for the rest you'll have to install appropriate plugins.

when I run this, the message appear :(OLE error code 0x80004005: unspecified error). I cant solve this. what happend ?? and how to solve it..??
thanks
Iam use Vfp 7

I would first make sure that PDF files can be viewed in Internet Explorer

I had tried with NOTE2 above, and pdf was appear in IE (Run no trouble), I also had trid in Vfp9 and run no trouble too, actually I want to run your this sample in Vfp7 ( I see code TRY..ENDTRY in in Vfp isn't available), the message 'OLE error code 0x80004005: unspecified error' is appear every I run the form , if I push Ignore command button, this sample is Run, but this error annoy. [I have't wanted move to Newest Vfp like Vfp9]. I have just remove mozila firefox and changed with IE
Thanks so much sergey, I wait you response for solve this. thanks

It looks like you didn't put <b>NODEFAULT</b> in the Refresh method.

I have also this error 0x80004005 wen running this program, can this be solved ? I have NODEFAULT in refresh mode

PROCEDURE errhand
PARAMETER merror, mess, mess1, mprog, mlineno

IF merror = 1426 &&--OLE error code 0x"name".
*--Ignore and CONTINUE
ENDIF

Hi, i have been using this code for about 6 months now and it's been working great (thank you!). However, in the last week or so, suddenly the PDF opens up in it's own Adobe Window rather than inside the VFP9 form it was originally displaying in. The reason I like it inside the form is because it forces the user to exit (I put an Exit button on the form to release it). Suddenly it opens the PDF in a separate Adobe Acrobat window, and opens the blank form behind Adobe. In order to exit, I have to exit out of Adobe, then hit the Exit button of the form (which is blank because the PDF didn't load inside it). Any idea why this would suddenly happen? No code has been changed.

Thanks!

Hi Ginny,

See <b>Note 1</b> in the article

Sergey,
This is great, I am trying to select text from PDF and copy to clipboard for further processing. I am new to OLE Automation and having trouble finding Methods to call. I've tried note 3 and looked through the api documentation but did not see what I needed or even the navigate2 Method that you used. Any help with selecting all the text on pdf and copying to clipboard would be great.

Thanks,
Bill

Hi Bill,

You can use Acrobat Reader toolbar to select and copy text to clipboard.

I just found this article recently and it helped me a lot. Thanks for sharing your knowledge. Can you help me on how to print the viewed pdf file in vfp form.

You can use Acrobat Reader toolbar to print viewed PDF.

Hi,
Very much needed stuff for me. Thank you
But, now, I need to make programmatically to make Display in Browser checked.
How can I do this?
I use both IE and FF
Sincerely,

This worked perfectly. I've used it for PDF, HTML, and MHT file formats. Thanks again Sergey

Hi... i did everything properly. but when i try to execute the code, an ADOBE ACROBAT message window appears but with empty message and an OK button. then my PDF contents would flash in the web browser control but just in a flash and then disappears the control goes white again.

Windows7 64bit

Hi Sergey,

Many thanks for the helps you've rendered to many people. Am new into VFP6 programming. Can you give me a details explanation on how to use the Scanner activeX Control in VFP6? I suppose it is meant to be used to control a TWAIN scanner from within a VFP6 form. Please help.

Regards

Afunmai

I added html5 to the above solution:
thisform.txdat.Value = GETFILE("PDF","Open pdf","Open",1,"Open pdf")

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
LOCAL lcHtml,lcf, lcFile
lcFile = TRIM(thisform.txdat.Value)
lcFile = "file://"+STRTRAN(lcFile,'\',"/")

lcHtml = "&lt;html&gt;"
lcHtml = lcHtml + "&lt;head&gt;"
lcHtml = lcHtml + "&lt;title&gt;Pdf viewer&lt;/title&gt;"
lcHtml = lcHtml + "&lt;/head&gt;"
lcHtml = lcHtml + "&lt;body&gt;"
lcHtml = lcHtml + '&lt;object width="100%" height="100%" data="'+lcFile+'"&gt;&lt;/object&gt;'
lcHtml = lcHtml + "&lt;/body&gt;"
lcHtml = lcHtml + "&lt;/html&gt;"
lcf = ADDBS(SYS(2023))+"pdfview.html"
IF FILE(lcf)
	ERASE (lcf) RECYCLE
ENDIF 
STRTOFILE(lcHtml,lcf)
thisform.cpdffilename = lcf
thisform.showpdf()

Hi, I'm currently using your "View PDF in VFP form" code. I was hoping I can introduce an auto "PrintAll". I don't get an error, but it seems the "PrintAll" request gets ignored (Note: If security settings do not allow printing, this method is ignored.). Have you ever tried "PrintAll".

Not sure if you are receiving comments/questions?
Jeff

Very good code: View PDF in VFP Form.
Work instantly with Adobe 11 + Windows 7.

I'm lost in step 5 & 6.

Step 5, copy code from Procedure ShowPdf, is it copy the whole text starting: Public oforml?
I tried to paste it to oWB.init and got an error Methods and events cannot contain nested procedures or class definitions

Step 6, copy code from command1.Click, is it means copy the whole text starting: PROCEDURE AdjustPdfView...

Thanks for the help