|
|
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
Есть контроль ocx который является контейнером для других ocx -ов Есть коллекция обьектов с withEvents 2 класса один сама коллекция другой обработка обьекта на каждый ocx есть свой Event как можно в контейнере (ocx) получить перехватить Event на каждый ocx и обработать его ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2006, 16:32 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
Если я правильно понял формулировку, то надо в проект, в котором содержится класс-коллекция, добавить private класс-оболочку для "другого ocx"-а. Этот класс содержит член-ссылку на хозяина-коллекцию и WithEvents член-ссылку на "другой ocx". По приходу события "другого ocx"-а класс-оболочка вызывает Friend-метод коллекции, который и делает RaiseEvent. Во внутренней же коллекции хранятся ссылки на экземпляры класса-оболочки, но реализация public-методов коллекции это скрывает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2006, 17:57 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
А как это реализовать для получения Event в родительском ocx который контейнер как получить член-ссылку на хозяина-коллекцию ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2006, 18:26 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
miki1, уж больно косноязычное описание проблемы. Поэтому приведу пример для ситуации, как я её понял. Пусть есть некий класс, назовём его CMyItem, который умеет генерировать события. Он может лежать в другом .ocx-файле, быть написан другим человеком на другом языке и т. п. Например, код у этого класса такой: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Пусть есть класс, назовём его CMyItems, есть методы Count, Add, Remove, Item, реализующие функциональность коллекции элементов типа CMyItem. Это может быть отдельный класс, а может быть часть класса-контейнера. Код CMyItems: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. Тогда код класс-оболочка для CMyItem, назовём его CMyItemNotifier, выглядит так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2006, 19:28 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
Бенедикт Спасибо похоже на то что нужно только не понятно как использовать класс CMyItemNotifier использовать WithEvnts с ним не получается а насчёт косноязычного описания проблемы я как Моника Ливински языком не владею ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.08.2006, 11:50 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
miki1, CMyItemNotifier не генерирует события (нет в нём Public Event и RaiseEvent) - WithEvents в описании экземпляра не нужен. Это сугубо посреднический private класс, снаружи проекта его и не видно. Его единственное предназначение - быть задействованным в CMyItems как класс, экземпляры которого будут складываться во внутреннюю коллекцию класса-контейнера. Если же CMyItem и CMyItems лежат в одной библиотеке (проекте), то функциональность CMyItemNotifier можно засунуть в CMyItem и отказаться от CMyItemNotifier. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.08.2006, 13:04 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
Бенедикт Спасибо я просто не то скопировал Вопрос другой если можно если я ставлю этот контейнер на форму и добавляю контроли во внутрь то события на контроли внутри срабатывают в основой форме но если добавление контейнера динамическое через Controls.Add то событие на контроли внутри не срабатывает в основной форме все RaiseEvent срабатывает по всем этапам ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.08.2006, 14:33 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
miki1, по динамическому добавлению ActiveX-ов на форму есть обязательная к прочтению статья: Q190670. How To Dynamically Add Controls to a Form with Visual Basic 6.0 . Поскольку в данном случае ActiveX свой, вопросы лицензирования можно игнорировать. Если количество ActiveX-ов (контейнеров) заранее неизвестно, то придётся городить такой же огород с коллекцией, но на более высоком уровне - в роли CMyItem будет выступать уже контейнер. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.08.2006, 16:24 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
Бенедикт огромное пионерское спасибо Перезарегистрировал ocx и заработало Хотя на событие каждого контроля нужно писать отдельный код нет динамики но всё равно спасибо тема закрыта ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.08.2006, 16:46 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
Update: взглянув трезвым послепраздничным взглядом, вижу, что есть ошибка при работе с памятью. Надо добавить в CMyItems метод Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2007, 17:34 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
..., либо циклом явно очищать CMyItems от элементов (вместо вызова Release). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2007, 17:39 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
Про работу без циклических ссылок я писал тут. Жаль нет времени написать хорошие примеры для повседневной работы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2007, 17:55 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
Worobjoff, коллекция не управляет явно временем жизни экземпляра объекта (неявно управляет уничтожением - если ссылка на экземпляр, хранящаяся в ней, оказалась последней). Это означает что а) экземпляры могут (иногда, по логике, должны; пример: те же контролы, нарисованные в design-time, поэтому создаваемые автоматически) быть созданы/уничтожены извне коллекции; б) возможна реализация отношения "многие ко многим" между экземплярами и коллекциями. Пример в приведённой ссылке - не коллекция в этом (общепринятом? Microsoft-овском?) смысле, а некая фабрика классов, реализующая отношение "многие к одному". И, как мне показалось, Parent можно было бы реализовать прямее, через friend-свойство. Не всё ли равно, кому накручивать счётчик ссылок - экземпляру MyCollection, или её внутреннему свойству (m_Notifier; другой кандидат - mCol)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2007, 20:24 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
Да. я знаю про этот механизм подсчета ссылок. А мой пример - лишь одну цель преследует: Чтобы после уничтожения ссылки на коллекцию, не пришлось принудительно гасить ссылки на входящие в нее объекты. Сделал "Коллекция=Нафиг" - и все содержимое "нафингавалось" автоматически. Кстати, контролы, которые надо анлоадить, вполне можно "гасить" (т.е. анлоадить) в событии Class_Terminate. И не придется специально уничтожать их. (на всякий случай уточню: анлоадить - не есть уничтожать ссылку). В общем-то это - как раз и предусмотрено в COM. Т.е. чтобы этим пользовались (автоматическим сбором памяти без применения специальных методов). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2007, 20:38 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
Worobjoff, да я не спорю, хороший пример к теории When to Use Events or Call-Backs for Notifications . (И трюки с ObjPtr/CopyMemory удовольствия действительно не доставляют). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2007, 03:02 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
странное завершение старого топика. 2 Бенедикт вероятно претензий к вашему первоначальному варианту кода не было, по причине времени жизни контейнера равному времени жизни приложения. недостаток предложенного Вами исправления в том, что оно вносит дополнительные условия на "правильное" использование контейнера. автор(И трюки с ObjPtr/CopyMemory удовольствия действительно не доставляют). В условиях данной конкретной задачи, когда по ее условиям: - контейнер существует в отдельном компоненте, - введенный Вами посредник CMyItemNotifier должен реализовываться приватным классом - время жизни CMyItemNotifier не может быть больше времени жизни содержащего его контейнера слабая ссылка абсолютно оправдана, не привносит опасностей использования и полностью развязывает ситуацию, исключая дополнительные соглашения по использованию контейнера. вот код исправленного CMyItemNotifier, не вызывающего проблем с использованием контейнера. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. Какие в таком варианте для данной задачи (контейнер, живущий в собственном компоненте с приватным посредником) могут возникать неудовольствия, кроме сплошных удовольствий? 2 Worobjoff Вы малек бредите в обсуждаемом вопросе. авторЖаль нет времени ... Попробуйте его найти. Вас же люди читают и даже разрешение на "использование" спрашивают. распространение событий - один из механизмов вызова процедур. Сам по себе он не решает и не может решать проблем циклических ссылок. Я вполне к Вам с уважением. Надеюсь, совет "разобраться с вопросом" тоже будет встречен вполне доброжелательно. (с выражением лица) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2007, 04:19 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
Victosha, спасибо за код, но именно такого и хотелось бы избежать. Вопрос callbacks vs events и создания weak reference старый, активно обсуждался, например, в VBPJ (Visual Basic Programmer's Journal) в 1996-1998 годах (и подзабыт). Ваш "наезд" на Воробьёва мне не очень понятен (старый спор?). Пример (1 к 1 с его примером) могу привести я, если угодно . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2007, 11:16 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
ок. Признаю - в своих эмоциях был неправ, погорячился. Данный пост прошу признать, как взятие эмоций взад и попытку сместить акценты. Вступление в топик г-на Worobjoff я воспринял так, что здесь все неправильно написано, а "там" правильно. И упор на события делается как самостоятельное и самодостаточное средство, само по себе развязывающее циклические ссылки. Существо дела не в событиях, а в конструкции и методе ее использования. Конструкция (почти) всегда определяется добавлением вспомогательного (почти всегда скрытого от непосредственного клиентского воздействия) объекта-посредника, полностью или частично развязывающего обратную связь. События – один из возможных механизмов передачи информации от развязывающего объекта к публикуемым классам связанной объектной модели. Можно находить преимущества одного или другого способа в безопасности применения или эффективности реализации и даже спорить об этом. Возможно, лучше исходить из того, что могут быть различные реализации механизма управления набором связанных объектов, более или менее удачно подходящие для решения конкретной задачи. Важнее выявлять и понимать границы применения каждого из вариантов. Внимательное повторное чтение дало мне основание думать, что г-н Worobjoff понимает это не хуже меня, и обращенные к нему слова я должен признать за ошибочные и забрать назад. Если бы было: «а есть еще и такой подход», было бы в целом другое чтение. Фактическое «про работу без циклических ссылок я писал тут» читается существенно иначе. Этим и определилась эмоциональная составляющая моего поста. Странным образом в обоих случаях событийной передачи информации от посредника контейнеру находятся детали, затрудняющее чтение по диагонали и понимание прочитанного «влет». В одном случае не объявлен mCol и о том, что это и как должна работать вся конструкция, приходится догадываться по косвенным признакам. В другом - в классе Doofer свойство Parent заявлено как возвращающее Doofer, а должно быть Doofers. “Совершенно понятно” что в обоих случаях это обычные опечатки. Но кусочек досады остается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2007, 15:08 |
|
||
|
коллекция обьектов + перехватить Events
|
|||
|---|---|---|---|
|
#18+
На самом деле всегда есть несколько способов решения задачи. Лично я препочитаю развязывать циклическую ссылку через события лишь потому что так она решается попутно с другой задачей. Другая задача (их даже две) - это подписывание на события не только классом-коллекцией (специально не пишу "контейнером"). Ведь на события элемента коллекции может подписаться, например, форма отображающая ее в полях (или класс-биндинг) или другая коллекция (почему нет?). Но как передать события одного объекта сразу двум коллекциям? Ведь не будешь хранить ссылки на каждого владельца (упаси бог еще и коллекцию владельцев размещать в классе). Вот и создаешь по два объекта при каждом Add - собственно элемент коллекции и транслятор событий. И держишь две коллекции в одном контейнерном классе. А еще вводишь поле-транслятор событий в классе-элементе коллекции (чтобы унифицировать всю работу с событиями. Наследования здесь нет, а для событий даже интерфейс не унаследуешь). ...А если писать отдельно код для передачи события контейнеру "владельцу" и генерацию события самим классом, получается дублирование кода... ... Ну это замечание уже устарело в связи с упомянутым чуть выше (не забываем, речь зашла о подавлени циклической ссылки). Выложить классы это реализующие все это можно. Но сделать хорошее описание этому не нахожу времени. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2007, 16:15 |
|
||
|
|

start [/forum/topic.php?desktop=1&fid=60&tid=2164712]: |
0ms |
get settings: |
10ms |
get forum list: |
18ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
189ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
56ms |
get tp. blocked users: |
1ms |
| others: | 241ms |
| total: | 538ms |

| 0 / 0 |
