Текущий архив: 2005.11.13;
Скачать: CL | DM;
Вниз
Как из компонента узнать, что в форме выполнилось событие ShortC Найти похожие ветки
← →
вопрос (2005-03-02 17:59) [0]Господа разработчики, у меня такая проблема: мне надо в моем компоненте распознать, когда будет выполняться стандартный обработчик события ShortCut формы и после него выполнить определенный метод компонента. Как быть???
Заранее спасибо.
← →
Gero © (2005-03-02 18:02) [1]Вызвать метод компонента в обработчике события формы.» Юрий Зотов:» А как же это сделать?
← →
вопрос (2005-03-02 18:12) [2]Нет, это я уже сделал, но надо чтобы он сам определял когда производится событие формы.
← →
GLFox (2005-03-02 18:16) [3]Вообще любой обработчик события можно перекрыть своим. Ну а в нем уже вызывать стандартный (а точнее, тот который был до определения своего)» Юрий Зотов:» А юзер перекроет его своим. Имеет полное право. И компонент перестанет работать.
← →
Gero © (2005-03-02 18:26) [4]
> вопрос (02.03.05 18:12)
Form1.OnEvent := MyComp.Event;
Только зачем?
Компонент должен быть максимально автономным, на то он и компонент.» Юрий Зотов:» А юзер перекроет этот обработчик своим. Имеет полное право. И компонент перестанет работать.
← →
вопрос (2005-03-02 18:40) [5]2 gero
Form1.OnEvent := MyComp.Event;
а если у формы другое имя, то тогда событие не выполнится вообще.//
← →
вопрос (2005-03-02 18:51) [6]ну так как же быть??????????
← →
вопрос (2005-03-02 18:53) [7]я не хочу при создании компонента на форме прописывать метод компонента в обработчик события формы. Надо чтобы он сам определял, когда будет выполняться событие...
← →
Юрий Зотов © (2005-03-02 19:18) [8]> вопрос
Если нужную форму Вы уже определили, то будем считать, что компонент имеет ссылку на нее. Это важно, потому что без этого, конечно, ничего не выйдет. Идем дальше.
Смотрим код TCustomForm - видим, что событие OnShortCut возбуждается в методе IsShortCut. В свою очередь, этот метод вызывается формой при получении сообщения CM_ISSHORTCUT, либо объектом Application при получении сообщения CM_APPKEYDOWN (через Application.IsShortCut). Значит, задача сводится к перехвату сообщений, адресованных форме и Application.
Чтобы перехватить эти сообщения, нужно подменить оконные функции формы и Aplication своими. Поскольку это не системные сообщения, то способ с SetWindowLong отпадает и остаются два пути: через свойство WindowProc и через MakeObjectInstance. Примеры обоих легко найти в VCL.
Но не забудьте, что юзер может положить на форму несколько Ваших компонентов, да еще и поудалять половину из них, да еще и в произвольном порядке. И нужно не допустить чехарды.
Ну а после подмены все просто - в своей оконной функции формы пишем что-то вроде этого:
if не_наше_сообщение then
вызов_прежней_оконной_функции
else
if Form.IsShortCut(TWMKey(Message)) then
begin
Result := 1;
вызов_нашего_метода
end
else
Result := 0;
И аналогично для Application.
← →
jack128 © (2005-03-02 19:35) [9]Очень мне не нравится код где происходят подмены оконных процедур. Как действовать при таком сценарии я не знаю:
1) Кидаем компонент на форму. Он подменяет процедуру ( DefWndProc на CompWndProc)
2) Юзер подменяет окнную процедуру (CompWndProc на UserWndProc)
3) Компонент удаляется с формы и возвращает старую оконную процедуру (DefWndProc)
И теперь пользователь в непонятках, а почему код моей UserWndProc не выполняется?
То есть пользователь должен четко представлять, когда, при каких условиях происходит такая подмена. Это очень нехорошо, потому что логика подмены ожет быть достаточно запутанной.
У кого нить есть предложения как быть в таком случае??
← →
Набережных С. © (2005-03-02 21:23) [10]
> jack128 © (02.03.05 19:35) [9]
> У кого нить есть предложения как быть в таком случае??
У меня есть - не делать так. Использовать хуки, например. В общем, выбирать что-то иное, исходя из ситуации. В данном случае не вполне понятна конечная цель, но CM_APPKEYDOWN хуком точно перехватится.
← →
jack128 © (2005-03-02 23:47) [11]Набережных С. © (02.03.05 21:23) [10]
CM_APPKEYDOWN хуком точно перехватится.
вот как раз CM_* то точно хуком не перехватить ;-)
в хуке плохо, то что это механизм Windows, а не дельфи со всеми вытекающими. В часности он будет работать только на уровне TWinControl, но не для TControl/TGraphicControl
← →
Набережных С. © (2005-03-03 07:06) [12]
> jack128 © (02.03.05 23:47) [11]
Да чего бы CM_APPKEYDOWN не перехватилось, если отсылается через SendMessage? Да и многие CM_* так. Другое дело, что это само по себе все полностью не перекрывает. Ну глубже рыть надо, все решаемо.
> в хуке плохо, то что это механизм Windows, а не дельфи со
> всеми вытекающими.
Имхо, это плюс.
> В часности он будет работать только на уровне TWinControl,
> но не для TControl/TGraphicControl
Ну так я и говорю - исходя из ситуации.
← →
Erik1 © (2005-03-03 12:49) [13]Я думаю, что у автора неправельности с логикой. Надо создать своего наследника от формы, в котором перехватить нужное событие(В нашем случии message). Далее перебрать все компоненты на форме которые могут принять такое событие. Или сделать механизм подписки на событие. Главное, что задача решается в два этапа.
Страницы: 1 вся ветка
Текущий архив: 2005.11.13;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.044 c