Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/48: Рейтинг темы: голосов - 48, средняя оценка - 4.54
Модератор
3490 / 2613 / 741
Регистрация: 19.09.2012
Сообщений: 7,974
1

Перехват сообщений

13.11.2012, 21:13. Показов 9186. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть такая конструкция:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
unit Unit1;
..............
 
type // Ïåðåõâàò âñòàâêè
  TEdit = class(StdCtrls.TEdit)
private
  procedure WMPaste(var Msg:TMessage); message WM_PASTE;
end;
 
type
  TForm1 = class(TForm)
.............
позволяющая перехватывать вставку в Едиты.
Мне надо сделать, чтобы это работало еще для некоторых компонентов (или для всей программы).
Знаю, что можно прописать тоже самое для других компонентов, но это как-то громоздко. Может есть другое решение?
Перенос процедуры в TForm1 ничего не дал.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.11.2012, 21:13
Ответы с готовыми решениями:

Перехват сообщений в RichEdit
Доброго времени!! Нашел на просторах интернета код перехвата сообщения при вставке в TEdit. type...

Перехват сообщений от ICQ
Доброго времени суток! Возможно ли перехватывать сообщения исходящии и входящии от аси? Пробовал...

Перехват сообщений от клавиатуры!
Всем Здрасьте! Есть программа, которая висит в трее, необходимо, чтобы она перехватывала все что...

перехват ошибки
как перехватить оошибку? try IdSMTP1.Connect(); sleep(5000); IdSMTP1.Send(IdMessage1); ...

13
2664 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
13.11.2012, 21:33 2
Цитата Сообщение от gorfil Посмотреть сообщение
Может есть другое решение?
Специально для этого существующее и вполне документированное событие Applicаtion.OnMessage спасет ОРД и упасет его от изобретения велосипеда.
0
Модератор
3490 / 2613 / 741
Регистрация: 19.09.2012
Сообщений: 7,974
13.11.2012, 22:28  [ТС] 3
Цитата Сообщение от mss Посмотреть сообщение
Специально для этого существующее и вполне документированное событие Applicаtion.OnMessage спасет ОРД и упасет его от изобретения велосипеда.
Пытаюсь разобраться... А как определить к какому компоненту относится событие (например, событие "вставка" куда? в Едит1, Мемо2 и т.п.)?
0
2664 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
13.11.2012, 22:31 4
Цитата Сообщение от gorfil Посмотреть сообщение
А как определить
С пом. ф-ции FindControl()
0
Модератор
3490 / 2613 / 741
Регистрация: 19.09.2012
Сообщений: 7,974
13.11.2012, 22:40  [ТС] 5
Почему-то не работает:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
unit Unit1;
 
.....
 
type
  TForm1 = class(TForm)
.....
 
  public
    { Public declarations }
    procedure AppMessage(var Msg: TMsg; var Handled: Boolean);
 
.....
 
procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
  if Msg.message = WM_PASTE then
    begin
      ShowMessage('Вставка!');
    end;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := AppMessage; // Перехватчик событий
end;
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32835 / 21172 / 8148
Регистрация: 22.10.2011
Сообщений: 36,431
Записей в блоге: 8
13.11.2012, 22:53 6
WM_PASTE подобным образом не ловится. Система шлет его не в общую очередь сообщений приложения, а непосредственно в WndProc тому контролу, в который осуществляется вставка. Поэтому перехватить его можно не из Application.OnMessage, а сабклассингом нужного контрола (переопределением его WndProc) или глобальным хуком.
0
Модератор
3490 / 2613 / 741
Регистрация: 19.09.2012
Сообщений: 7,974
13.11.2012, 22:54  [ТС] 7
Вставка делается, а событие не перехватывается.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32835 / 21172 / 8148
Регистрация: 22.10.2011
Сообщений: 36,431
Записей в блоге: 8
13.11.2012, 22:56 8
Не там перехватываешь. Ты переопределил WndProc своих Edit-ов?
0
Модератор
3490 / 2613 / 741
Регистрация: 19.09.2012
Сообщений: 7,974
13.11.2012, 22:59  [ТС] 9
Цитата Сообщение от UI Посмотреть сообщение
WM_PASTE подобным образом не ловится. Система шлет его не в общую очередь сообщений приложения, а непосредственно в WndProc тому контролу, в который осуществляется вставка. Поэтому перехватить его можно не из Application.OnMessage, а сабклассингом нужного контрола (переопределением его WndProc) или глобальным хуком.
сабклассингом - это, если я правильно понял, как у меня вначате описано?:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
unit Unit1;
..............
 
type // Перехват вставки
  TEdit = class(StdCtrls.TEdit)
private
  procedure WMPaste(var Msg:TMessage); message WM_PASTE;
end;
 
type
  TForm1 = class(TForm)
.............
т.е. для каждого класса надо свой делать?
глобальным хуком - можно поподробнее или пример какой, плиз?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32835 / 21172 / 8148
Регистрация: 22.10.2011
Сообщений: 36,431
Записей в блоге: 8
14.11.2012, 01:25 10
Цитата Сообщение от gorfil Посмотреть сообщение
это, если я правильно понял, как у меня вначате описано?
Можно - так как у тебя, а можно - вот так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  TEdit = class(StdCtrls.TEdit)
  protected
    procedure WndProc( var Message: TMessage ); override;
  end;
 
// ...
 
procedure TEdit.WndProc(var Message: TMessage);
begin
   inherited;
   if Message.Msg = WM_PASTE then
   begin
      ShowMessage('Paste!!!');
   end;
end;
Да, придется делать для каждого класса (можно подумать их так уж много, тех, кому Windows посылает WM_PASTE...)

С хуками пока не заморачивайся.
1
Модератор
3490 / 2613 / 741
Регистрация: 19.09.2012
Сообщений: 7,974
14.11.2012, 09:36  [ТС] 11
Цитата Сообщение от UI Посмотреть сообщение
Да, придется делать для каждого класса (можно подумать их так уж много, тех, кому Windows посылает WM_PASTE...)

С хуками пока не заморачивайся.
Понятно, спасибо.
Тогда еще такой вопрос: можно как-то в процедурах TEdit'а вызвать процедуры TForm1 (они нужны для обработки вставки), а то Дельфи ругается:[This form of method call only allowed for class methods]?
0
2664 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
14.11.2012, 09:57 12
1. Объявить и реализовать в любом своем объекте метод MyMsgHandler с прототипом TWndMethod, в котором фильтровать и обрабатывать нужным образом WM_PASTE.
2. Получить указатель на оконную ф-цию вызовом MyWndFunc := MakeObjectInstance(MyMsgHandler)
3. Перечислить все винконтролы приложения, отфильтровать нужные.
4. Для каждого отфильтрованного винконтрола заменить вызовом SetWindowLong его оконную функцию на MyWndFunc.
1
Модератор
3490 / 2613 / 741
Регистрация: 19.09.2012
Сообщений: 7,974
14.11.2012, 20:26  [ТС] 13
Цитата Сообщение от mss Посмотреть сообщение
1. Объявить и реализовать в любом своем объекте метод MyMsgHandler с прототипом TWndMethod, в котором фильтровать и обрабатывать нужным образом WM_PASTE.
2. Получить указатель на оконную ф-цию вызовом MyWndFunc := MakeObjectInstance(MyMsgHandler)
3. Перечислить все винконтролы приложения, отфильтровать нужные.
4. Для каждого отфильтрованного винконтрола заменить вызовом SetWindowLong его оконную функцию на MyWndFunc.
, но я попробую разобраться. Кстати, может пример похожий есть? Он бы мне здорово помог.
0
Модератор
3490 / 2613 / 741
Регистрация: 19.09.2012
Сообщений: 7,974
17.11.2012, 11:25  [ТС] 14
Цитата Сообщение от mss Посмотреть сообщение
1. Объявить и реализовать в любом своем объекте метод MyMsgHandler с прототипом TWndMethod, в котором фильтровать и обрабатывать нужным образом WM_PASTE.
2. Получить указатель на оконную ф-цию вызовом MyWndFunc := MakeObjectInstance(MyMsgHandler)
3. Перечислить все винконтролы приложения, отфильтровать нужные.
4. Для каждого отфильтрованного винконтрола заменить вызовом SetWindowLong его оконную функцию на MyWndFunc.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
procedure TForm1.MsgHandler(var Msg: TMessage);
begin
  if Msg.Msg = WM_PASTE then
    ShowMessage('Paste!!!')
  else
    Msg.Result := CallWindowProc(OldProc, Edit1.Handle, Msg.Msg, Msg.wParam, Msg.LParam);
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  OldProc:=pointer(GetWindowLong(Edit1.Handle, GWL_WndProc));
  WndFunc := MakeObjectInstance(MsgHandler);
  SetWindowLong(Edit1.Handle, GWL_WndProc, integer(WndFunc));
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
  SetWindowLong(Edit1.Handle, GWL_WndProc, integer(OldProc));
  FreeObjectInstance(WndFunc);
end;
Получается, что это тоже самое, что и:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
TEdit = class(StdCtrls.TEdit)
  protected
    procedure WndProc( var Message: TMessage ); override;
  end;
 
// ...
 
procedure TEdit.WndProc(var Message: TMessage);
begin
   if Message.Msg = WM_PASTE then
      ShowMessage('Paste!!!')
   else inherited;
end;
только для каждого компонента прописывается отдельно.
Впрочем это можно использовать, если надо переиначить конкретный компонент, а не все компоненты класса.
0
17.11.2012, 11:25
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.11.2012, 11:25
Помогаю со студенческими работами здесь

Перехват обращений
Здравствуйте. Возникла такая проблемма - у меня существует программа, которая должна по внесенной...

Перехват пакетов
Подскажите пожалуйста, как в делфи можно работать с пакетами в браузере?Сколько не искал - ничего...

Перехват копирования
Привет ребята, как реализовать перехват копирования ?? например я с флешки копирую на рабочий стол...

перехват ошибок
Здравствуйте! У меня есть Stringgrid и кнопка. Если какая-то ячейка Грида пустая, мы должны...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru