Форум: "Основная";
Текущий архив: 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