2010-11-08 5 views
2

Я пытаюсь создать программу, которая, когда я нажимаю горячую клавишу, конкатенирует определенный текст с выбранным текстом из окна. например: у меня есть текст «захват текст, выделенный мышью», я выбираю слово «текст» с помощью мыши, и теперь, когда я нажимаю какую-то горячую клавишу, она копирует меня в буфер обмена следующим образом: xxx + text + xxx , поэтому мой вопрос в том, как вернуть слово, выбранное мышью?захватить текст, выделенный мышью

спасибо !!


от того, что у меня сказал я understud это:

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. Есть ли способ обойти эту проблему?

спасибо!

+1

Вы отправили три вопроса на SO, все они в новой учетной записи. Вы должны * не * создавать новую учетную запись каждый раз, когда хотите опубликовать новый вопрос! –

+1

Он может создавать столько учетных записей, сколько ему нравится. Он ** должен ** не быть. На SO нет правил о создании учетных записей или анонимных. –

ответ

1

Если я правильно понимаю ваш вопрос, то, что вы подразумеваете под «выбранным с помощью мыши», является нормальным выделенным текстом в элементе управления редактированием, например, в TEdit, TMemo или TRichEdit. Если такой случай, то VCL имеет свойство Seltext, которое содержит выделенный текст. так что код будет выглядеть примерно так: (пример для управления ТМето)

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

Если выбранный текст из другого приложения, то его очень зависит от управления, используемого приложением. Если элемент управления является стандартным элементом управления Windows или его потомком (в основном), вы можете получить выделенный текст, отправив сообщение этому элементу управления, но если компонент не является стандартным, он не ответит на сообщение правильно. Этот метод требует, чтобы вы знали дескриптор окна целевого элемента управления (используя GetFocus в блоке Windows): 1. Получите весь текст, отправив сообщение WM_GETTEXT 2. Получите позицию выбора, отправив сообщение EM_GETSEL 3. Вычислите выбранный text (подстрока целого текста) с использованием выбора позиция из пункта 2. Если у вас есть источник vcl, вы можете использовать реализацию исходного кода класса TCustomEdit в модуле StdCtrls в качестве ссылки. мой пример:

... 
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; 
+0

№. Я хочу, чтобы он вставлял мне текст, выбранный вне приложения delphi. например IE или firefox или Microsoft Word и т. д. – Andrei

+0

это нормально?если не AttachThreadInput (GetCurrentThreadId, GetWindowThreadProcessId (GetForegroundWindow), true), то RaiseLastOSError; try SendMessage (GetFocus, WM_COPY, 0, 0); lookup_word: = clipboard.astext; edit1.Text: = lookup_word; Clipboard.AsText: = ' edit1.text'; SendMessage (GetFocus, WM_PASTE, 0, 0); finally AttachThreadInput (GetCurrentThreadId, GetWindowThreadProcessId (GetForegroundWindow), false); – Andrei

+0

хорошо, зависит от того, чего вы хотите достичь, но для «получения выделенного текста» я предпочитаю получать/манипулировать им в памяти, не вставляя буфер обмена в первый раз. –

0

Пожалуйста, не засоряйте в буфер обмена таким образом. Буфер обмена предоставляется для удобства пользователя, а не для программиста. Если у пользователя есть что-то важное в буфере обмена, вы собираетесь его уничтожить. И вы собираетесь вызывать непредвиденные/нежелательные данные в приложениях расширения буфера обмена. При использовании продуктов Remote Desktop вы будете создавать нежелательный сетевой трафик.

+1

Я не вижу злоупотребления в буфере обмена. Действие инициируется специальным нажатием клавиши, не отличающимся от Ctrl + C. Действия, инициируемые пользователем, могут делать все, что им нужно, в буфере обмена, предполагая, что пользователь знает, что действие является операцией буфера обмена. –

+0

@Rob, справедливо, но я часто вижу, что такое реализовано, не сообщая пользователю. Пользователь думает, что у них есть аккуратная маленькая универсальная проверка орфографии или калькулятор, и задаются вопросом, почему их буфер обмена переписывается. –

Смежные вопросы