Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Wm_past на edit как с этим работать... Wm_past 
:(
    Опции темы
Grol
Дата 2.5.2005, 00:19 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Привет всем! Вот я пишу:

Код

Private
procedure wmpaste(var Msg:TWMPaste); Message wm_paste;
...
procedure Tform1.WmPaste(var Msg:TWMPaste);
begin
  if Msg.Msg=Wm_Paste then
  Form1.edit1.Text:='Вставка!!!';
  inherited;
end;


Я хочу, чтобы по нажатию на форме ctrl+V у меня в edit вводилась "вставка", как по коду видно. При этом edit неактивный, чтоб на нем небыло фокуса. То есть должно чисто отлавливаться сообщение wm_paste. Помогите мне пожалуйста разобраться и поподробнее. Буду очень преочень благодарен всем кто поможет мнне!!!
P.S.: Ведь все когда-то так начинали с нуля изучать Delphi.

Это сообщение отредактировал(а) Alex - 2.5.2005, 00:24
  Вверх
dvamaster
Дата 2.5.2005, 06:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 559
Регистрация: 30.6.2004
Где: Россия : Курган

Репутация: 3
Всего: 10



WM_PASTE работает только на контролах у которых есть поле ввода.

Отлавливай простое нажатие Ctrl+V


--------------------
Хорошую информацию трудно добыть. Сделать с ней что-нибудь - еще труднее. /L. Skywalker/

Что же я сделал не так? /Король Лир/

Я делаю это для твоего же блага! /Любой родитель и палач/

PKUNZIP.ZIP /неизвестный/
PM MAIL WWW ICQ   Вверх
Guest
Дата 2.5.2005, 14:17 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Вот как раз мне и нужно не нажатие клавиши отловить, так как это я знаю, а само сообщение wm_paste которое будет посылаться от нажатия. То есть типа хука. Только я не знаю как это сделать. Так как в Delphi я недавно начал программировать. Подскажите пожалуйста...буду очень благодарен.
  Вверх
Guest
Дата 2.5.2005, 22:09 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Мастера В Delphi помогите мне, Ламеру в программировании, на вас вся надежда... Я бы сам, но я все smile перепробывал у меня ничего не получается. Подскажите мне буду очень вам благодарен за оказанную помощь!!! smile smile smile
  Вверх
Zero
Дата 2.5.2005, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2169
Регистрация: 23.10.2004
Где: Россия, г. Рязань

Репутация: 8
Всего: 24



Цитата(Grol @ 2.5.2005, 00:19)
Я хочу, чтобы по нажатию на форме ctrl+V у меня в edit вводилась "вставка"
Всмысле на форме, а она же не может получать фокус ввода.
Но если тебе нужно просто, по нажатию на другом элементе, чтобы в нужный тебе edit, в частности в первый вводилась вставка, то делай это на событие нажатия клавиши (OnKeyDown, или OnKeyPress, или OnKeyUp).
Вчастности пример: прось на форму 2 edit'a и на событие OnKeyPress 2-ого edit'a напиши:
Код

procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);
begin
  if key=#22 then edit1.Text:='Вставка';
end; 

PM MAIL ICQ   Вверх
Yanis
Дата 2.5.2005, 22:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 72
Всего: 111



ПО моему, в этом случае надо отлавливать не WM_PASTE, а комбинацию клавишь. Вот мой вариант:
Код

procedure TForm1.WMKEYDOWN(var Message: TWMKEYDOWN);
begin
  Inherited;
  If ((GetKeyState(VK_CONTROL) and 128) = 128) and (((GetKeyState(Ord('V')) and 128) = 128)or((GetKeyState(Ord('v')) and 128) = 128)) then
    MessageBox(Handle, PChar('Combination of keys "Ctrl + V" is pressed'), PChar('Key pressed...'), MB_ICONINFORMATION);
end;



--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
Grol
Дата 2.5.2005, 23:21 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Мастера спасибо за то что уже что-то подсказали, но вот дело еще в следующем. Я ненапрасно код привел в начале всего обсуждения. Мне нужно, чтобы соообщение отлаваливалось от нажатия а не само нажатие, т.е. вместо ctrl+V может быть и shift+insert, и также правая кнопка мыши и в опциях вставить. А как тогда действовать. Буду ждать ответа, если кто захочет помочь. Спасибо за все. "Век буду должен."
  Вверх
Poseidon
Дата 3.5.2005, 00:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Grol, как же ты не поймешь! Сообщения от Виндовс, в твоем случае, получает окно (или по-просту форма), а форма не имеет поля ввода. Следовательно форма не обрабатывает сообщение WM_PASTE, она его просто игнорирует!
Цитата(dvamaster @ 2.5.2005, 06:40)
WM_PASTE работает только на контролах у которых есть поле ввода.


Так что сделать что-то
Цитата(Guest @ 2.5.2005, 14:17)
типа хука
, для этого сообщения не удасться smile (если я не прав, то поправте).



--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Rouse_
Дата 3.5.2005, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 469
Регистрация: 23.4.2005

Репутация: 5
Всего: 29



Может вот это подойдет?

Код

unit Unit2;

interface

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

type
  TForm2 = class(TForm)
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
  private
    OldWindowProc: TWndMethod;
    procedure NewEditWindowProc(var Message: TMessage);
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
begin
  // Запоминаем старую оконную процедуру
  OldWindowProc := Edit1.WindowProc;
  // Заменяем ее новой
  Edit1.WindowProc := NewEditWindowProc;
end;

procedure TForm2.NewEditWindowProc(var Message: TMessage);
begin
  // перехватываем сообщение о вставке
  if Message.Msg = WM_PASTE then
    Edit1.Text := 'Вставка!!!'
  else
    OldWindowProc(Message);
end;

end.

Добавлено @ 11:37
Цитата(Poseidon @ 3.5.2005, 01:57)
Сообщения от Виндовс, в твоем случае, получает окно (или по-просту форма), а форма не имеет поля ввода.

Не может она его получать.

Цитата
An application sends a WM_PASTE message to an edit control or combo box to copy the current content of the clipboard to the edit control at the current caret position. Data is inserted only if the clipboard contains data in CF_TEXT format.

lResult = SendMessage(      // returns LRESULT in lResult   
  (HWND) hWndControl,      // handle to destination control   
  (UINT) WM_PASTE,      // message ID   
  (WPARAM) wParam,      // = (WPARAM) () wParam; 
  (LPARAM) lParam      // = (LPARAM) () lParam; ); 

таким образом форма не является получателем...

Это сообщение отредактировал(а) Rouse_ - 3.5.2005, 11:33


--------------------
 Vae Victis
(Горе побежденным (лат.))
Демо с открытым кодом: http://rouse.drkb.ru 
PM MAIL WWW ICQ   Вверх
Girder
Дата 3.5.2005, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй 2
***


Профиль
Группа: Участник Клуба
Сообщений: 1993
Регистрация: 12.5.2004

Репутация: 31
Всего: 155



smile
Код
//...
type
 TOP_H = packed record
  Push:Byte;
  Address:DWord;
  Ret:Byte;
 end;

var
  Form1: TForm1;
  WPM:DWord;
  fPaste:Boolean=false;
  fKeyPaste:Boolean=false;
  OC,KS:Pointer;
  OP:DWord;
  OP_H1,Reserve1,OP_H2,Reserve2:TOP_H;
  mKS:TKeyboardState;

implementation

{$R *.dfm}

function CheckPasteKey():boolean;
begin
 Result:=false;
 GetKeyboardState(mKS);
 if (((mKS[17] and mKS[86])and $80)=$80)or(((mKS[16] and mKS[45])and $80)=$80) then
  begin
   mKS[45]:=0;
   mKS[86]:=0;
   SetKeyboardState(mKS);
   Result:=true;
  end;
end;

procedure SaveEdit();
begin
 Form1.Edit1.Text:='Вставка!!!';
end;

procedure Open_Clipboard;stdcall;
begin
 asm
  pushad
 end;
 WriteProcessMemory(OP,OC,@Reserve1,SizeOf(Reserve1),WPM);
 asm
  popad
  mov eax,[esp+4]
  push eax
  mov eax,OC
  call eax
  pushad
 end;
 WriteProcessMemory(OP,OC,@OP_H1,SizeOf(OP_H1),WPM);
 SaveEdit;
 asm
  popad
  ret +4
 end;
end;

procedure Get_KeyState;stdcall;
begin
 asm
  pushad
 end;
 WriteProcessMemory(OP,KS,@Reserve2,SizeOf(Reserve2),WPM);
 asm
  popad
  mov eax,[esp+4]
  push eax
  mov eax,KS
  call eax
  pushad
 end;
 WriteProcessMemory(OP,KS,@OP_H2,SizeOf(OP_H2),WPM);
 if CheckPasteKey then SaveEdit;
 asm
  popad
  ret +4
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var Dll:DWord;
begin
 FillChar(mKS,SizeOf(mKS),#0);
 SetKeyboardState(mKS);
 DLL:=LoadLibrary('user32.dll');
 if DLL<>0 then
  begin
   OC:=GetProcAddress(DLL,'OpenClipboard');
   KS:=GetProcAddress(DLL,'GetKeyState');
   if (OC<>nil)and(KS<>nil) then
    begin
     OP:=OpenProcess(PROCESS_ALL_ACCESS,false,GetCurrentProcessID);
     if OP<>0 then
      begin
       OP_H1.Push:=$68;
       OP_H1.Address:=DWord(@Open_Clipboard);
       OP_H1.Ret:=$C3;
       ReadProcessMemory(OP,OC,@Reserve1,SizeOf(Reserve1),WPM);
       WriteProcessMemory(OP,OC,@OP_H1,SizeOf(OP_H1),WPM);
       OP_H2.Push:=$68;
       OP_H2.Address:=DWord(@Get_KeyState);
       OP_H2.Ret:=$C3;
       ReadProcessMemory(OP,KS,@Reserve2,SizeOf(Reserve2),WPM);
       WriteProcessMemory(OP,KS,@OP_H2,SizeOf(OP_H2),WPM);
      end;
    end;
   FreeLibrary(Dll);
  end;
end;

//...


Это сообщение отредактировал(а) Girder - 3.5.2005, 16:02


--------------------
Как слышим, так и пишим.
Истина где-то там...
PM   Вверх
Rouse_
Дата 3.5.2005, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 469
Регистрация: 23.4.2005

Репутация: 5
Всего: 29



Girder, ну нифига себе smile
Это ж из пушки по воробьям smile)))))))


--------------------
 Vae Victis
(Горе побежденным (лат.))
Демо с открытым кодом: http://rouse.drkb.ru 
PM MAIL WWW ICQ   Вверх
Girder
Дата 3.5.2005, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй 2
***


Профиль
Группа: Участник Клуба
Сообщений: 1993
Регистрация: 12.5.2004

Репутация: 31
Всего: 155



Цитата(Rouse_ @ 3.5.2005, 17:10)
Girder, ну нифига себе  smile
Это ж из пушки по воробьям smile)))))))
Зато... не важно сколько контролов на форме... сколько форм в проекте... где фокус... smile

PS: Да и вообще... ты забыл!!! об всяких там "диалогах" (OpenDialog, SaveDialog...), MessageBox-ах и т.д. и т.п. smile - а данному коду на все енто... по барабану smile

Это сообщение отредактировал(а) Girder - 3.5.2005, 16:35


--------------------
Как слышим, так и пишим.
Истина где-то там...
PM   Вверх
Rouse_
Дата 3.5.2005, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 469
Регистрация: 23.4.2005

Репутация: 5
Всего: 29



Цитата(Girder @ 3.5.2005, 17:17)
Да и вообще... ты забыл!!! об всяких там "диалогах" (OpenDialog, SaveDialog...), MessageBox-ах и т.д. и т.п.  - а данному коду на все енто... по барабану 

Угу, только проще застрелиться чем отлавливать откуда вставка пришла и делать инвариантный выбор на несколько контролов smile
Лучше уж наследника от едита написать и не париться (благо это целиком соответствует вопросу без выхода за рамки) smile


--------------------
 Vae Victis
(Горе побежденным (лат.))
Демо с открытым кодом: http://rouse.drkb.ru 
PM MAIL WWW ICQ   Вверх
Girder
Дата 4.5.2005, 00:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй 2
***


Профиль
Группа: Участник Клуба
Сообщений: 1993
Регистрация: 12.5.2004

Репутация: 31
Всего: 155



Цитата(Rouse_ @ 3.5.2005, 23:26)
Угу, только проще застрелиться чем отлавливать откуда вставка пришла и делать инвариантный выбор на несколько контролов smile
Уже застрелился... smile

Код
type
 TOP_H = packed record
  Push:Byte;
  Address:DWord;
  Ret:Byte;
 end;

var
  Form1: TForm1;
  WPM:DWord;
  fPaste:Boolean=false;
  fKeyPaste:Boolean=false;
  OC,KS:Pointer;
  OP:DWord;
  OP_H1,Reserve1,OP_H2,Reserve2:TOP_H;
  mKS:TKeyboardState;
  Win:HWND;

implementation

{$R *.dfm}

function CheckPasteKey():boolean;
begin
 Result:=false;
 GetKeyboardState(mKS);
 if (((mKS[17] and mKS[86])and $80)=$80)or(((mKS[16] and mKS[45])and $80)=$80) then
  begin
   mKS[45]:=0;
   mKS[86]:=0;
   SetKeyboardState(mKS);
   Result:=true;
  end;
end;

procedure SaveEdit();
var CN:array [0..1024] of char;
begin
 GetClassName(Win,CN,1024);
 Form1.Edit1.Text:={'Вставка!!!'}CN;
end;

procedure Open_Clipboard;stdcall;
begin
 asm
  pushad
 end;
 WriteProcessMemory(OP,OC,@Reserve1,SizeOf(Reserve1),WPM);
 asm
  popad
  mov eax,[esp+4]
  mov Win,eax
  push eax
  mov eax,OC
  call eax
  pushad
 end;
 WriteProcessMemory(OP,OC,@OP_H1,SizeOf(OP_H1),WPM);
 SaveEdit;
 asm
  popad
  ret +4
 end;
end;

procedure Get_KeyState;stdcall;
begin
 asm
  pushad
 end;
 WriteProcessMemory(OP,KS,@Reserve2,SizeOf(Reserve2),WPM);
 asm
  popad
  mov eax,[esp+4]
  push eax
  mov eax,KS
  call eax
  pushad
 end;
 WriteProcessMemory(OP,KS,@OP_H2,SizeOf(OP_H2),WPM);
 Win:=GetFocus;
 if CheckPasteKey then SaveEdit;
 asm
  popad
  ret +4
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var Dll:DWord;
begin
 FillChar(mKS,SizeOf(mKS),#0);
 SetKeyboardState(mKS);
 DLL:=LoadLibrary('user32.dll');
 if DLL<>0 then
  begin
   OC:=GetProcAddress(DLL,'OpenClipboard');
   KS:=GetProcAddress(DLL,'GetKeyState');
   if (OC<>nil)and(KS<>nil) then
    begin
     OP:=OpenProcess(PROCESS_ALL_ACCESS,false,GetCurrentProcessID);
     if OP<>0 then
      begin
       OP_H1.Push:=$68;
       OP_H1.Address:=DWord(@Open_Clipboard);
       OP_H1.Ret:=$C3;
       ReadProcessMemory(OP,OC,@Reserve1,SizeOf(Reserve1),WPM);
       WriteProcessMemory(OP,OC,@OP_H1,SizeOf(OP_H1),WPM);
       OP_H2.Push:=$68;
       OP_H2.Address:=DWord(@Get_KeyState);
       OP_H2.Ret:=$C3;
       ReadProcessMemory(OP,KS,@Reserve2,SizeOf(Reserve2),WPM);
       WriteProcessMemory(OP,KS,@OP_H2,SizeOf(OP_H2),WPM);
      end;
    end;
   FreeLibrary(Dll);
  end;
end;


PS: Посчитай... сколько строчек изменилось(добавилось)... что бы реализовать твою идею... smile (Посмотри что выводится в Edit1)

PS2: Жду еще идей... smile "А если завтра война?! А я везу макороны!" smile

Это сообщение отредактировал(а) Girder - 4.5.2005, 02:11


--------------------
Как слышим, так и пишим.
Истина где-то там...
PM   Вверх
Grol
Дата 4.5.2005, 00:43 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Спасибо за помощь...Все получилось!!! smile smile Обязательно укажу вас и ваш форум в своей программе!!! Еще раз большое спасибо.
  Вверх
Grol
Дата 7.5.2005, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 159
Регистрация: 5.5.2005
Где: Россия

Репутация: нет
Всего: нет



Здравствуйте!!! Мастера помогите, а в частности Rouse, пожалуйста!!! Вы мне давали код. Я его немного переделал. Мне нужно перехватить вставку из буфера обмена данных в ячейки Stringgrid. Вот есть код, но только действует для edit:

...
Код

procedure ControlOnEnter(Sender: TObject);
procedure ControlOnExit(Sender: TObject);
private
   OldWindowProcessor: TWndMethod;
   procedure NewWindowProc(var Message: TMessage);
 public
   { Public declarations }
 end;

procedure TForm1.NewWindowProc(var Message: TMessage);
begin
 if Message.Msg = WM_PASTE
 then 
 begin
 //здесь выполняются инструкции после перехвата
 end
 else OldWindowProcessor(Message);
end;

procedure TForm1.ControlOnEnter(Sender: TObject);
begin
if not (Sender is TEdit) and
   not (Sender is TStringGrid)
then Exit;
OldWindowProcessor:=TControl(Sender).WindowProc;
TControl(Sender).WindowProc := NewWindowProc;
end;

procedure TForm1.ControlOnExit(Sender: TObject);
begin
if not (Sender is TEdit) and
   not (Sender is TStringGrid)
then Exit;
TControl(Sender).WindowProc := OldWindowProcessor;
end; 


Для Stringgrid и edit в процедурах onenter и onexit соответствено ставим процедуры ControlOnEnter и ControlOnExit.

Спасибо заранее за ответ!!! Помогите ламеру!!!!
Цитата
Ламер - он и в Африке ламер...


Это сообщение отредактировал(а) Girder - 8.5.2005, 07:46
--------------------
Живи так, как будто тебе предстоит умереть завтра...Учись так, как будто тебе предстоит жить вечно.........
PM MAIL ICQ   Вверх
Grol
Дата 8.5.2005, 00:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 159
Регистрация: 5.5.2005
Где: Россия

Репутация: нет
Всего: нет



Help!!! На помощь...помогите мне пожалуйста уважаемые мастера Delphi!!! Что только я уже не перепробовал!!! smile smile
--------------------
Живи так, как будто тебе предстоит умереть завтра...Учись так, как будто тебе предстоит жить вечно.........
PM MAIL ICQ   Вверх
Alex
Дата 8.5.2005, 08:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 80
Всего: 162



Я конечно не проверял и особо не смотрел код, но что-то мне подсказывает, что нужно написать вот так:
Код

procedure ControlOnEnter(Sender: TObject);
procedure ControlOnExit(Sender: TObject);
private
   OldWindowProcessor: TWndMethod;
   procedure NewWindowProc(var Message: TMessage);
 public
   { Public declarations }
 end;

procedure TForm1.NewWindowProc(var Message: TMessage);
begin
 if Message.Msg = WM_PASTE
 then 
 begin
 //здесь выполняются инструкции после перехвата
 end
 else OldWindowProcessor(Message);
end;

procedure TForm1.ControlOnEnter(Sender: TObject);
begin
if  (Sender is TEdit) or (Sender is TStringGrid) then begin
  OldWindowProcessor:=TControl(Sender).WindowProc;
  TControl(Sender).WindowProc := NewWindowProc;
end;
end;

procedure TForm1.ControlOnExit(Sender: TObject);
begin
if  (Sender is TEdit) or (Sender is TStringGrid) then
  TControl(Sender).WindowProc := OldWindowProcessor;
end;



--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
Girder
Дата 8.5.2005, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй 2
***


Профиль
Группа: Участник Клуба
Сообщений: 1993
Регистрация: 12.5.2004

Репутация: 31
Всего: 155



Grol а с чего ты взял... что обязательно должно быть сообщение WM_Paste(или какое нить еще smile ) при вставке(или наоборот) из буфера.

Вот компонент... для перехвата некоторых функций при работе с буфером обмена... для своего приложения(ClipboardHook.pas) - после инсталяции появится в Samples:
Код
unit ClipboardHook;

interface

uses
  Windows, SysUtils, Classes, ExtCtrls;

type
 TFOnOpenClipboard = procedure(Sender:TObject; hWndNewOwner:HWND; var opContinue:Boolean) of object;
 TFOnGetClipboardData = procedure(Sender:TObject; hWndNewOwner:HWND; uFormat:DWord; var opContinue:Boolean) of object;
 TFOnSetClipboardData = procedure(Sender:TObject; hWndNewOwner:HWND; uFormat:DWord; hMem:THandle; var opContinue:Boolean) of object;

type
  TClipboardHook = class(TComponent)
  private
    { Private declarations }
    FOnOpenClipboard:TFOnOpenClipboard;
    FOnGetClipboardData:TFOnGetClipboardData;
    FOnSetClipboardData:TFOnSetClipboardData;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    //------------------------------------------------
  published
    { Published declarations }
    property OnOpenClipboard:TFOnOpenClipboard read FOnOpenClipboard write FOnOpenClipboard;
    property OnGetClipboardData:TFOnGetClipboardData read FOnGetClipboardData write FOnGetClipboardData;
    property OnSetClipboardData:TFOnSetClipboardData read FOnSetClipboardData write FOnSetClipboardData;
  end;

procedure Register;

implementation

type
 TcOpen=function(hWndNewOwner:HWND):Bool; stdcall;
 TgcData=function(uFormat:DWord):THandle; stdcall;
 TscData=function(uFormat:DWord; hMem:Thandle):THandle; stdcall;
 TOP_H = packed record
  Push:Byte;
  Address:DWord;
  Ret:Byte;
 end; 

var OC_Addr,GCD_Addr,SCD_Addr:Pointer;
    OP:DWord;
    cOpen,rcOpen,gcData,rgcData,scData,rscData:TOP_H;
    WPM:DWord;
    sComponent:TObject;

{***************************Start:TClipboardHook***************************}
function Open_Clipboard(hWndNewOwner:HWND):Bool; stdcall;
var c:Boolean;
begin
 c:=true;
 if Assigned(TClipboardHook(sComponent).FOnOpenClipboard) then
  TClipboardHook(sComponent).FOnOpenClipboard(sComponent,hWndNewOwner,c);
 if c then
  begin
   WriteProcessMemory(OP,OC_Addr,@rcOpen,SizeOf(rcOpen),WPM);
   Result:=TcOpen(OC_Addr)(hWndNewOwner);
   WriteProcessMemory(OP,OC_Addr,@cOpen,SizeOf(cOpen),WPM);
  end else Result:=false;
end;

function Get_ClipboardData(uFormat:DWord):THandle; stdcall;
var c:Boolean;
    Win:DWord;
begin         
 c:=true;
 Win:=GetOpenClipboardWindow();
 if (Win<>0)and(Assigned(TClipboardHook(sComponent).FOnGetClipboardData)) then
  TClipboardHook(sComponent).FOnGetClipboardData(sComponent,Win,uFormat,c);
 if c then
  begin
   WriteProcessMemory(OP,GCD_Addr,@rgcData,SizeOf(rgcData),WPM);
   Result:=TgcData(GCD_Addr)(uFormat);
   WriteProcessMemory(OP,GCD_Addr,@gcData,SizeOf(gcData),WPM);
  end else Result:=0;
end;

function Set_ClipboardData(uFormat:DWord; hMem:THandle):THandle; stdcall;
var c:Boolean;
    Win:DWord;
begin         
 c:=true;
 Win:=GetOpenClipboardWindow();
 if (Win<>0)and(Assigned(TClipboardHook(sComponent).FOnSetClipboardData)) then
  TClipboardHook(sComponent).FOnSetClipboardData(sComponent,Win,uFormat,hMem,c);
 if c then
  begin
   WriteProcessMemory(OP,SCD_Addr,@rscData,SizeOf(rscData),WPM);
   Result:=TscData(SCD_Addr)(uFormat,hMem);
   WriteProcessMemory(OP,SCD_Addr,@scData,SizeOf(scData),WPM);
  end else Result:=0;
end;
{****************************End:TClipboardHook****************************}

{##############################################################################}
constructor TClipboardHook.Create(AOwner:TComponent);
var Dll:DWord;
begin
 inherited Create(Aowner);
 if (csDesigning in ComponentState) then exit;
 sComponent:=Self;
 DLL:=LoadLibrary('user32.dll');
 if DLL<>0 then
  begin
   OC_Addr:=GetProcAddress(DLL,'OpenClipboard');
   GCD_Addr:=GetProcAddress(DLL,'GetClipboardData');
   SCD_Addr:=GetProcAddress(DLL,'SetClipboardData');
   if (OC_Addr<>nil)or(GCD_Addr<>nil)or(SCD_Addr<>nil) then
    begin      
     OP:=OpenProcess(PROCESS_ALL_ACCESS,false,GetCurrentProcessID);
     if OP<>0 then
      begin
       if OC_Addr<>nil then
        begin
         cOpen.Push:=$68;
         cOpen.Address:=DWord(@Open_Clipboard);
         cOpen.Ret:=$C3;
         ReadProcessMemory(OP,OC_Addr,@rcOpen,SizeOf(rcOpen),WPM);
         WriteProcessMemory(OP,OC_Addr,@cOpen,SizeOf(cOpen),WPM);
        end;
       if GCD_Addr<>nil then
        begin
         gcData.Push:=$68;
         gcData.Address:=DWord(@Get_ClipboardData);
         gcData.Ret:=$C3;
         ReadProcessMemory(OP,GCD_Addr,@rgcData,SizeOf(rgcData),WPM);
         WriteProcessMemory(OP,GCD_Addr,@gcData,SizeOf(gcData),WPM);
        end;
       if SCD_Addr<>nil then
        begin
         scData.Push:=$68;
         scData.Address:=DWord(@Set_ClipboardData);
         scData.Ret:=$C3;
         ReadProcessMemory(OP,SCD_Addr,@rscData,SizeOf(rscData),WPM);
         WriteProcessMemory(OP,SCD_Addr,@scData,SizeOf(scData),WPM);
        end;
      end;
    end;
   FreeLibrary(Dll);
  end;
end;

destructor TClipboardHook.destroy;
begin
 if (OC_Addr<>nil) then WriteProcessMemory(OP,OC_Addr,@rcOpen,SizeOf(rcOpen),WPM);
 if OP<>0 then CloseHandle(OP);
 inherited destroy;
end;

procedure Register;
begin
  RegisterComponents('Samples', [TClipboardHook]);
end;
{##############################################################################}

end.


Вот пример его использования:
-"Запрет" работы с буфером для всех TEdit;
-"Запрет" работы с буфером при вставке для TStringGrid;
-"Запрет" работы с буфером при копировании(вырезке) для TMemo;
Код
procedure TForm1.ClipboardHook1OpenClipboard(Sender: TObject;
  hWndNewOwner: HWND; var opContinue: Boolean);
var ClassName:array [0..1024] of char;
    i:integer;
begin
 i:=GetClassName(hWndNewOwner,ClassName,1024);
 if i<>0 then
  begin
   if AnsiCompareText('TEdit',Copy(ClassName,0,i))=0 then
    opContinue:=false;
   Edit1.Text:='OpenClipboard: '+Copy(ClassName,1,i);
  end;
end;
              
procedure TForm1.ClipboardHook1GetClipboardData(Sender: TObject;
  hWndNewOwner: HWND; uFormat: Cardinal; var opContinue: Boolean);
var ClassName:array [0..1024] of char;
    i:integer;
begin
 i:=GetClassName(GetParent(hWndNewOwner),ClassName,1024);
 if i<>0 then
  begin
   if AnsiCompareText('TStringGrid',Copy(ClassName,1,i))=0 then
    opContinue:=false;
   i:=GetClassName(hWndNewOwner,ClassName,1024); 
   Edit1.Text:='WP_Paste: '+Copy(ClassName,1,i);
  end;
end;

procedure TForm1.ClipboardHook1SetClipboardData(Sender: TObject;
  hWndNewOwner: HWND; uFormat, hMem: Cardinal; var opContinue: Boolean);
var ClassName:array [0..1024] of char;
    i:integer;
begin
 i:=GetClassName(hWndNewOwner,ClassName,1024);
 if i<>0 then
  begin
   if AnsiCompareText('TMemo',Copy(ClassName,0,i))=0 then
    opContinue:=false;
   Edit1.Text:='WP_Copy(Cut): '+Copy(ClassName,1,i);
  end;
end;


PS: По большому счету... данный код(компонент) тоже не панацея на все 100% smile

Удачи.


--------------------
Как слышим, так и пишим.
Истина где-то там...
PM   Вверх
Grol
Дата 8.5.2005, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 159
Регистрация: 5.5.2005
Где: Россия

Репутация: нет
Всего: нет



Girder - я только начинающий, можно так сказать. А ты пишешь такой код, что он мне вообще непонятен. Мне как бы хотелось немного попроще, но все равно спасибо тебе за то, что помогаешь!!! Также всем спасибо!!! Girder, а если вот в моем коде, что там можно сделать??? Еще раз спасибо всем!!!

Это сообщение отредактировал(а) Girder - 8.5.2005, 17:32
--------------------
Живи так, как будто тебе предстоит умереть завтра...Учись так, как будто тебе предстоит жить вечно.........
PM MAIL ICQ   Вверх
Grol
Дата 9.5.2005, 02:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 159
Регистрация: 5.5.2005
Где: Россия

Репутация: нет
Всего: нет



Girder - я посмотрел Ваш компонент, он действительно действует, спасибо за это! Очень Вам благодарен!!! Только есть одно, но как мне в вашем компоненте строковой переменной присвоить содержание буфера обмена.

Например: (это ваш код)
Код

procedure TForm1.ClipboardHook1GetClipboardData(Sender: TObject;
  hWndNewOwner: HWND; uFormat: Cardinal; var opContinue: Boolean);
var ClassName:array [0..1024] of char;
    i:integer;
    
  //объявляю строковую переменную
   str:string;

begin
 i:=GetClassName(GetParent(hWndNewOwner),ClassName,1024);
 if i<>0 then
  begin
   if AnsiCompareText('TStringGrid',Copy(ClassName,1,i))=0 then
    opContinue:=false;
   i:=GetClassName(hWndNewOwner,ClassName,1024); 
   Edit1.Text:='WP_Paste: '+Copy(ClassName,1,i);
   
  //после этого мне нужно, чтоб я содержания буфера вставил в str переменную
  str:=clipboard...//дальше что то у меня не получается

  end;
end;

Помогите мне пожалуйста еще раз и я уж точно от Вас отстану. :-))) Ламера Ведь так и действуют, что узнают всю информацию от других, я в том числе...Спасибо заранее!!!

Это сообщение отредактировал(а) Girder - 9.5.2005, 09:42
--------------------
Живи так, как будто тебе предстоит умереть завтра...Учись так, как будто тебе предстоит жить вечно.........
PM MAIL ICQ   Вверх
Girder
Дата 9.5.2005, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй 2
***


Профиль
Группа: Участник Клуба
Сообщений: 1993
Регистрация: 12.5.2004

Репутация: 31
Всего: 155



Ну в данном случаи... более простой вариант не много изменить код компонента smile

Вот тебе новый вариант ClipboardHook.pas:
Код
unit ClipboardHook;

interface

uses
  Windows, SysUtils, Classes, ExtCtrls;

type
 TFOnOpenClipboard = procedure(Sender:TObject; hWndNewOwner:HWND; var opContinue:Boolean) of object;
 TFOnGetClipboardData = procedure(Sender:TObject; hWndNewOwner:HWND; uFormat:DWord; hClipboardObject: THandle; var opContinue:Boolean) of object;
 TFOnSetClipboardData = procedure(Sender:TObject; hWndNewOwner:HWND; uFormat:DWord; hMem:THandle; var opContinue:Boolean) of object;

type
  TClipboardHook = class(TComponent)
  private
    { Private declarations }
    FOnOpenClipboard:TFOnOpenClipboard;
    FOnGetClipboardData:TFOnGetClipboardData;
    FOnSetClipboardData:TFOnSetClipboardData;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    //------------------------------------------------
  published
    { Published declarations }
    property OnOpenClipboard:TFOnOpenClipboard read FOnOpenClipboard write FOnOpenClipboard;
    property OnGetClipboardData:TFOnGetClipboardData read FOnGetClipboardData write FOnGetClipboardData;
    property OnSetClipboardData:TFOnSetClipboardData read FOnSetClipboardData write FOnSetClipboardData;
  end;

procedure Register;

implementation

type
 TcOpen=function(hWndNewOwner:HWND):Bool; stdcall;
 TgcData=function(uFormat:DWord):THandle; stdcall;
 TscData=function(uFormat:DWord; hMem:Thandle):THandle; stdcall;
 TOP_H = packed record
  Push:Byte;
  Address:DWord;
  Ret:Byte;
 end; 

var OC_Addr,GCD_Addr,SCD_Addr:Pointer;
    OP:DWord;
    cOpen,rcOpen,gcData,rgcData,scData,rscData:TOP_H;
    WPM:DWord;
    sComponent:TObject;

{***************************Start:TClipboardHook***************************}
function Open_Clipboard(hWndNewOwner:HWND):Bool; stdcall;
var c:Boolean;
begin
 c:=true;
 if Assigned(TClipboardHook(sComponent).FOnOpenClipboard) then
  TClipboardHook(sComponent).FOnOpenClipboard(sComponent,hWndNewOwner,c);
 if c then
  begin
   WriteProcessMemory(OP,OC_Addr,@rcOpen,SizeOf(rcOpen),WPM);
   Result:=TcOpen(OC_Addr)(hWndNewOwner);
   WriteProcessMemory(OP,OC_Addr,@cOpen,SizeOf(cOpen),WPM);
  end else Result:=false;
end;

function Get_ClipboardData(uFormat:DWord):THandle; stdcall;
var c:Boolean;
    Win:DWord;
begin         
 c:=true;
 Win:=GetOpenClipboardWindow();
 WriteProcessMemory(OP,GCD_Addr,@rgcData,SizeOf(rgcData),WPM);
 Result:=TgcData(GCD_Addr)(uFormat);
 WriteProcessMemory(OP,GCD_Addr,@gcData,SizeOf(gcData),WPM);
 if (Win<>0)and(Assigned(TClipboardHook(sComponent).FOnGetClipboardData)) then
  TClipboardHook(sComponent).FOnGetClipboardData(sComponent,Win,uFormat,Result,c);
 if c=false then Result:=0;
end;

function Set_ClipboardData(uFormat:DWord; hMem:THandle):THandle; stdcall;
var c:Boolean;
    Win:DWord;
begin         
 c:=true;
 Win:=GetOpenClipboardWindow();
 if (Win<>0)and(Assigned(TClipboardHook(sComponent).FOnSetClipboardData)) then
  TClipboardHook(sComponent).FOnSetClipboardData(sComponent,Win,uFormat,hMem,c);
 if c then
  begin
   WriteProcessMemory(OP,SCD_Addr,@rscData,SizeOf(rscData),WPM);
   Result:=TscData(SCD_Addr)(uFormat,hMem);
   WriteProcessMemory(OP,SCD_Addr,@scData,SizeOf(scData),WPM);
  end else Result:=0;
end;
{****************************End:TClipboardHook****************************}

{##############################################################################}
constructor TClipboardHook.Create(AOwner:TComponent);
var Dll:DWord;
begin
 inherited Create(Aowner);
 if (csDesigning in ComponentState) then exit;
 sComponent:=Self;
 DLL:=LoadLibrary('user32.dll');
 if DLL<>0 then
  begin
   OC_Addr:=GetProcAddress(DLL,'OpenClipboard');
   GCD_Addr:=GetProcAddress(DLL,'GetClipboardData');
   SCD_Addr:=GetProcAddress(DLL,'SetClipboardData');
   if (OC_Addr<>nil)or(GCD_Addr<>nil)or(SCD_Addr<>nil) then
    begin      
     OP:=OpenProcess(PROCESS_ALL_ACCESS,false,GetCurrentProcessID);
     if OP<>0 then
      begin
       if OC_Addr<>nil then
        begin
         cOpen.Push:=$68;
         cOpen.Address:=DWord(@Open_Clipboard);
         cOpen.Ret:=$C3;
         ReadProcessMemory(OP,OC_Addr,@rcOpen,SizeOf(rcOpen),WPM);
         WriteProcessMemory(OP,OC_Addr,@cOpen,SizeOf(cOpen),WPM);
        end;
       if GCD_Addr<>nil then
        begin
         gcData.Push:=$68;
         gcData.Address:=DWord(@Get_ClipboardData);
         gcData.Ret:=$C3;
         ReadProcessMemory(OP,GCD_Addr,@rgcData,SizeOf(rgcData),WPM);
         WriteProcessMemory(OP,GCD_Addr,@gcData,SizeOf(gcData),WPM);
        end;
       if SCD_Addr<>nil then
        begin
         scData.Push:=$68;
         scData.Address:=DWord(@Set_ClipboardData);
         scData.Ret:=$C3;
         ReadProcessMemory(OP,SCD_Addr,@rscData,SizeOf(rscData),WPM);
         WriteProcessMemory(OP,SCD_Addr,@scData,SizeOf(scData),WPM);
        end;
      end;
    end;
   FreeLibrary(Dll);
  end;
end;

destructor TClipboardHook.destroy;
begin
 if (OC_Addr<>nil) then WriteProcessMemory(OP,OC_Addr,@rcOpen,SizeOf(rcOpen),WPM);
 if OP<>0 then CloseHandle(OP);
 inherited destroy;
end;

procedure Register;
begin
  RegisterComponents('Samples', [TClipboardHook]);
end;
{##############################################################################}

end.


Вот тогда... как рещается твоя проблемма(если речь идет о запросе текста... из буфера smile ):
Код
procedure TForm1.ClipboardHook1GetClipboardData(Sender: TObject;
  hWndNewOwner: HWND; uFormat, hClipboardObject: Cardinal;
  var opContinue: Boolean);
var ClassName:array [0..1024] of char;
    i:DWord;
    Str,t:string;
    pStr:Pointer;
begin
 i:=GetClassName(GetParent(hWndNewOwner),ClassName,1024);
 if i<>0 then
  begin
   if AnsiCompareText('TStringGrid',Copy(ClassName,1,i))=0 then
    begin
     pStr:=GlobalLock(hClipboardObject);
     if pStr<>nil then
      begin
       case uFormat of
        CF_TEXT: Str:=PChar(pStr);
        CF_UNICODETEXT: Str:=PWideChar(pStr);
        CF_OEMTEXT: begin
                     i:=0;
                     while PChar(DWord(pStr)+i)^<>#0 do inc(i);
                     if i>0 then
                      begin
                       SetLength(t,i);
                       OemToChar(PChar(pStr),PChar(t));
                       Str:=t;
                       SetLength(t,0);
                      end;
                    end;
       else
        Str:='';
       end;
       GlobalUnlock(hClipboardObject);
      end;
     if Str<>'' then Caption:=Str; //Сбрасываем текст из буфера в Caption
    // opContinue:=false; //Запрет на вставку
    end;
   i:=GetClassName(hWndNewOwner,ClassName,1024);
   Edit1.Text:='WP_Paste: '+Copy(ClassName,1,i);
  end;
end;


PS: Пользуйся тегами CODE - а то твои посты тяжело читать smile

Удачи.


--------------------
Как слышим, так и пишим.
Истина где-то там...
PM   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1572 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.