Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.09.12;
Скачать: [xml.tar.bz2];

Вниз

Перехват всех 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.029 c
6-1089282292
sapsi
2004-07-08 14:24
2004.09.12
Определение количества подключений на сервере сокетов


1-1093853845
BillyJeans
2004-08-30 12:17
2004.09.12
I/O Error 183.


1-1093518032
HydraMarat
2004-08-26 15:00
2004.09.12
Вставка строки в PChar


3-1092375802
REP
2004-08-13 09:43
2004.09.12
Не удается записать в TBlobField произвольный файл


1-1093460903
Joker
2004-08-25 23:08
2004.09.12
помогите написать шифровальщик





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский