![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
Есть инспектор объектов, который работает во время исполнения программы.
Как узнать, какой компонент выбрал пользователь, чтобы скормить этому инспектору объектов выбранный компонент. Компонентов много, у некоторых уже есть свои события OnClick. Каждому назначать отдельно - не годится. Какой был бы наиболее простой и правильный метод определения активного компонента? Это сообщение отредактировал(а) Akella - 3.10.2010, 22:41 |
|||
|
||||
okkonst |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 33 Регистрация: 5.9.2010 Где: Воронеж Репутация: 1 Всего: 1 |
Смотри на события TWinControl.OnEnter, TWinControl.OnExit ("активизация" и "деактивизация" контрола, всем можно один обработчик задать), свойство TCustomForm.ActiveControl
|
|||
|
||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
Ты не понял вопроса.
Добавлено через 1 минуту и 17 секунд Есть на форме 100 компонентов. Как узнать, какой из них выбрал пользователь в момент выбора? Мне что, каждому компоненту прописывать код в событии, например, OnClick? Добавлено через 2 минуты и 10 секунд У некоторых компонентов уже есть код в свойстве, у некоторых появится в будущем. |
|||
|
||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
Всё, решил проблему. Я использую компоненты Cindy для изменения размеров и положения компонентов. Там нашёл свойство cyResizer1.LastMouseDownControl
![]() |
|||
|
||||
okkonst |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 33 Регистрация: 5.9.2010 Где: Воронеж Репутация: 1 Всего: 1 |
Во-первых, не onClick, а OnEnter (почитай-таки справку!). Во-вторых, им ВСЕМ можно установить ОДИН обработчик (сообщающий сендера твоему инспектору). Причем, программно. 2 строчки кода...
А если я, такой поганец, не мышой а TABом? |
||||
|
|||||
Akella |
|
||||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
А я возьму и заменю, да? Добавлено через 1 минуту и 21 секунду Tab не работает. |
||||
|
|||||
okkonst |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 33 Регистрация: 5.9.2010 Где: Воронеж Репутация: 1 Всего: 1 |
А в чем проблема сохранить имеющийся обработчик, скажем, в массив, заменить своим, из которого вызвать старый? Массив структур, одно поле - контрол, второе - метод.. Но, в принципе, если проблема решена - че говорить...
:-\ не люблю я слишком мышастые интерфейсы, с ними медленно работать... Добавлено через 1 минуту и 26 секунд Потом. ты не говорил про код в OnEnter, только в OnClick, который тут не нужен |
|||
|
||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
||||
|
||||
okkonst |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 33 Регистрация: 5.9.2010 Где: Воронеж Репутация: 1 Всего: 1 |
![]() Но, кстати, если серьезно (и не в тему ![]() |
|||
|
||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
||||
|
||||
cat512 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 438 Регистрация: 20.3.2007 Репутация: 7 Всего: 15 |
Если, проблема ещё актуальна, то можно использовать: Screen.ActiveControl, или Screen.ActiveForm.ActiveControl
Добавлено через 1 минуту и 34 секунды и не надо никаких OnEnter, OnClick |
|||
|
||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
Можно сказать, что актуальна.
А в каком событии? Нужно же как-то централизовано... Узнать активный элемент не сложно. А вот узнать где щёлкнул пользователь или что он выбрал с помощью Tab сложновато. Ну для меня по крайне мере. Хотя, используя KeyPreview можно отловить нажатие на клавишу без проблем через OnKeyDown. Жаль что нет такого события для мышки. |
|||
|
||||
cat512 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 438 Регистрация: 20.3.2007 Репутация: 7 Всего: 15 |
Application.OnMessage - цепляешь код типа:
Код не проверял, возможно на множествах компилятор будет ругаться. Единственное, посмотри какого типа OnMessage, и создай процедуру соотв. типа. По идее должно работать. |
|||
|
||||
cat512 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 438 Регистрация: 20.3.2007 Репутация: 7 Всего: 15 |
Как говорится, хорошие мысли приходят позже, лучше код получения ActiveControl,
повесить на OnIdle. Тогда не надо тебе обрабатывать сообщения. Просто пишешь
Это сообщение отредактировал(а) cat512 - 4.10.2010, 12:23 |
|||
|
||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
||||
|
||||
okkonst |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 33 Регистрация: 5.9.2010 Где: Воронеж Репутация: 1 Всего: 1 |
Кстати, ответ сильно зависит от того, все ли компоненты являются окнами? То есть, все ли они - потомки TWinControl?
Добавлено через 7 минут и 17 секунд
Мнэ-э... Работать-то оно, конечно, будет. Но могут быть спецэффекты. Если уж хочется 100%, универсально и непробиваемо - вешай локальный хук ![]() |
|||
|
||||
cat512 |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 438 Регистрация: 20.3.2007 Репутация: 7 Всего: 15 |
Ну по условию задачи, человеку надо выбирать(устанавливая фокус) элементы управления! Компоненты он выбрать не сможет, по причине не визуальности. На TControl - фокус установить невозможно, только кликнуть. Остаётся TWinControl ![]() На OnIdle должно быть всё в шоколаде, не должно быть спецэффектов |
||||
|
|||||
okkonst |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 33 Регистрация: 5.9.2010 Где: Воронеж Репутация: 1 Всего: 1 |
Что-то я про "устанавливая фокус" не нашел в исходном тексте. Более того, по тексту можно предположить (не обязательно), что изготавливается конструктор формы. А там могут быть не только винконтролы. Те же лейблы, к примеру... Другое дело, что для них не сработает OnEnter так же ![]()
А если параллельные потоки? OCX-компоненты? Потом, ты дашь гарантию, что после клика на компоненте OnIdle наступит достаточно быстро, чтобы юзер не успел ткнуть еще куда-нибудь? Логика программы может быть весьма замысловата... Я бы все-таки пошел по пути установки в рантайме своих обработчиков OnClick (для не-винконтролов) и OnEnter для остальных с вызовом ранее установленных. При условии полной автоматизации этого процесса, он станет совершенно прозрачным, синхронным и не связанным с расчетами координат (при перехвате мыши), не будет зависеть от способа активизации компонента... Еще мысли про недостаток OnIdle. У нас есть кнопка. У нее в OnClick сидит ее обработчик. Юзер кидает в нее тапком и что происходит: - клик - OnClick - Выполнение обработчика - Выход из обработчика - OnIdle То есть, мы поймем, что юзер "выбрал" кнопку только после того, как она уже сработает. А это может произойти не скоро... Это сообщение отредактировал(а) okkonst - 4.10.2010, 16:47 |
||||
|
|||||
cat512 |
|
||||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 438 Регистрация: 20.3.2007 Репутация: 7 Всего: 15 |
![]() C тобой интересно общаться, видно человек думающий, но скажем, не обращавший внимание на тонкости VCL. По порядку: 1 "устанавливая фокус" я вывел методом исключения(см. выше) Просто скорее всего akellka опечатался, оговорив в условии задачки TComponent. Ну это не столь важно. 2
Н ураз уж сказал А, то говори и Б. Разворачивай ответ в контексте параллельных потоков и ОСХ. Покажи, каким образом они могут нам навредить, а я покажу как обойти возникшую проблемму
Даю, даже не я, а разработчики VCL из Borland. Смотри как работает ActionUpdate, и когда наступает OnIdle. И вообще, нам абсолютно не важно как быстро наступит OnIdle. В кон. счёте нам без разницы, сколько кликов сделает пользователь, главное что бы он выбрал, какой нибудь ел. управл., а на OnIdle мы его сдадим кому нужно.
с этим согласен, но мне кажется, ты немного всё усложняешь
В этом наши подходы с тобой как раз отличаются. Ты размазываешь всю логику по обработчикам сообщения, у меня логика обработки находится в централизованном (водном месте) обработчике, что ведёт к простоте и лёгкости в сопровождении. Кстати, а где ты увидел расчёт координат, перехват мыши в варианте предложенном мной???
И что с того, что она работает/отработала?Зачем искать кошку, там где её нет?Вот когда ТС столкнётся с проблемой производительности, вот тогда и будет пытатся оптимизировать. А что сейчас говорить на абстрактные темы? Можно такого напридумывать, а в реальности окажется, задачка гроша ломанного не стоит. Это сообщение отредактировал(а) cat512 - 4.10.2010, 23:27 |
||||||||||
|
|||||||||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
Есть в onIdle "установить" какой-то код, то не будет ли это сильно сказываться на работе программы и вообще на производительности?
Например, на главную форму приложения кидаем компоненту и там прописываем:
Получается, что этот код будет выполняться почти постоянно? |
|||
|
||||
cat512 |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 438 Регистрация: 20.3.2007 Репутация: 7 Всего: 15 |
OnIdle - выполняется когда приложение ПРОСТАИВАЕТ! Другими словами когда у приложения пустая очередь сообщений (это значит что приложение ничего не делает, просто висит), то начинает выполняться OnIdle и соответственно код который там находится. Это нюанс VCL, например в других приложениях, написанных с использованием GetMessage, OnIdle, в режиме пользователя вообще отсутсвует, он работает только в режиме ядра, причём поток всё равно крутит spinLock (цикл), а в этом spinLocke тупо считает количество процессорных тактов. Как только в очереди появится хоть одно сообщение, VCL переводит контекст управления из OnIdle в конкретный обработчик сообшения. Т. е. другими словами, у OnIdle - приоритет выполнения ниже чем у любого обработчика сообщений.
Теперь по сути:
Ну и хай себе выполняется постоянно. Если тебе это не нравится, можешь поставить флажок (я закоментил код с флажком в предыдущих постах) и сбрасывать его когда контрол обновился Даже лучше не флажок, а так:
![]() Это сообщение отредактировал(а) cat512 - 5.10.2010, 15:21 |
||||
|
|||||
Frees |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2233 Регистрация: 2.12.2005 Где: Екатеринбург Репутация: 9 Всего: 54 |
иногда бывало что из за кода в Идле проц загружался на 100 % лучше код в Идле пытаться минимизировать
-------------------- Кольцов Виктор Владимирович |
|||
|
||||
cat512 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 438 Регистрация: 20.3.2007 Репутация: 7 Всего: 15 |
Пожалуй соглашусь с Frees, что в любом случае оптимизация лучше, отсутствие таковой.
![]() Единственное хочу отметить один момент: код в OnIdle будет грузить процессор - если там цикл (что есть неправильно!), или длительное выполнение системных вызовов (например работа с файловой системой, графикой ...etc), которые требуют переключения контекста между режимом пользователя и режимом ядра. |
|||
|
||||
Akella |
|
||||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
В моём случае Screen.ActiveControl всегда будет cxResizer, т.к. я использую компонент TcxResizer (Cindy Components) для возможности перемещения компонентов по форме и изменения их размеров.
Возможно я откажусь от этих компонентов в пользу других. Пока не знаю. Добавлено через 6 минут и 18 секунд На данный момент у мну там сделано: вызываю код начала/окончания редактирования:
Я не знаю, но думаю, что достаточное тяжёлое, т.к. в cxVerticalGrid грузится полностью вся инфа о выбранном объекте, а на сколько я знаю, то работа с RTTI очень медленная. Добавлено через 9 минут и 28 секунд А кто-нибудь работал с компонентами Greatis? |
||||
|
|||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
И ещё проблема в том, что инспектор ни в какую не хочет видеть изменения, которые я сделал с компонентом на форме. Например я переместил компонент, а инспектор не поменял свойства left и top.
Получается, что то, что предложил Frees if fmRTTIInspector.cxRTTIInspector1.InspectedObject <> Screen.ActiveControl Наоборот нужно выполнять принудительно, чтобы инспектор "перечитывал" постоянно свойства инспектируемой компоненты. |
|||
|
||||
Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 36 Всего: 329 |
У TcxResizer есть событие OnClick, которое срабатывает при клике на любой компоненте, которая принадлежит родительской панели. Уже легче
![]()
|
|||
|
||||
cat512 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 438 Регистрация: 20.3.2007 Репутация: 7 Всего: 15 |
Чёт сразу не подумал, а теперь вспомнил, что у Screen-а есть войство OnActiveControlChange, которое случается при смене фокуса на контроле, можно с ним поиграться
|
|||
|
||||
okkonst |
|
||||||||||||||||||||||||||
![]() Новичок Профиль Группа: Участник Сообщений: 33 Регистрация: 5.9.2010 Где: Воронеж Репутация: 1 Всего: 1 |
Например, активный поток может блокироваться. Тем или иным образом.
Смотрел. И не раз. OnIdle срабатывает, когда пустеет очередь сообщений. Причем, если очередь разгребалась через HandleMessage (а не через, скажем, самодельный цикл с ProcessMessages) Проблема в том, что это весьма малопредсказуемая штука. Я могу придумать кучу сценариев, когда OnIdle облажается. Смотри. Тачка загружена "по самые помидоры". Кванты нашей задаче отдаются нечасто. Юзеру надоело ждать, пока все "прочихается", он жмет мышой на ТЕдит, топчет ("в буфер") клавиатуру и жмет "ентер", с тем, что когда все прочихается, едит активируется, данные из буфера клавиатуры в него вобьются и нажмется "ок". При этом, OnIdle сработает ПОСЛЕ обработки OK. А возможны и менее пессимистичные сценарии. Мне в твоем подходе не нравится то, что ты используешь событие, логика которого предназначена для другого. Я достаточно далек от сравнения "забивать гвозди микроскопом", но не слишком ![]()
Поправочка: ПО ОБРАБОТЧИКУ. Одному. А то, что вызываться он будет из кучи мест - проблемы не составляет. Ну, плюс ЕЩЕ одна подпрограмма - установщик.
не в твоем.
Во-первых, тут проблема не производительности. В том смысле. что она будет при ЛЮБОЙ скорострельности компа - OnIdle сработает ПОСЛЕ обработчика кнопки. Во-вторых, ты предлагаешь думать об этом, когда заказчик позвонит, и начнет в терминах "я там нажала, а оно выскочило" объяснять проблему? Добавлено через 2 минуты
А-а!!! Позор на мою седую голову!!! (посыпает пеплом беломора) Ведь сам же юзал... ![]() |
||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||
cat512 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 438 Регистрация: 20.3.2007 Репутация: 7 Всего: 15 |
![]() |
|||
|
||||
cat512 |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 438 Регистрация: 20.3.2007 Репутация: 7 Всего: 15 |
2okkonst
если под ",блокироваться" - понимается DeadLock, то используем механизмы синхронизации, если нет, то будет ждать своего кванта. ![]()
Скажи плиз, почему ты решил что контрол должен здаваться инспектору объектов, до того момента, как он(контрол) начнёт обработку сообщения, или скажем ранее??? Ведь этот момент, завмсит от проблемы предметной области. Если например, этот механизм используется с чисто информативной целью( например для того что-бы тупо отобразить информацию о объекте, на фрэйме детализации), то использование OnIdle очень даже подходит. Для других вариантов использования, возможны разные варианты реализации. Могу предположить, что для каких-то OnIdle не самый лучший вариант. Но ТС, спросил "как"! Он ничего не детализировал! Поэтому метафора "забивать гвозди микроскопом", для варианта (тупо отобразить информацию о объекте, на фрэйме детализации). я бы сказал, не верный. ![]()
Вот как раз что проблемы не вызывает - это Пару строчек кода в обработчике OnIdle, а тебе как минимум надо написать 2 подпрограммы, плюс постоянно беспокоиться о безопасности (не запорол ли кто в runtime, логику установки обработчиков), или скажем какой-нить компонент, что то неявно делает с обработчиками)
см. выше, зависит от вар. использования Это сообщение отредактировал(а) cat512 - 6.10.2010, 15:05 |
||||||||
|
|||||||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |