Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.09.12;
Скачать: CL | DM;

Вниз

Перехват всех Click-ов по кнопкам   Найти похожие ветки 

 
YaMaximus   (2004-08-20 16:35) [0]

Есть проект, в котором штук 200 форм, на них разные
кнопочки (TRxSpeedButton) в событиях OnClick которых идет определенная обработка.
Как перехватить все эти клики и узнать имя кнопки, по которой
клацнули.
Есть конечно возможность перехвата всех событий через
Application.OnMessage или WndProc, но там я не узнаю имя кнопки.
Может кто-нибудь подскажет идейку.
Заранее благодарен.


 
VMcL ©   (2004-08-20 16:57) [1]

>>YaMaximus  (20.08.04 16:35)

>узнать имя кнопки, по которой
клацнули


Sender: TObject


 
Юрий Зотов ©   (2004-08-20 17:06) [2]

> но там я не узнаю имя кнопки.

Там есть хэндл кнопки, а далее - FindControl с проверкой на is TButton.


 
s999   (2004-08-20 17:11) [3]


> Там есть хэндл кнопки, а далее - FindControl с проверкой
> на is TButton.


Не знаю как TRxSpeedButton, но TSpeedButton от TControl, минуя TWinControl, поэтому не пройдет.


 
YaMaximus   (2004-08-20 17:12) [4]

Да, но мне надо узнать имя кнопки не в OnClick, а в процедуре,
через которую должны проходить все OnClick в программе
(иначе мне прийдется во всех 200 формах переписывать событие OnClick).
Вообще задача стоит в определении в момент
"клика" по кнопке - есть ли у пользователя право на данное действие. Т.е. процедура перехвата определяет имя кнопки, определяет по этому имени права доступа и если таких
прав нету - посылает пользователя. Только как эту процедуру написать?


 
Юрий Зотов ©   (2004-08-20 17:22) [5]

> s999   (20.08.04 17:11) [3]

Пройдет и для графики, если дополнительно вызвать ControlAtPos.

> YaMaximus   (20.08.04 17:12) [4]

Application.OnMessage, а там:
FindControl + GetCursorPos + ScreenToClient + ControlAtPos


 
nikkie ©   (2004-08-20 17:33) [6]

>Как перехватить все эти клики и узнать имя кнопки, по которой клацнули.
написать потомка этой кнопки.


 
s999   (2004-08-20 17:49) [7]


> Пройдет и для графики, если дополнительно вызвать ControlAtPos.


Если так, то да, только тяжеловато немного будет, ControlAtPos - рекурсивная.  


> но мне надо узнать имя кнопки не в OnClick, а в процедуре


Задача стоит ТОЛЬКО для TRxSpeedButton? Если так, то проще всего подправить исходники RX, добавив проверки, и пересобрать.


 
Mim1 ©   (2004-08-20 18:04) [8]


> FindControl + GetCursorPos


Мне кажется что GetCursorPos может не сработать, так как на момент выборки сообщения из очереди и обработки его, курсор может быть совсем в другом месте. Лучше воспользоватья предудущесохраненных положением от mousedown.


 
Mim1 ©   (2004-08-20 18:05) [9]


> Если так, то да, только тяжеловато немного будет, ControlAtPos
> - рекурсивная.  


Думается что пользователь даже не заметит тяжести даже на самом медленном компе. :)


 
YaMaximus   (2004-08-20 18:05) [10]

> s999   (20.08.04 17:11) [7]
Вообщето не только TRxSpeedButton, но и для TMenuItem.OnClick
Но это помоему из области фантастики.
А в чем заключается рекурсивность ControlAtPos?


 
Mim1 ©   (2004-08-20 18:11) [11]


> Вообщето не только TRxSpeedButton, но и для TMenuItem.OnClick
> Но это помоему из области фантастики.


Тоже вполне реально. Перехватвайте сообщение wm_command, ищите в менюхе пункт с нужным wID.


 
YaMaximus   (2004-08-21 10:45) [12]

Огромное спасибо всем за ответы, особенно за ControlAtPos.
Очень помогло!
Ну может еще кто подскажет:
Я делаю так...
procedure TForm1.OnAppMessage(var Msg: TMsg; var Handled: boolean);
var
 sClickCode: string;
 Window: TWinControl;
 Control: TControl;
begin
 if Msg.message = WM_LBUTTONUP then
 begin
   Window := FindVCLWindow(Msg.pt);
   if Window <> nil then
   begin
     Control := Window.ControlAtPos(Window.ScreenToClient(Msg.pt), false);
     if (Control <> nil) and (Control.ClassNameIs("TRxSpeedButton")) then
     begin
       sClickCode := Window.ClassName + "." + Control.Name;
       DoSomething(sClickCode);
     end;
   end;
 end;
 Handled := false;
end;

Вся штука в том, что FindVCLWindow находит виндоу на котором сидит кнопка(TPanel, TToolBar и т.д.), а как бы мне в этой процедуре узнать название самой формы (TForm.Name), на которой сидит эта панель или тулбар или еще чего с этой кнопкой?


 
YaMaximus   (2004-08-25 14:10) [13]

>Тоже вполне реально. Перехватвайте сообщение wm_command, ищите в >менюхе пункт с нужным wID.

Подскажите пожалуста как найти пункт меню в PopupMenu.
При перехвате wm_command убедился , что в wParam действительно сидит wID, но как
по нему найти нажатый пункт меню я не пойму.(Если учесть, что PopupMenu может быть несколько штук).


 
begin...end ©   (2004-08-25 14:17) [14]


> [12] YaMaximus   (21.08.04 10:45)


> узнать название самой формы (TForm.Name), на которой сидит эта панель или тулбар

TControl.Parent ?


 
Mim1 ©   (2004-08-25 15:34) [15]


> Если учесть, что PopupMenu может быть несколько штук


В сообщении так же известен handle окна с которым связано мень. От этого контрола вы можете узнать его меню через getmenu, а по handle меню вы можете вычислить какому vcl компоненту принадлежит это меню (перебором).


 
YaMaximus   (2004-08-25 18:02) [16]

>В сообщении так же известен handle окна с которым связано мень. >От этого контрола вы можете узнать его меню через getmenu, а по >handle меню вы можете вычислить какому vcl компоненту >принадлежит это меню (перебором).

Да, я собственно так и собирался делать.
Во время WM_COMMAND на MainMenu в поле Msg.Hwnd действительно хандл окна(Form1).
Вот только в момент WM_COMMAND на PopupMenu в поле Msg.Hwnd вообще непонятно какой хандл(я проверил хандлы Form1, Application, PopupMenu, PopupMenuItem, dbGrid-a(на котором в моем примере висит Popup), но это не они).
FindControl(Msg.Hwnd) дает nil, чо делать не пойму :о(
Можно конечно использовать:
Window := FindVCLWindow(Msg.pt);
sClickCode := (Window as TRxDbGrid).PopupMenu.FindItem(Msg.wParam, fkCommand).Name;
Но Popup может висеть не только на гриде.


 
Mim1 ©   (2004-08-25 20:07) [17]

При создании менюхи в Delphi 7 она регистрируется в PopupList
 PopupList.Add(Self);
которая если котнролов менюх больше нуля генерит невидимое окошко.
 if Count = 0 then FWindow := Classes.AllocateHWnd(MainWndProc);
После этого все сообщения пришедшие этому окну передаются менюхам.
   WM_COMMAND:
     for I := 0 to Count - 1 do
       if TPopupMenu(Items[I]).DispatchCommand(Message.wParam) then Exit;


Ссылка на обьектик PopupList находит в интервейсной части модуля Menus так что думаю у вас не возникнет труднойстей с определением что к чем относится.


 
YaMaximus   (2004-08-26 10:36) [18]

< Mim1 ©   (25.08.04 20:07) [17]

СУПЕР!!! Спасибо огромное, вы мне очень помогли!
Вообще всем спасибо за советы.


 
SPy ©   (2004-08-26 12:13) [19]

О БОЖЕ МОЙ! Вот накрутили так накрутили!!!
О полезном свойстве Tag читали? Его то и надо менять у кнопки в ее OnClick, а потом проверять. Ну и сделали же из мухи слона %)


 
Палыч   (2004-08-26 12:18) [20]

проект, в котором штук 200 форм???

Да это не проект а фуфло какое-то! Никак чувак решил операционку новую сваять (на Дэлфях:)


 
SPy ©   (2004-08-26 12:20) [21]

ЛОЛ! Удачи ему :)


 
YaMaximus   (2004-08-26 16:05) [22]

> О полезном свойстве Tag читали? Его то и надо менять у кнопки в > ее OnClick, а потом проверять. Ну и сделали же из мухи слона %)

При чем тут Tag? Причем тут OnClick?
Я определяю имя нажатой кнопки в обработчике всех событий
Application.OnMessage. Что мне в каждом OnClick писать процедуру проверки?

>Да это не проект а фуфло какое-то! Никак чувак решил операционку >новую сваять (на Дэлфях:)
Зачем сразу фуфло. Если в проекте 200 форм - значит сразу отстой.
Просто 6 проектов комплекса по управлению производством на предприятии. Даже с учетом наследования форм их количество получается нехилое, их наверное даже больше чем 200.


 
MIm1 ©   (2004-08-26 19:19) [23]


> [22] YaMaximus   (26.08.04 16:05)


Не обращайте внимания, некоторым люди обажают по наличию виснушек на пятке левой ноги судить о вашем интелектуальном уровне.


 
nikkie ©   (2004-08-26 20:57) [24]

ну так объясните мне, почему нельзя было подправить/перекрыть метод Click в TRxSpeedButton??


 
YaMaximus   (2004-08-27 09:59) [25]

>ну так объясните мне, почему нельзя было подправить/перекрыть >метод Click в TRxSpeedButton??

Была и такая идея. Но это надо переопределять методы и TMainMenu
и TPopupMenu, а завтра еще где-нибудь.
А в таком виде(в OnMessage) очень даже централизовано и красиво получилось.

>по наличию виснушек на пятке левой ноги судить о вашем >интелектуальном уровне.
:o))
Красиво сказано.


 
NAlexey ©   (2004-08-27 10:30) [26]

>YaMaximus   (27.08.04 09:59) [25]
Впринципе я могу кнопку нажать пробелом или по Enter как будешь отлавливать?


 
NAlexey ©   (2004-08-27 10:44) [27]

Да, а у меню есть ShortCut-ы как быть с ними?


 
Erik1   (2004-08-27 11:55) [28]

Переопредалять надо однозначно, но если хочется похалявить, то есть такой выход: При зпруске программы пробегаем по всем необходимым объектам(for i := 0 to ComponentCount-1 do) и переопределяем у них событие OnClick, старое соответственно запоминаем вместе с именем объекта(кнопки). При возникновении события делаем, что дуща желает и получаем имя объекта, находим его старый обрабочик и ..... передаем ему управление.
 Помоему все элементарно и работает со всеми контролами, но предупреждаю это для халявщеков.

P.S.
Настоящие герои всегда идут в обход. :)



Страницы: 1 вся ветка

Текущий архив: 2004.09.12;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.119 c
4-1090927960
Sasha73
2004-07-27 15:32
2004.09.12
Как передать данные из одного роцесса в другой ?


1-1093590736
asphix
2004-08-27 11:12
2004.09.12
плавное перемещение


10-1038400454
Павел
2002-11-27 15:34
2004.09.12
просьба помочь


3-1092339929
Сергей Плоткин
2004-08-12 23:45
2004.09.12
Огромный размер БД


1-1093604126
Alex870
2004-08-27 14:55
2004.09.12
HotTrack в TreeView