|
-
Mar 27th, 2007, 08:44 PM
#1
Thread Starter
Fanatic Member
Displaying PDF's in VB6
So I thought I was really smart and made a link to the Adobe PDF library and placed an Adobe control on my form. It displays PDF's just fine.
Problem is that some people don't have Adobe PDF reader installed. In those cases the program crashes and burns.
How can I get the program to gracefully display a "You need Adobe PDF Reader" message? Or just display an empty box when the Adobe control isn't loaded or handle things in some more graceful way?
Thanks!
--DB
-
Mar 28th, 2007, 04:34 AM
#2
Lively Member
Re: Displaying PDF's in VB6
You can use this code to check if Adobe reader is already installed!
<VBCODE>
Option Explicit
Private Const KEY_READ As Long = 131097
Private Declare Function RegOpenKeyEx _
Lib "advapi32.dll" _
Alias "RegOpenKeyExA" _
(ByVal hKey As Long, _
ByVal lpSubKey As String, _
ByVal ulOptions As Long, _
ByVal samDesired As Long, _
phkResult As Long) As Long
Private Declare Function RegQueryInfoKey _
Lib "advapi32.dll" _
Alias "RegQueryInfoKeyA" _
(ByVal hKey As Long, _
ByVal lpClass As String, _
lpcbClass As Long, _
ByVal lpReserved As Long, _
lpcSubKeys As Long, _
lpcbMaxSubKeyLen As Long, _
lpcbMaxClassLen As Long, _
lpcValues As Long, _
lpcbMaxValueNameLen As Long, _
lpcbMaxValueLen As Long, _
lpcbSecurityDescriptor As Long, _
lpftLastWriteTime As Any) As Long
Private Declare Function RegEnumKeyEx _
Lib "advapi32.dll" _
Alias "RegEnumKeyExA" _
(ByVal hKey As Long, _
ByVal dwIndex As Long, _
ByVal lpName As String, _
lpcbName As Long, _
ByVal lpReserved As Long, _
ByVal lpClass As String, _
lpcbClass As Long, _
ByVal lpftLastWriteTime As Long) As Long
Private Declare Function RegCloseKey _
Lib "advapi32.dll" _
(ByVal hKey As Long) As Long
Private Declare Function RegQueryValueEx _
Lib "advapi32" _
Alias "RegQueryValueExA" _
(ByVal hKey As Long, _
ByVal lpValueName As String, _
ByVal lpReserved As Long, _
ByRef lpType As Long, _
ByVal szData As String, _
ByRef lpcbData As Long) As Long
Private Const HKEY_CURRENT_USER = &H80000001
Private Const ERROR_SUCCESS = 0
Private Const REG_SZ = 1
Public Function GetAdobeAcrobatPath() As String
Dim CRegNodes As Collection
Set CRegNodes = New Collection
Set CRegNodes = GetRegKeysCol("Software\Adobe\Acrobat Reader")
GetAdobeAcrobatPath = GetRegValueString("Software\Adobe\AcrobatReader\" & _
CRegNodes.Item(1) & "\InstallPath", vbNullString)
Set CRegNodes = Nothing
End Function
Public Function GetRegKeysCol(ByVal MainKey As String, _
Optional ByVal hKey As Long = HKEY_CURRENT_USER) As Collection
Dim colTemp As Collection
Dim strItem As String
Dim lngKeyHandle As Long
Dim lngResult As Long
Dim lngSubKeyCount As Long
Dim lngMaxSubKeyLength As Long
Dim strKeyName As String
Dim lngIndex As Long
Dim lngKeyLength As Long
Set colTemp = New Collection
lngResult& = RegOpenKeyEx(hKey, MainKey, 0, KEY_READ, lngKeyHandle)
If lngResult = ERROR_SUCCESS Then
lngResult = RegQueryInfoKey(lngKeyHandle, vbNullString, 0&, ByVal 0&, lngSubKeyCount, lngMaxSubKeyLength, 0&, 0&, 0&, 0&, 0&, ByVal 0&)
For lngIndex = 0 To lngSubKeyCount - 1
lngKeyLength = lngMaxSubKeyLength + 1
strKeyName = VBA.String$(lngMaxSubKeyLength + 1, 0)
lngResult = RegEnumKeyEx(lngKeyHandle, lngIndex, strKeyName, lngKeyLength, 0&, vbNullString, 0&, ByVal 0&)
If lngResult = ERROR_SUCCESS Then
strItem = VBA.Left$(strKeyName, lngKeyLength)
colTemp.Add strItem, strItem
End If
Next lngIndex
Call RegCloseKey(lngKeyHandle)
Set GetRegKeysCol = colTemp
Set colTemp = Nothing
End If
End Function
Public Function GetRegValueString(ByVal SubKey As String, _
ByVal KeyName As String, _
Optional ByVal hKey As Long = HKEY_CURRENT_USER) As String
Dim lngResult As Long
Dim lngKeyHandle As Long
Dim lngMaxValueLength As Long
Dim strRegValueBuffer As String
Dim lngBuffSize As Long
lngResult = RegOpenKeyEx(hKey, ByVal SubKey, 0&, KEY_READ, lngKeyHandle)
If lngResult = ERROR_SUCCESS Then
lngResult = RegQueryInfoKey(lngKeyHandle, vbNullString, 0&, ByVal 0&, 0&, 0&, 0&, 0&, 0&, lngMaxValueLength, 0&, ByVal 0&)
'Create Buffer (set it to the maximal string length! NOTE NONEED FOR Trailing Null!!!
strRegValueBuffer = VBA.Space$(lngMaxValueLength)
lngBuffSize = lngMaxValueLength
'Query the value
lngResult = RegQueryValueEx(lngKeyHandle, ByVal KeyName, 0, REG_SZ, ByVal strRegValueBuffer, lngBuffSize)
'Return obtained value
If lngResult = ERROR_SUCCESS Then
GetRegValueString = VBA.Left$(strRegValueBuffer, lngBuffSize - 1)
Else
GetRegValueString = vbNullString
End If
'Close the key
RegCloseKey lngKeyHandle
Else
GetRegValueString = vbNullString
End If
End Function
</VBCODE>
IBM poster explaining virtual memory 1978
If it's there and you can see it--it's real
If it's not there and you can see it--it's virtual
If it's there and you can't see it--it's transparent
If it's not there and you can't see it--you erased it!
-
Mar 28th, 2007, 08:23 AM
#3
Re: Displaying PDF's in VB6
You can try this
1.Declare these
Code:
Private Declare Function ShellExecute Lib "shell32.dll" _
Alias "ShellExecuteA" _
(ByVal hwnd As Long, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As Long
Private Declare Function FindExecutable Lib "shell32.dll" Alias "FindExecutableA" (ByVal lpFile As String, ByVal lpDirectory As String, ByVal lpResult As String) As Long
2. Write this
Code:
Dim strPathToPDF As String '--path where file exists
Dim sReturnSpec As String * 100
Dim sDummy As String * 100
Dim iResult As Integer
iResult = FindExecutable(strPathToPDF, sDummy, sReturnSpec)
If iResult < 32 Then
Msgbox "PDF viewer program not found"
Exit Sub
End If
Call ShellExecute(0, "Open", strPathToPDF, 0&, 0&, SW_SHOWDEFAULT)
-
Mar 28th, 2007, 10:37 AM
#4
Thread Starter
Fanatic Member
Re: Displaying PDF's in VB6
First, thanks for your help. Sadly I don't think either method will work.
When I made my program I clicked on Components then clicked on the Adobe Acrobat control. I dragged the Adobe control onto my form. This makes my program appear to be able to read Adobe files without using the shell function to call out to another program.
The problem is that my program now REQUIRES adobe to be installed BEFORE it will properly load.
Using either of the above two methods as soon as the program loads it will either run fine and report that Adobe exists or it will crash saying that a component is not installed.
The same problem would exist for any missing OCX not just Adobe. There must be a way around this, right? How would you handle it if some component (OCX or DLL) was not installed or was deleted after installation?
--DB
-
Mar 28th, 2007, 10:49 AM
#5
Re: Displaying PDF's in VB6
As for viewing PDF's without having to use the control, you can use a Web Browser control and navigate to the desired file name. I used this trick in a .NET report viewer app I just wrote but the same technique should work in VB6 as well. Of course, this assumes that the Adobe Acrobat reader is installed on the target system. If it's not you get the standard IE "download file" dialog. You could use the routines provided to see if Acrobat is installed and, if not, redirect the browser to the appropriate Adobe Acrobat download web page.
As for missing OCX's or DLL's that disappear after an install, there's not a lot you can do except crash. If a COM object isn't installed and registered locally, you're essentially out of luck. You could check registry settings for your required components in your Sub Main prior to loading a form or accessing any objects but this might be more trouble than it's worth depending on the application.
-
Mar 28th, 2007, 10:50 AM
#6
Frenzied Member
Re: Displaying PDF's in VB6
Use late binding for the control and create the control at runtime.
-
Mar 28th, 2007, 10:52 AM
#7
Re: Displaying PDF's in VB6
If you check Acrobats site for licensing on redistribution I think it may be ok to distribute the ocx as I see Reader packaged in other programs that may rely upon it. These are professional commercial programs so it would be worth looking into.
See my two threads on PDFs on a Form with the pdf.ocx or AcroPDF.dll
http://vbforums.com/showpost.php?p=2574725&postcount=2
http://vbforums.com/showpost.php?p=2800128&postcount=7
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum. 
Microsoft MVP 2006-2011
Office Development FAQ (C#, VB.NET, VB 6, VBA)
Senior Jedi Software Engineer MCP (VB 6 & .NET), BSEE, CET
If a post has helped you then Please Rate it! 
• Reps & Rating Posts • VS.NET on Vista • Multiple .NET Framework Versions • Office Primary Interop Assemblies • VB/Office Guru™ Word SpellChecker™.NET • VB/Office Guru™ Word SpellChecker™ VB6 • VB.NET Attributes Ex. • Outlook Global Address List • API Viewer utility • .NET API Viewer Utility •
System: Intel i7 6850K, Geforce GTX1060, Samsung M.2 1 TB & SATA 500 GB, 32 GBs DDR4 3300 Quad Channel RAM, 2 Viewsonic 24" LCDs, Windows 10, Office 2016, VS 2019, VB6 SP6 
-
Mar 28th, 2007, 10:56 AM
#8
Thread Starter
Fanatic Member
Re: Displaying PDF's in VB6
Excellent answers. First, Shragel, what's late binding? Any links on where a guy could read up on late binding? Sounds promising!
Next, RobDog, I agree. It looks like you can redistribute the control with your application. You do need to fill in a form and fax it in. Now I need to figure out what components I need to distribute. Any suggestions on that front? The package and deployment wizard comes up with ADOBE.EXE but of course that's not a file anywhere on my system.
Thanks guys and sorry for newbie questions!
--DB
Last edited by Darkbob; Mar 28th, 2007 at 11:00 AM.
-
Mar 28th, 2007, 11:06 AM
#9
Re: Displaying PDF's in VB6
Yes, in my second link it specifies the cox or dll depending on the version of Acrobat Reader.
Version 5 or 6 will be pdf.ocx and version 7 or 8 will be AcroPDF.dll
By packaging Reader with your installer and noting its a required app to install if they currentlydont have it will be more professional then telling them to download it.
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum. 
Microsoft MVP 2006-2011
Office Development FAQ (C#, VB.NET, VB 6, VBA)
Senior Jedi Software Engineer MCP (VB 6 & .NET), BSEE, CET
If a post has helped you then Please Rate it! 
• Reps & Rating Posts • VS.NET on Vista • Multiple .NET Framework Versions • Office Primary Interop Assemblies • VB/Office Guru™ Word SpellChecker™.NET • VB/Office Guru™ Word SpellChecker™ VB6 • VB.NET Attributes Ex. • Outlook Global Address List • API Viewer utility • .NET API Viewer Utility •
System: Intel i7 6850K, Geforce GTX1060, Samsung M.2 1 TB & SATA 500 GB, 32 GBs DDR4 3300 Quad Channel RAM, 2 Viewsonic 24" LCDs, Windows 10, Office 2016, VS 2019, VB6 SP6 
-
Mar 28th, 2007, 11:08 AM
#10
Re: Displaying PDF's in VB6
For an explaination of Late Binding, its basically where you declare the object variable as an "Object" as oppossed to the actual type.
See my thread on Early vs Late Binding for more details and code examples.
http://vbforums.com/showthread.php?t=406640
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum. 
Microsoft MVP 2006-2011
Office Development FAQ (C#, VB.NET, VB 6, VBA)
Senior Jedi Software Engineer MCP (VB 6 & .NET), BSEE, CET
If a post has helped you then Please Rate it! 
• Reps & Rating Posts • VS.NET on Vista • Multiple .NET Framework Versions • Office Primary Interop Assemblies • VB/Office Guru™ Word SpellChecker™.NET • VB/Office Guru™ Word SpellChecker™ VB6 • VB.NET Attributes Ex. • Outlook Global Address List • API Viewer utility • .NET API Viewer Utility •
System: Intel i7 6850K, Geforce GTX1060, Samsung M.2 1 TB & SATA 500 GB, 32 GBs DDR4 3300 Quad Channel RAM, 2 Viewsonic 24" LCDs, Windows 10, Office 2016, VS 2019, VB6 SP6 
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|