我是开源项目的主要开发人员(http://nbcgib.uesc.br/lec/software/editores/tinn-r/en)。
现在项目的用户指南是PDF格式(在LaTeX下制作)。
我正在尝试制作一个程序,以编程方式在PDF 中的指定目的地/部分打开用户指南。
由于我不知道用户的默认PDF查看器,我正在开发一个支持专业的程序:Sumatra,Foxit和Adobe。
该程序适用于苏门答腊岛,但不适用于Foxit和Adobe。
代码下方:
function GetAssociation(const DocFileName: string): string;
var
FileClass: string;
Reg: TRegistry;
begin
Result:= '';
Reg:= TRegistry.Create(KEY_EXECUTE);
Reg.RootKey:= HKEY_CLASSES_ROOT;
FileClass:= '';
if Reg.OpenKeyReadOnly(ExtractFileExt(DocFileName)) then
begin
FileClass:= Reg.ReadString('');
Reg.CloseKey;
end;
if FileClass <> '' then begin
if Reg.OpenKeyReadOnly(FileClass +
'\Shell\Open\Command') then
begin
Result:= Reg.ReadString('');
Reg.CloseKey;
end;
end;
Reg.Free;
end;
procedure TfrmTinnMain.OpenUserGuidePDF(sWhere: string);
var
sFile,
sViewerDefault,
sParameter: string;
begin
sViewerDefault:= GetAssociation('.pdf');
if pos('Sumatra', // Sumatra: OK
sViewerDefault) > 0 then
sParameter:= '-reuse-instance ' +
'-named-dest ' +
sWhere
else if pos('Foxit', // Foxit: opens the file, but not at the named destination
sViewerDefault) > 0 then
sParameter:= '/A ' +
'page=100'
else if pos('Adobe', // Adobe: opens the file, but not at the named destination
sViewerDefault) > 0 then begin
sWhere:= StringReplace(sWhere,
'"',
'',
[rfReplaceAll]);
sParameter:= '/A ' +
'"' +
'nameddest=' +
sWhere +
'"';
end
else
sParameter:= '';
sFile:= sPathTinnR +
'\doc\User guide.pdf';
try
// Open PDF viewer
ShellExecute(0,
'open',
Pchar(sFile),
Pchar(sParameter),
nil,
sw_shownormal);
except
MessageDlg('PDF viewer is not accessible!',
mtInformation,
[mbOk],
0);
end;
end;
procedure TfrmTinnMain.menHelUserGuideClick(Sender: TObject);
begin
OpenUserGuidePDF('"Contents"');
end;
答案 0 :(得分:0)
我要感谢所有观察和建议!
我发现(与Tinn-R联合)分发便携版SumatraPDF更实际。 如果苏门答腊是系统默认值,它将被使用。否则,将使用便携版。
在计算解决方案之下:
procedure TfrmTinnMain.OpenUserGuidePDF(sWhere: string);
var
sFile,
sViewerDefault,
sPathSumatra,
sParameter: string;
begin
sFile:= sPathTinnR +
'\doc\User guide.pdf';
sParameter:= '-reuse-instance ' +
'-named-dest ' +
sWhere;
try
sViewerDefault:= GetAssociation('.pdf');
if pos('Sumatra',
sViewerDefault) > 0 then
// Open default PDF viewer
ShellExecute(0,
'open',
Pchar(sFile),
Pchar(sParameter),
nil,
sw_shownormal)
else begin
sPathSumatra:= sPathTinnR +
'\sumatra\SumatraPDF.exe';
// Open SumatraPDF viewer
OpenCmdLine(sPathSumatra +
' "' +
sFile +
'"' +
sParameter,
sw_shownormal);
end;
except
MessageDlg('PDF viewer is not accessible!',
mtInformation,
[mbOk],
0);
end;
end;
电话:
procedure TfrmTinnMain.menHelUserGuideClick(Sender: TObject);
begin
OpenUserGuidePDF('"Contents"');
end;
必要的功能和程序:
{ Execute a complete shell command line without waiting. }
function OpenCmdLine(const CmdLine: string;
wWindowState: Word): Boolean;
var
sUInfo: TStartupInfo;
pInfo : TProcessInformation;
begin
{ Enclose filename in quotes to take care of long filenames with spaces. }
FillChar(sUInfo,
SizeOf(sUInfo),
#0);
with SUInfo do
begin
cb := SizeOf(sUInfo);
dwFlags := STARTF_USESHOWWINDOW;
wShowWindow:= wWindowState;
end;
Result:= CreateProcess(nil,
PChar(CmdLine),
nil,
nil,
False,
CREATE_NEW_CONSOLE or
NORMAL_PRIORITY_CLASS,
nil,
nil {PChar(ExtractFilePath(sFileName))},
sUInfo,
pInfo);
end;
function GetAssociation(const DocFileName: string): string;
var
FileClass: string;
Reg: TRegistry;
begin
Result:= '';
Reg:= TRegistry.Create(KEY_EXECUTE);
Reg.RootKey:= HKEY_CLASSES_ROOT;
FileClass:= '';
if Reg.OpenKeyReadOnly(ExtractFileExt(DocFileName)) then
begin
FileClass:= Reg.ReadString('');
Reg.CloseKey;
end;
if FileClass <> '' then begin
if Reg.OpenKeyReadOnly(FileClass +
'\Shell\Open\Command') then
begin
Result:= Reg.ReadString('');
Reg.CloseKey;
end;
end;
Reg.Free;
end;
欢迎任何建议!
一切顺利,
J.C.Faria
答案 1 :(得分:-1)
让Windows决定该文件类型的默认查看器:
ShellExecute(0, 'open', Filename, nil, nil, SW_SHOW);