Как получить ссылку на контрол зная его хэндл?

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Как получить ссылку на контрол зная его хэндл?

Сообщение ger_kar » 14.12.2013 (Сб) 22:32

Есть некий контейнер с контролами, например самый обычный Frame. Контролы, которые на нем лежат, должны подключаться к источнику данных (через свойство DataSource). Можно конечно написать десяток строк кода для подключения к источнику данных, а можно это процесс автоматизировать. Для этого достаточно перебрать в цикле все контролы расположенные на контейнере и для всех найденных контролов, кроме лейблов, произвести подключение к источнику данных. И тут возникает вопрос, а как эти контролы то перечислить? Перечислить то конечно можно, но все способы жутко не оптимальны. Например, можно было бы перечислять все контролы на форме и у каждого делать проверку на принадлежность к нужному контейнеру, но это куча лишней не кому не нужной работы, так как контролов на форме достаточно много, а подключать нужно лишь небольшую часть. Можно поступить по другому, искать не контролы, а окна им принадлежащие. Найти все дочерние окна данного окна - контейнера можно быстро просто и оптимально, но тут встает вопрос, как превратить эти хендлы в объектные ссылки на сами контролы. То что превратить можно это я неоднократно читал в постах Хакера, но как это сделать для меня пока тайна. И даже с какой стороны начать копать я пока не представляю, поэтому и обращаюсь за помощью.
Бороться и искать, найти и перепрятать

Sam777e
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 157
Зарегистрирован: 16.09.2010 (Чт) 4:33

Re: Как получить ссылку на контрол зная его хэндл?

Сообщение Sam777e » 16.12.2013 (Пн) 13:20

Excel, VBA
Controls.png
Controls.png (77.82 Кб) Просмотров: 2676
Здоровья и удачи

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Как получить ссылку на контрол зная его хэндл?

Сообщение ger_kar » 16.12.2013 (Пн) 19:06

Все это конечно хорошо, вот только для VB6 это не прокатывает...
Бороться и искать, найти и перепрятать

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 16.12.2013 (Пн) 19:26

Sam777e писал(а):Excel, VBA

Интересно, это так всегда было, или VBA развивается так?
Кстати, есть подозрение, что можно сразу использовать Frame1.Controls, а не Me.Controls("Frame1").Conrols.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Как получить ссылку на контрол зная его хэндл?

Сообщение ger_kar » 16.12.2013 (Пн) 19:51

Qwertiy писал(а):Интересно, это так всегда было, или VBA развивается так?
Ну тут дело не в самом VBA или VB6, а только в компонентах, которые в используются. И тут то и проявляется вся разница. Например VB6 поддерживает массивы контролов, и на одну форму можно положить несколько контролов с одинаковым именем, но разными индексами и даже сделать для них общий обработчик событий, а в VBA такое уже не прокатывает, что порой бывает просто жутко неудобно. Ну и других отличий тоже достаточно, просто привел пример самого наболевшего.
Qwertiy писал(а):Кстати, есть подозрение, что можно сразу использовать Frame1.Controls, а не Me.Controls("Frame1").Conrols.
Да, так оно и есть, потому, что контрол Frame из состава UserForm, входящего в VBA реализует свойство Controls, которое к тому же еще является и свойством по умолчанию, а у VB6'шного Frame такого свойства нет, поэтому такая метода не прокатывает.
Бороться и искать, найти и перепрятать

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Как получить ссылку на контрол зная его хэндл?

Сообщение alibek » 17.12.2013 (Вт) 8:27

ger_kar писал(а):Например, можно было бы перечислять все контролы на форме и у каждого делать проверку на принадлежность к нужному контейнеру, но это куча лишней не кому не нужной работы, так как контролов на форме достаточно много, а подключать нужно лишь небольшую часть.

Даже если их тысяча, время на их перебор будет незначительным на фоне остальной работы.
Впрочем правильнее будет при запуске программы создать коллекцию из элементов управления и обходить коллекцию.
Следующая степень — написать класс-контроллер, в который добавляются элементы управления (при старте) и который будет управлять контролируемыми элементами, примерно так:
Код: Выделить всё
Public ctl as FormControls
...
Set ctl = New FormControls
ctl.AddControl txtField1, lblField1
...
ctl.Enable = False 'batch disable
Set ctl.DataSource = Data1 'batch binding
ctl.Reset 'batch clear


ger_kar писал(а):Можно поступить по другому, искать не контролы, а окна им принадлежащие.

Без хардкода это не сделать, необходимости в этом нет.
Lasciate ogni speranza, voi ch'entrate.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re:

Сообщение alibek » 17.12.2013 (Вт) 8:29

Qwertiy писал(а):Интересно, это так всегда было, или VBA развивается так?

Подключи к проекту VB компонент UserForms, и будут такие же формы с такими же методами, как в VBA.

ger_kar писал(а):Да, так оно и есть, потому, что контрол Frame из состава UserForm, входящего в VBA реализует свойство Controls, которое к тому же еще является и свойством по умолчанию, а у VB6'шного Frame такого свойства нет, поэтому такая метода не прокатывает.

У всех визуальных элементов управления VB есть свойство Container.
Lasciate ogni speranza, voi ch'entrate.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Как получить ссылку на контрол зная его хэндл?

Сообщение The trick » 17.12.2013 (Вт) 11:37

Можно через Set/GetProp устанавливать/получать адрес объекта. Потом через Get/Putmem, __vbaObjSet(AddRef) получать сам объект.
UA6527P

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Как получить ссылку на контрол зная его хэндл?

Сообщение ger_kar » 17.12.2013 (Вт) 12:43

alibek писал(а):Впрочем правильнее будет при запуске программы создать коллекцию из элементов управления и обходить коллекцию.Следующая степень — написать класс-контроллер, в который добавляются элементы управления (при старте) и который будет управлять контролируемыми элементами, примерно так:
Спасибо за идею, тогда уж можно сразу наверное сделать UserControl - контейнер. Хотя даже не знаю, возможно ли делать UserControl'ы контейнеры, надо посмотреть, ни разу такого не делал :)
alibek писал(а):Даже если их тысяча, время на их перебор будет незначительным на фоне остальной работы.
Ну такой подход точно идет в разрез с принципом лени.
Кривоус Анатолий писал(а):Можно через Set/GetProp устанавливать/получать адрес объекта. Потом через Get/Putmem, __vbaObjSet(AddRef) получать сам объект.
Не понял момента. Это к чему относится? Если например известен адрес объекта, который по сути будет адресом (ссылкой) на интерфейс этого объекта, то какой еще объект нужно получать через Get/Putmem?
Бороться и искать, найти и перепрятать

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Как получить ссылку на контрол зная его хэндл?

Сообщение ger_kar » 17.12.2013 (Вт) 12:46

alibek писал(а):У всех визуальных элементов управления VB есть свойство Container.
Ну это же свойство никак не заменяет свойства Controls. Через это свойство можно только получить ссылку на объект-контейнер, на котором лежит контрол.
Бороться и искать, найти и перепрятать

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Как получить ссылку на контрол зная его хэндл?

Сообщение The trick » 17.12.2013 (Вт) 13:19

ger_kar писал(а):Не понял момента. Это к чему относится? Если например известен адрес объекта, который по сути будет адресом (ссылкой) на интерфейс этого объекта, то какой еще объект нужно получать через Get/Putmem?

1. Относится к названию темы
2. Получить объект (контрол)
Перебираешь все дочерние фрейма через EnumChildWindows, получаешь хендлы дочерних окон. При каждой итерации получаешь (GetProp) адрес объекта(контрола), и используешь его, тем самым переводя хендлы окон в объектные ссылки на сами контролы (все как ты писал в первом посте).
UA6527P


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 50

    TopList