【问题标题】:capture a text selected with the mouse捕获用鼠标选择的文本
【发布时间】:2010-11-08 09:19:18
【问题描述】:

我正在尝试制作一个程序,当我按下热键时,它会将某个文本连接到窗口中的选定文本。例如:我有文本“捕获一个用鼠标选择的文本”,我用鼠标选择了“文本”这个词,现在当我按下某个热键时,它会将我复制到剪贴板以下: xxx+文字+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 编辑框的文本。有没有办法解决这个问题?

谢谢!

【问题讨论】:

  • 您在 SO 上发布了三个问题,所有这些问题都在一个新帐户中。您必须不要在每次发布新问题时都创建新帐户!
  • 他可以创建任意数量的帐户。但他不应该。 SO 没有关于创建帐户或匿名的规则。

标签: delphi text clipboard return selected


【解决方案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.使用selection计算选中的文本(整个文本的子串) 从第 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;

【讨论】:

  • 没有。我希望它粘贴我从 delphi 应用程序外部选择的文本。比如 IE 或 firefox 或 Microsoft Word 等。
  • 这样可以吗?如果不是 AttachThreadInput(GetCurrentThreadId, GetWindowThreadProcessId(GetForegroundWindow), true) 然后 RaiseLastOSError;试试 SendMessage(GetFocus, WM_COPY, 0, 0); lookup_word:=剪贴板.astext; edit1.Text := lookup_word; Clipboard.AsText := ' edit1.text '; SendMessage(GetFocus, WM_PASTE, 0, 0);最后 AttachThreadInput(GetCurrentThreadId, GetWindowThreadProcessId(GetForegroundWindow), false);
  • 嗯,这取决于你想要实现的目标,但对于“获取选定的文本”,我更喜欢在不涉及剪贴板的情况下在内存中获取/操作它。
【解决方案2】:

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

【讨论】:

  • 我没有看到剪贴板被滥用。该操作由一个特殊的按键启动,与 Ctrl+C 没有什么不同。假设用户知道该操作是剪贴板操作,用户启动的操作可以对剪贴板做任何他们想做的事情。
  • @Rob,很公平,但我经常看到这种事情在没有通知用户的情况下实现。用户认为他们有一个简洁的通用拼写检查器或计算器,并想知道为什么他们的剪贴板会被覆盖。
猜你喜欢
  • 2012-06-15
  • 1970-01-01
  • 1970-01-01
  • 2017-04-05
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
  • 2017-05-27
  • 2021-10-12
相关资源
最近更新 更多