Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Работа с выделенным текстом стороннего приложения


Автор: Vyadzmak 17.10.2008, 23:58
Помогите разобраться над вопросом. Суть его вот в чем:
В моей программе есть компонент memo. При копировании текста из сторонних программ, ctrl+с, ctrl+insert, или спомощью
контекстного меню все получается замечательно. Текста заноситься в буфер, а оттуда прямиком в memo.
Так вот, мне надо реализовать функцию, которая при выделении текста, вернее при его завершении, то есть
при отпускании левой клавиши мыши, сама занесет выделенный текст в буфер обмена. У меня есть код:

unit hk1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ClipBrd, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
PrevHwnd: Hwnd;
procedure wMMOUSEUP(var Msg: TWMLBUTTONUP); message WM_LBUTTONUP;
procedure WMChangeCBChain(var Msg: TWMChangeCBChain);
message WM_CHANGECBCHAIN;
procedure WMDrawClipboard(var Msg: TWMDrawClipboard);
message WM_DRAWCLIPBOARD;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  len:integer;
  H: THandle;
implementation

{$R *.dfm}



procedure TForm1.wMMOUSEUP(var Msg: TWMLBUTTONUP);
begin

!!!!ВОТ ЧТО ЗДЕСЬ НАПИСАТЬ, ИЛИ ПОДСКАЖИТЕ ДРУГОЙ МЕТОД РЕАЛИЗАЦИИ



end;

procedure TForm1.WMChangeCBChain(var Msg: TWMChangeCBChain);
begin
if PrevHWnd = Msg.Remove then
PrevHWnd := Msg.Next;
if Msg.Remove <> Handle then
SendMessage(PrevHWnd, WM_CHANGECBCHAIN, Msg.Remove, Msg.Next);
end;

procedure TForm1.WMDrawClipboard(var Msg: TWMDrawClipboard);
var
P: PChar;

begin
SendMessage(PrevHWnd, WM_DRAWCLIPBOARD, 0, 0);
if Clipboard.HasFormat(CF_TEXT) then
begin
H := Clipboard.GetAsHandle(CF_TEXT);
Len := GlobalSize(H) + 1;
P := GlobalLock(H);
Memo1.SetTextBuf(P);
GlobalUnlock(H);
end;
Msg.Result := 0;
end;



procedure TForm1.FormCreate(Sender: TObject);
begin
PrevHwnd := SetClipboardViewer(Handle);
end;


end.
Так вот помогите реализовать функцию, что бы моя программа в сторонних приложениях отлавливала отпускание левой клавиши мыши и выделенный текст заносила в буфер или
сразу передавала в мою программу в компонент memo. Заранее спасибо

Автор: Vyadzmak 18.10.2008, 01:22
Ребят, помогите очень нужно. Проект горит!!!!!! Буду очень признателен

Автор: Christoph 18.10.2008, 15:10
Код

procedure TForm1.FormCreate(Sender: TObject);
begin
PrevHwnd := SetClipboardViewer(Handle);
end;


Может быть так будет правильней...
Код

procedure TForm1.FormCreate(Sender: TObject);
begin
PrevHwnd := SetClipboardViewer(Memo1.Handle);
end;


и мне кажется что переменной PrevHwnd лучше быть глобальной

и зачем описывать все сообщения?  
Сообщение WM_DRAWCLIPBOARD посылается первому окну в цепочке окон просмотра буфера обмена, когда изменяется содержание буфера обмена. Это дает возможность окну просмотра буфера обмена отобразить его новое содержание.
а что бы его изменить надо скопировать...Мое мнение - этосообщение не подоходит :(


Автор: Christoph 18.10.2008, 16:41
Вот например для небольшого эксперимента smile
Код

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
  public
   end;

var
  Form1: TForm1;
   PrevHwnd: HWND;
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
PrevHwnd := SetClipboardViewer(Memo1.Handle);
end;


Поидеи, как только скопировали...оно должно отобразиться с мемо :(

Автор: MetalFan 18.10.2008, 19:13
Christoph, а при чем тут хэндл мемы? где обработка WM_DRAWCLIPBOARD и WM_CHANGECBCHAIN?

Автор: Christoph 18.10.2008, 19:27
Функция SetClipboardViewer:

Данная функция добавляет определяемое окно к цепочке окон просмотра буфера обмена. а Окно просмотра буфера мемо

а зачем изменять сообщения WM_DRAWCLIPBOARD и WM_CHANGECBCHAIN . 1 сообщение при изменение буфера выводит в окно его содержимое. а 2 сообщение удаляет из цепочки окно просмотра... Зачем его менять...не знаю

Автор: MetalFan 18.10.2008, 20:32
Vyadzmak, я так понимаю, глобальный хук на мышу тебе поможет...
а вот если выделили текст с клавы?

Добавлено через 30 секунд
Цитата(Christoph @  18.10.2008,  19:27 Найти цитируемый пост)
1 сообщение при изменение буфера выводит в окно его содержимое

ничего оно никуда не выводит

Автор: Christoph 21.10.2008, 16:27
Проблема эта и мне спать не дает...пробывал ее решить...
нашел компонент TWatch вроде как бы он, может описывать события для всех приложений...ну так вот...пробывал я сделать так:
Код

procedure TForm1.Watch1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var Point: TPoint;
begin
Point.x:=x;
Point.y:=y;
keybd_event(VK_CONTROL,0,0,0);
keybd_event($43,0,0,0);
 sleep(10);
keybd_event($43,0,KEYEVENTF_KEYUP,0);
keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);

Memo1.Text:=clipboard.AsText;

end;



Попробывал и через WM_KEYDOWN, WM_KEYUP ничего не получается smile Ребята помогите  решить эту проблему  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)