Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
尝试在Delphi XE6中发送密钥失败_Delphi - Fatal编程技术网

尝试在Delphi XE6中发送密钥失败

尝试在Delphi XE6中发送密钥失败,delphi,Delphi,下面是我用来将Ctrl+Shift+S键发送到PDF文档的完整例程。它应该显示“保存”对话框,但没有显示 该过程使用GetFiles打开驻留在sFolder中的pdf文档。sFolder中只有一个pdf文档 正如您可以从注释掉的行中看到的,我也尝试了sndkey32,但没有成功 procedure TForm1.Button1Click(Sender: TObject); var oBrowser: TBrowseForFolder; oList: TStringDynArray;

下面是我用来将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;

窗口
oShellExecuteInfo.Wnd
是Delphi过程中的一个窗口。您可以将其指定为
应用程序。句柄
。您似乎希望它将成为PDF查看器的主窗口,但事实并非如此

因此,您需要找到PDF查看器的主窗口。这涉及调用
枚举窗口
,以获取所有顶级窗口。然后,对于每个窗口,使用
GetWindowThreadProcessId
测试该窗口是否属于PDF查看器进程

其他一些评论:

  • 调用API函数时忽略了错误检查
  • 您应该使用
    SendInput
    而不是
    keybd\u event
  • 泄漏由
    ShellExecuteEx
    返回的进程句柄
  • ShellExecuteEx
    可能根本不返回进程句柄。这取决于文件关联的设置方式,以及Acrobat是否已在运行
  • 在发送输入之前,您可能需要等待新进程完成启动
  • 您的程序似乎假定安装的PDF查看器是Acrobat。如果不是呢