Reputation: 321
I have a problem with opening pdf file from Delphi. I need to open pdf with parameters, because I want to create help manual for my program. I try to use shellExecute, but this function needs path for reader pdf.
procedure TForm3.Button2Click(Sender: TObject);
var e,s:String;
begin
s:='/A nameddest=somePlaceInPDF pathToMyFile.pdf';
e:='AcroRd32';
ShellExecute(handle,'open',pchar(e),pchar(s),nil,sw_show);
end;
The program runs, but it is not a solution for me. Some users can use other pdf reader. Do you know a way to skip adding a reader path?
The other way is
if ShellExecute(handle,'open',pchar(e),pchar(s),nil,sw_show) < 32 then
begin
ShellExecute(0,0,'rundll32.exe','shell32.dll,OpenAs_RunDLL pathToMyFile.pdf',0,SW_SHOW);
end;
I think, that I need to some method, which pull the path from the pdf reader. Is this the best solutions for this problem?
Upvotes: 2
Views: 6200
Reputation: 255
pdf files could be associated with another program, so "FindExecutable" is not a reliable way to find the installed Acrobat Reader program. I use the registry key : HKEY_CLASSES_ROOT\Software\Adobe\Acrobat\Exe
procedure TfrmFsYtd.btnPdfHelpTestClick(Sender: TObject);
var strAcro, strParam:string;
Registry: TRegistry;
begin
// Get the users' installed Adobe Reader from the registry >>
Registry:=TRegistry.Create;
Registry.RootKey:=HKEY_CLASSES_ROOT;
Registry.OpenKey('Software\Adobe\Acrobat\Exe',False);
strAcro :=Registry.ReadString('');
Registry.Free;
// Use the installed Adobe Reader to open your pdf- help- file at a specific page >>
strParam := ' /A page=4 "'+ProgPath+'FsYtd_Manual.pdf"';
ShellExecute(Handle, 'open', PChar(strAcro), PChar(strParam),nil, SW_SHOWNORMAL);
end;
Upvotes: 0
Reputation: 321
This is a best answer to my question
procedure TForm3.Button2Click(Sender: TObject);
var s, result:String;
path: array[0..250] of char
begin
s:='/A nameddest=somePlaceInPDF "pathToMyFile.pdf"';
FindExecutable('pathToMyFile.pdf',nil,path);
result := trim(StrPas(path));
ShellExecute(handle,nil,pchar(result),pchar(s),nil,sw_show);
end
Upvotes: 0
Reputation: 4878
Open a PDF with the default system application
ShellExecute(Handle, nil, 'pathToMyFile.pdf', nil, nil, SW_SHOW);
If lpOperation
is nil
the default verb is used.
Open a PDF file with parameters
The way to open a PDF file with parameters from command line on Windows is:
"C:\Program Files\Adobe\Reader 11.0\Reader\AcroRd32.exe" /A "zoom=1000=OpenActions" "C:\Documents and Settings\winUser\Desktop\wss-v1.1-spec-errata-os-SOAPMessageSecurity.pdf"
The above opens the PDF file with a x1000 zoom (not very useful indeed).
To achieve the same result with ShellExecute
do the following:
var
application, appParams, fileName,
shellParams: string;
begin
application := 'AcroRd32.exe';
appParams:= '/A "zoom=1000=OpenActions"';
fileName := 'C:\Documents and Settings\winUser\Desktop\wss-v1.1-spec-errata-os-SOAPMessageSecurity.pdf';
shellParams := Format('%s "%s"', [appParams, fileName]);
ShellExecute(Handle, nil, PChar(application), PChar(shellParams), nil, SW_SHOW);
end;
Here is PDF Open Parameters for reference.
Finally (with no try
) notice that PDF Open Parameters are specific of an application so a different reader may ignore them in the best case; in the worst, the application will simply refuse to start.
I'd recommend to use open parameters only after being sure that the correct application is available on the client; if not, use the first method.
Upvotes: 2
Reputation: 613602
If you wish to pass parameters to an executable, then you are going to ignore any associations and require the presence of a specific executable. Because specific parameters will only be valid for one specific executable. That is, parameters for Acrobat won't be understood by Foxit, and vice versa.
In which case you should invoke it with CreateProcess
. To locate the executable for Acrobat Reader, refer to this question: How to get Adobe Reader full path(including executable file name)? There will be similar approaches for other PDF programs.
The real point of ShellExecute
is that it understands the system and user preferences for file associations. The shell knows which application should be used to open different file types, and where to find that application.
As a broad rule, if you know the location of the executable, use CreateProcess
. If you know the location of a document and want the system to find the executable, use ShellExecute(Ex)
.
So, pass the full path to the PDF file to ShellExecute
and let the system find and open the associated application.
ShellExecute(0, 'open', PChar(PdfFileName), nil, nil, SW_SHOW);
If you want to have proper error handling use ShellExecuteEx
. You might also replace 'open'
with nil
and let the system choose the default action.
Upvotes: 2