Как найти хендл контрола

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

Как найти хендл контрола

Сообщение ger_kar » 23.11.2012 (Пт) 8:20

Собственно есть контрол календарь. Вот такой
Календарь.png
Календарь.png (3.11 Кб) Просмотров: 15609

Собственно сам календарь меня вполне устраивает, но в нем есть досадные недоработки, которые я хотел устранить и для этого банально его засубклассить. Но не тут то было. Проблема в том, что для этого нужен хендл, а тот кто делал этот контрол (редиска ;) ) получение хендла не предусмотрел. Сразу подумалось, что можно найти нужное окно и получить его хендл через FindWindowEx, но и здесь засада. Поиск возможен только по классу, ибо ничего другого нет или неизвестно. Класс окна ThunderRT6UserControlDC, а засада в том что контрол то не один, и окон с этим классом соответственно тоже. Ну и как в таком случае можно найти хендл окна нужного экземпляра контрола? Я ничего не могу придумать и соответственно обращаюсь за помощью.

PS: На картинке не только один календарь, а так сказать его симбиоз с текстовым полем, кроме этого в ТП есть кнопочка для, того, что-бы этот самый календарик появлялся.
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как найти хендл контрола

Сообщение Хакер » 23.11.2012 (Пт) 10:05

По координатам.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение Qwertiy » 23.11.2012 (Пт) 11:19

ger_kar писал(а):а засада в том что контрол то не один

А тебе не кажется, что если с контролом что-то не то, то это надо менять для всех его экземпляров в приложении, а не для одного?

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

Re: Как найти хендл контрола

Сообщение ger_kar » 23.11.2012 (Пт) 14:59

Qwertiy писал(а):А тебе не кажется, что если с контролом что-то не то, то это надо менять для всех его экземпляров в приложении, а не для одного?
Ну так то оно бы хорошо конечно было, но как его реализовать? Зато я знаю как можно изменить поведение конкретного окна, применив субклассинг, после чего добавить реакцию окна на нужные мне оконные сообщения.

Хакер писал(а):По координатам.
А можно чуть более подробно?
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как найти хендл контрола

Сообщение Хакер » 23.11.2012 (Пт) 15:31

ger_kar писал(а):А можно чуть более подробно?

У контролла есть координаты.
У окна тоже.
Надо сравнить.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Re: Как найти хендл контрола

Сообщение ger_kar » 23.11.2012 (Пт) 16:49

Т.е. находить окно, сравнить его координаты с координатами контрола, если совпадают, то оно, если не совпало, не оно и дальнейший поиск?
Может лучше в отладчике найти место где контрол хендл хранит, высчитать смещение и брать оттуда? Будет конечно небольшой блек-кодинг, но зато все будет быстро и без лишних движений?
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как найти хендл контрола

Сообщение Хакер » 23.11.2012 (Пт) 17:17

ger_kar писал(а):Т.е. находить окно, сравнить его координаты с координатами контрола, если совпадают, то оно, если не совпало, не оно и дальнейший поиск?

Грубо говоря — так.
Но по-уму — алгоритм другой.

ger_kar писал(а):Может лучше в отладчике найти место где контрол хендл хранит, высчитать смещение и брать оттуда? Будет конечно небольшой блек-кодинг, но зато все будет быстро и без лишних движений?

Большой блэк-кодинг. Может меняться от одной версии рантайма к другой (а может и не меняться). С учётом того, что MS может выпустить новый билд рантайма, полагаться на это я бы опасался.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Re: Как найти хендл контрола

Сообщение ger_kar » 23.11.2012 (Пт) 17:22

Хакер писал(а):Но по-уму — алгоритм другой.
Ну конечно хотелось бы по уму :) . А что за умный алгоритм, мне кроме того, что я написал другое ничего в голову не идет?
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как найти хендл контрола

Сообщение Хакер » 23.11.2012 (Пт) 17:27

ger_kar писал(а):Ну конечно хотелось бы по уму :) . А что за умный алгоритм, мне кроме того, что я написал другое ничего в голову не идет?

Не хочешь думать.
Прочитай оду лени и об обновлении списка правильным методом. Обновление списка тут не причём, однако алгоритмическая проблема — та же.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение Qwertiy » 23.11.2012 (Пт) 20:36

Хакер писал(а):Прочитай оду лени и об обновлении списка правильным методом. Обновление списка тут не причём, однако алгоритмическая проблема — та же.

Тоже не понимаю. Окно одно, найти его надо один раз. Эффективнее, чем проверять найденные окна до тех пор, пока не попадётся нужное не выйдет...

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

Re: Как найти хендл контрола

Сообщение ger_kar » 23.11.2012 (Пт) 20:43

Qwertiy писал(а):Тоже не понимаю. Окно одно, найти его надо один раз.
Почему одно? Если бы было одно, то и проблемы бы не было. Окон может быть несколько, по количеству контролов но в основном это 2 окна.
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как найти хендл контрола

Сообщение Хакер » 23.11.2012 (Пт) 20:44

Querty, как ты предлагаешь это делать? Может я чего-то не понимаю в Windows API :wink: ? Покажи хотя бы псевдокодом.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение Qwertiy » 23.11.2012 (Пт) 21:13

ger_kar писал(а):Почему одно?

Потому что
ger_kar писал(а):Зато я знаю как можно изменить поведение конкретного окна
а если нет, то бери вообще все свои.

Хакер писал(а):Querty, как ты предлагаешь это делать? Может я чего-то не понимаю в Windows API :wink: ? Покажи хотя бы псевдокодом.

Ну я не так хорошо разбираюсь в WinApi, чтобы точно сказать, что и как использовать...
Если нужен только один контрол, то представляю примерно так. По имени класса находим окна. Внутри callback-функции проверяем координаты окна, если совпали, сохраняем хендл и прекращаем поиск.
Сейчас подумал, что можно пытаться получить видимое окно по точке внутри него, но для этого нужно чтобы оно отображалось на экране в момент поиска, поэтому мне такой вариант не нравится. К тому же, есть возможность угодить во вложенный контрол, если он по каким-то причинам подвинется.

PS: Я не "Querty".

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

Re: Как найти хендл контрола

Сообщение ger_kar » 23.11.2012 (Пт) 21:21

Ну Qwertiy, все запутал :) Нужно найти одно окно, среди некого множества. Т.е. Дано много окон, а не одно, поэтому написал
ger_kar писал(а): Почему одно?
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как найти хендл контрола

Сообщение Хакер » 23.11.2012 (Пт) 21:36

Qwertiy писал(а):Если нужен только один контрол, то представляю примерно так.

Если один, то да. Но ведь в данном случае ситуация не та.

Я говорил вообще об алгоритмической задаче вот такого рода: есть два равновеликих множества, между которыми действует биективное отношение. То есть мы можем как-то проверить, являются ли два элемента из двух множеств — связанными друг с другом.

И теперь нам нужно установить связанность.

Худший способ это делать: обходить элементы первого множества и для каждого элемента из первого множества делать перебор всех элементов второго множества, пока не будет найден соответствующий элемент.

Лучший способ, это то, что я называл «методом двух курсоров» в топике об обновлении списка. Нужно сначала выстроить элементы по какому-то ключу и потом установить два курсора на начала двух списков и двигать курсоры по установленному (описанному в том топике) правилу.

Для трёх контролов это может быть несущественно, но вообще...
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение Qwertiy » 23.11.2012 (Пт) 21:57

Хакер писал(а):Худший способ это делать: обходить элементы первого множества и для каждого элемента из первого множества делать перебор всех элементов второго множества, пока не будет найден соответствующий элемент.

Ну это-то да... Но здесь об одном контроле говорится. Или о всех без фильтрации.

Хакер писал(а):Лучший способ, это то, что я называл «методом двух курсоров» в топике об обновлении списка.

А как насчёт методов с использованием хешей?

Хакер писал(а):Если один, то да. Но ведь в данном случае ситуация не та.

Я уже совсем запутался, какая ситуация в данном случае :(

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как найти хендл контрола

Сообщение Хакер » 23.11.2012 (Пт) 22:04

Qwertiy писал(а):А как насчёт методов с использованием хешей?

И в чём суть метода?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ark
Бывалый
Бывалый
 
Сообщения: 216
Зарегистрирован: 18.07.2011 (Пн) 0:57

Re: Как найти хендл контрола

Сообщение ark » 24.11.2012 (Сб) 4:39

Чем отличается НУЖНЫЙ контрол от остальных? Координатами? Текстом? Ещё какой-нибудь фичей?
Я бы проверил через EnumProps - может, там уже что-то есть. Если нету - пронумеровать контролы врукопашную через SetProp hwnd, "ctrlIndex", index, ну а потом через GetProp определять - нужный или нет.
ЗЫ. Кстати, индекс может быть не только индексом, но и поинтером на куда угодно - строку, структуру, ObjPtr и т.п.
ЗЫ2
ger_kar писал(а): банально его засубклассить
Если процесс чужой - банально не получится. Если свой - зачем огород городить с FindWindow?

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

Re: Как найти хендл контрола

Сообщение ger_kar » 24.11.2012 (Сб) 7:54

ark писал(а):Если процесс чужой - банально не получится. Если свой - зачем огород городить с FindWindow?
Процесс родной. И почему интересно FindWindowEx это огород? Я думаю что с EnumChildWindows будет гораздо хуже, так как будут перечисляться все дочерние окна.
ark писал(а):Чем отличается НУЖНЫЙ контрол от остальных? Координатами? Текстом? Ещё какой-нибудь фичей?

Только координатами
Бороться и искать, найти и перепрятать

ark
Бывалый
Бывалый
 
Сообщения: 216
Зарегистрирован: 18.07.2011 (Пн) 0:57

Re: Как найти хендл контрола

Сообщение ark » 25.11.2012 (Вс) 3:30

ger_kar писал(а):И почему интересно FindWindowEx это огород
1. Так координаты нужного контрола известны заранее? http://msdn.microsoft.com/ru-ru/library ... 58(v=vs.85).aspx
2. Хэндл у контрола есть, и скорее всего, хранится для внутреннего пользования где-нибудь сразу за VTABLE. Попробуй посмотреть первые 100-200 байт за ObjPtr

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

Сообщение Qwertiy » 25.11.2012 (Вс) 11:05

ark писал(а):1. Так координаты нужного контрола известны заранее? http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms633558(v=vs.85).aspx

Могу ошибаться, но мне казалось, что такие функции возвращают видимое окно по координатам внутри него. Почему мне такой вариант не нравится, я уже говорил.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как найти хендл контрола

Сообщение Хакер » 25.11.2012 (Вс) 11:28

ark писал(а):2. Хэндл у контрола есть, и скорее всего, хранится для внутреннего пользования где-нибудь сразу за VTABLE. Попробуй посмотреть первые 100-200 байт за ObjPtr

Я уже говорил, почему такие методы должны быть отброшены.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ark
Бывалый
Бывалый
 
Сообщения: 216
Зарегистрирован: 18.07.2011 (Пн) 0:57

Re: Как найти хендл контрола

Сообщение ark » 25.11.2012 (Вс) 11:41

Qwertiy писал(а):такие функции возвращают видимое окно
Ну, так есть ChildWindowFromPoint(Ex)

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

Re: Как найти хендл контрола

Сообщение ger_kar » 26.11.2012 (Пн) 6:59

ark писал(а):Ну, так есть ChildWindowFromPoint(Ex)
Надо попробовать. Идея мне нравится. А по хендлу окна можно получить наименование оконного класса? Если да, то какой функцией?
Бороться и искать, найти и перепрятать

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

Сообщение Qwertiy » 26.11.2012 (Пн) 7:56

ger_kar писал(а):А по хендлу окна можно получить наименование оконного класса? Если да, то какой функцией?

GetWindowClass :)

ark
Бывалый
Бывалый
 
Сообщения: 216
Зарегистрирован: 18.07.2011 (Пн) 0:57

Re: Как найти хендл контрола

Сообщение ark » 26.11.2012 (Пн) 13:03

Кстати, а события у контрола есть? Resize, например?

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

Сообщение Qwertiy » 26.11.2012 (Пн) 13:56

Ну если хук повесить...

ark
Бывалый
Бывалый
 
Сообщения: 216
Зарегистрирован: 18.07.2011 (Пн) 0:57

Re: Как найти хендл контрола

Сообщение ark » 27.11.2012 (Вт) 0:30

Qwertiy писал(а):Ну если хук повесить
Как вариант, WH_CBT, например.
А вообще - какой функциональности не хватает, если не секрет. Может, по другому решить можно? И чем стандартный DTP не устраивает?

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

Re: Как найти хендл контрола

Сообщение ger_kar » 29.11.2012 (Чт) 16:27

ark писал(а):Кстати, а события у контрола есть? Resize, например?
Вот собственно сам контрол
Kalendar.rar
(11.14 Кб) Скачиваний: 314
, там событий как кот наплакал :cry: , всего ничего :
DragDrop, DragOver, GotFocus, LostFocus, SelectDate, Validate
Бороться и искать, найти и перепрятать

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

Re: Как найти хендл контрола

Сообщение ger_kar » 29.11.2012 (Чт) 17:17

ark писал(а):2. Хэндл у контрола есть, и скорее всего, хранится для внутреннего пользования где-нибудь сразу за VTABLE. Попробуй посмотреть первые 100-200 байт за ObjPtr
Нашел место, где контрол свой хедл прячет. И хранится он по смещению &H3C(60). Ну и заодно нашел и другие места где его можно найти. Таких мест оказалось 3 :) Мне интересно, а почему именно был указан диапазон 100-200 Байт?

ark писал(а):Ну, так есть ChildWindowFromPoint(Ex)
Тут есть небольшая заминка
Код: Выделить всё
Private Declare Function ChildWindowFromPoint Lib "user32.dll" (ByVal hWndParent As Long, ByVal pt As POINTAPI) As Long
Private Type POINTAPI
   x As Long
   y As Long
End Type
В объявлении указано, что структура передается по значению. Я сначала думал, что ошибка в декларации, но оказалось что нет, действительно структура должна передаваться по значению. Но VB так делать не умеет :( . Конечно в этом случае можно не париться со структурой, и сделать:
Declare Function ChildWindowFromPoint Lib "user32.dll" (ByVal hWndParent As Long, ByVal x As Long, ByVal y As Long) As Long
Но возникает вопрос, может все таки можно исхитриться и передать как то структуру ByVal? Хорошо, в этом случае всего два поля и передать их по отдельности не проблема, а вот если структура не такая простая? Или таких случаев в принципе не бывает? Я тоже удивился, до этого не разу не встречал передачу структуры ByVal. И еще, если таким образом структуру пихать с стек, то какое поле должно идти первым?

Qwertiy писал(а):GetWindowClass
Может GetClassName?
Бороться и искать, найти и перепрятать

След.

Вернуться в Windows-программирование

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5

    TopList  
cron