2

我正在尝试制作一个程序,当我按下热键时,它将某个文本连接到窗口中的选定文本。例如:我有文本“捕获用鼠标选择的文本”,我用鼠标选择了“文本”这个词,现在当我按下某个热键时,它会将我复制到剪贴板以下内容:xxx+text+xxx。所以我的问题是如何返回鼠标选择的单词?

谢谢!!


从你告诉我的情况来看,我理解了这一点:

unit Unit4;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Clipbrd;

type
  TForm4 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure WMHotkey(var Message: TWMHotKey); message WM_HOTKEY;
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

implementation

const
  MY_ID = 123;

{$R *.dfm}

procedure TForm4.FormCreate(Sender: TObject);
begin
  RegisterHotKey(Handle, MY_ID, MOD_CONTROL, ord('1'));

end;

procedure TForm4.FormDestroy(Sender: TObject);
begin
  UnregisterHotKey(Handle, MY_ID);

end;

procedure TForm4.WMHotkey(var Message: TWMHotKey);
lookup_word: string;
begin
clipboard.clear;
  if Message.HotKey = MY_ID then
  begin

    if not AttachThreadInput(GetCurrentThreadId, GetWindowThreadProcessId(GetForegroundWindow), true) then
      RaiseLastOSError;

    try
      SendMessage( GetFocus, WM_GETTEXT, 0, 0 );
      lookup_word:= clipboard.astext;
      edit1.Text := lookup_word;
      Clipboard.AsText := '<font color=blue> edit1.text </font>';
      SendMessage(GetFocus, WM_PASTE, 0, 0);
    finally
      AttachThreadInput(GetCurrentThreadId, GetWindowThreadProcessId(GetForegroundWindow), false);
    end;


end;

end;
end;
end.

这个可以吗?


我设法按照我想要的方式创建我的应用程序。但我现在遇到了另一个问题。它不适用于 aspx 应用程序。它不会识别来自 aspx 编辑框的文本。有没有办法解决这个问题?

谢谢!

4

2 回答 2

1

如果我正确理解您的问题,那么“用鼠标选择的文本”的意思是编辑控件上的正常突出显示文本,例如 TEdit、TMemo 或 TRichEdit。如果是这种情况,那么 VCL 有一个 Seltext 属性,其中包含当前选定的文本。所以代码将类似于:(TMemo 控件的示例)

...
uses Clipbrd;
...
Clipboard.asText:= xxx + Memo1.SelText + xxx;
...

如果所选文本来自其他应用程序,那么,它非常依赖于应用程序使用的控件。如果控件是标准 Windows 控件或其后代(大部分),那么您可以通过向该控件发送消息来获取所选文本,但如果组件不是标准组件,它将无法正确响应消息。该方法需要知道目标控件的窗口句柄(在 Windows 单元中使用 GetFocus): 1. 通过发送 WM_GETTEXT 消息获取整个文本 2. 通过发送 EM_GETSEL 消息获取选择位置 3. 计算所选文本(整个文本的子字符串)使用第 2 点的选择位置。如果您有 vcl 源,则可以使用 StdCtrls 单元中的 TCustomEdit 类源代码实现作为参考。我的例子:

...
var
  Buff: array[0..65535] of char;
...
function CurrentSelectedText: string;
var
  hFocus: hWnd;
  aStart, aEnd: integer;
begin
  //added by andrei, attach input to current thread
  AttachThreadInput(GetCurrentThreadId, GetWindowThreadProcessId(GetForegroundWindow), true); 
  hFocus:= GetFocus;
  SendMessage(hFocus, WM_GETTEXT, 65535, integer(@buff));
  SendMessage(hFocus, EM_GETSEL, Integer(@aStart), Integer(@aEnd));
  result:= Copy(StrPas(Buff), 1+aStart, aEnd-aStart);
end;
于 2010-11-08T10:21:02.957 回答
0

请不要以这种方式滥用剪贴板。提供剪贴板是为了方便用户,而不是程序员。如果用户在剪贴板上有重要的东西,你将把它擦掉。而且您将导致意外/不需要的数据出现在剪贴板扩展器应用程序中。使用任何类型的远程桌面产品时,都会导致不需要的网络流量。

于 2010-11-08T13:47:36.830 回答