【问题标题】:how to Simulate Ctrl+ c in Delphi如何在Delphi中模拟Ctrl+c
【发布时间】:2013-07-11 22:49:35
【问题描述】:

有什么方法可以在 delphi 中模拟 Ctrl+C 命令吗? 问题是我希望从另一个应用程序中,例如在选择目标文本后从记事本复制文本。

【问题讨论】:

  • 发送WM_COPY 消息。
  • @ANdreas 我之前只是尝试过,但它不适用于其他进程。
  • @Oussaki:确实如此,所以你一定不能正确使用它。
  • 当您尝试发送wm_Copy 时,是否在目标窗口中选择了任何文本?这是复制发生的先决条件。

标签: delphi


【解决方案1】:

有什么方法可以模拟CTRL+C

这样做的方法是使用Win32的SendInput函数来合成击键。这是一个例子:

procedure SendCtrlC;
var
  Inputs: array [0..3] of TInput;
begin
  ZeroMemory(@Inputs, SizeOf(Inputs));
  Inputs[0].Itype := INPUT_KEYBOARD;
  Inputs[0].ki.wVk := VK_CONTROL;
  Inputs[0].ki.dwFlags := 0; // key down
  Inputs[1].Itype := INPUT_KEYBOARD;
  Inputs[1].ki.wVk := ord('C');
  Inputs[1].ki.dwFlags := 0; // key down
  Inputs[2].Itype := INPUT_KEYBOARD;
  Inputs[2].ki.wVk := ord('C');
  Inputs[2].ki.dwFlags := KEYEVENTF_KEYUP;
  Inputs[3].Itype := INPUT_KEYBOARD;
  Inputs[3].ki.wVk := VK_CONTROL;
  Inputs[3].ki.dwFlags := KEYEVENTF_KEYUP;
  SendInput(4, Inputs[0], SizeOf(Inputs[0]));
end;

当然,您希望接收 CTRL+C 击键的应用程序需要具有输入焦点。

【讨论】:

    【解决方案2】:

    (让我先说使用剪贴板进行进程间通信是一个坏主意。剪贴板属于用户,您的应用程序只能在用户选择这样做的情况下使用它。)

    如果您在记事本中选择了文本,这会将内容放入 Delphi 表单上的 TMemo(仅使用 TMemoTButton;将 ClipBrd 添加到您的使用子句中):

    procedure TForm1.Button1Click(Sender: TObject);
    var
      NpWnd, NpEdit: HWnd;
    begin
      Memo1.Clear;
      NpWnd := FindWindow('Notepad', nil);
      if NpWnd <> 0 then
      begin
        NpEdit := FindWindowEx(NpWnd, 0, 'Edit', nil);
        if NpEdit <> 0 then
        begin
          SendMessage(NpEdit, WM_COPY, 0, 0);
          Memo1.Lines.Text := Clipboard.AsText;
        end;
      end;
    end;
    

    结果示例:

    如果没有先选择文本,请先发送WM_SETSEL 消息。传递 0 和 '-1' 的值会选择所有文本。

    procedure TForm1.Button1Click(Sender: TObject);
    var
      NpWnd, NpEdit: HWnd;
    begin
      Memo1.Clear;
      NpWnd := FindWindow('Notepad', nil);
      if NpWnd <> 0 then
      begin
        NpEdit := FindWindowEx(NpWnd, 0, 'Edit', nil);
        if NpEdit <> 0 then
        begin
          SendMessage(NpEdit, EM_SETSEL, 0, -1);
          SendMessage(NpEdit, WM_COPY, 0, 0);
          Memo1.Lines.Text := Clipboard.AsText;
        end;
      end;
    end;
    

    【讨论】:

    • 那很好用。为什么我不能在这个网站上问更多问题?
    • @Oussaki:我不知道你为什么不能问更多问题。您应该查看Meta Stack Overflow 以获取该类型的信息;这是有关 StackOverflow 的工作原理、设计和指南的问题所在。 (你看到我也回复了你的other question?)
    • ahaha 谢谢你,你是这里最好的。 (y)
    猜你喜欢
    • 2010-12-23
    • 1970-01-01
    • 2013-01-01
    • 2017-11-03
    • 1970-01-01
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多