以下是我用来将Ctrl + Shift + S键发送到PDF文档的完整例程。它应该显示保存对话框但不能这样做。
该过程使用GetFiles打开驻留在sFolder中的pdf文档。 sFolder中只有一个pdf文档。
从注释掉的行中可以看出,我也尝试了sndkey32但没有成功。
procedure TForm1.Button1Click(Sender: TObject);
var
oBrowser: TBrowseForFolder;
oList: TStringDynArray;
sFile: string;
sFolder: string;
oShellExecuteInfo: TShellExecuteInfo;
begin
oBrowser := TBrowseForFolder.Create(self);
oBrowser.Execute;
sFolder := oBrowser.Folder;
oBrowser.Free;
if DirectoryExists(sFolder) then begin
oList := TDirectory.GetFiles(sFolder, '*.pdf', TSearchOption.soAllDirectories);
if Length(oList) > 0 then begin
for sFile in oList do begin
FillChar(oShellExecuteInfo, SizeOf(oShellExecuteInfo), 0);
oShellExecuteInfo.cbSize := SizeOf(TShellExecuteInfo);
with oShellExecuteInfo do begin
fMask := SEE_MASK_NOCLOSEPROCESS;
Wnd := Application.Handle;
lpFile := PChar(sFile);
nShow := SW_SHOWNORMAL;
end;
if ShellExecuteEx(@oShellExecuteInfo) then begin
ShowWindow(oShellExecuteInfo.Wnd, 1);
SetForegroundWindow(oShellExecuteInfo.Wnd);
Winapi.Windows.SetFocus(oShellExecuteInfo.Wnd);
SendKey(Ord('s'), [ssCtrl, ssShift], False);
// if sndkey32.AppActivate('adobe') then
// sndkey32.SendKeys('^+S', False);
end;
end;
end;
end;
end;
procedure TForm1.SendKey(key: Word; const shift: TShiftState; specialkey: Boolean);
type
TShiftKeyInfo = record
shift: Byte;
vkey: Byte;
end;
ByteSet = set of 0 .. 7;
const
shiftkeys: array [1 .. 3] of TShiftKeyInfo = ((shift: Ord(ssCtrl); vkey: VK_CONTROL), (shift: Ord(ssShift); vkey: VK_SHIFT), (shift: Ord(ssAlt); vkey: VK_MENU));
var
flag: DWORD;
bShift: ByteSet absolute shift;
j: Integer;
begin
for j := 1 to 3 do begin
if shiftkeys[j].shift in bShift then keybd_event(shiftkeys[j].vkey, MapVirtualKey(shiftkeys[j].vkey, 0), 0, 0);
end;
if specialkey then flag := KEYEVENTF_EXTENDEDKEY
else flag := 0;
keybd_event(key, MapVirtualKey(key, 0), flag, 0);
flag := flag or KEYEVENTF_KEYUP;
keybd_event(key, MapVirtualKey(key, 0), flag, 0);
for j := 3 downto 1 do begin
if shiftkeys[j].shift in bShift then keybd_event(shiftkeys[j].vkey, MapVirtualKey(shiftkeys[j].vkey, 0), KEYEVENTF_KEYUP, 0);
end;
end;
答案 0 :(得分:3)
窗口oShellExecuteInfo.Wnd
是Delphi流程中的一个窗口。您将其指定为Application.Handle
。您似乎希望它将成为PDF查看器的主窗口,但事实并非如此。
因此您需要找到PDF查看器的主窗口。这需要调用EnumerateWindows
来获取所有顶级窗口。然后,对于每一个,使用GetWindowThreadProcessId
来测试窗口是否由PDF查看器进程拥有。
其他一些评论:
SendInput
而不是keybd_event
。 ShellExecuteEx
返回的进程句柄。 ShellExecuteEx
可能根本不返回进程句柄。这取决于文件关联的设置方式,以及Acrobat是否已在运行。