Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как однозначно определить окно?  (Прочитано 16534 раз)
0 Пользователей и 1 Гость смотрят эту тему.
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« : 10-05-2005 16:29 » 

Контекст: Обычная сессия Windows, имеется несколько обычных окон (совершенно любые оконные приложения), которые, естественно, содержат какие-то контролы.
Задача: однозначно определить конкретный контрол в конкретном окне/дочернем окне.
Например, combo-box в, скажем, Outlook.
Нужно это для того, чтобы посылать ему всякие сообщения.
----
Я делаю так: по нажатию определенной кнопки (глобальный хук) контрол под мышкой (не в своем окне!) берется функцией WindowFromPoint(). Соответственно, имеем хэндл окна. Но этот хэндл, как я понимаю, сессионный, то есть после перезагрузки винды он будет другим.
Тогда я по цепочке нахожу (GetParent()) всех родителей этого контрола. Запоминаю каждого через GetClassName(). То есть имею цепочку классов... Для каждого запоминаю координаты, в которых для него находилась мышка.
Когда надо отправить сообщение (для начала банальное WM_LBUTTONDOWN/WM_LBUTTONUP), я по той же цепочке нахожу каждое окно через FindWindowEx(). И последнему посылаю сообщения.
В принципе, работает... Но когда в окне два контрола одного класса, то выбирается, естественно, первый. А если мне надо второй/третий?
Конкретное приложение - TotalCommander, в котором две панели. Все время выбирается правая (?), хотя могу кликать и на левой.
---
Повторю вопрос: как однозначно определить контрол? Причем не в пределах сессии, а так, чтобы можно было повторить операцию на другом компе с другой операционкой (98/2k/XP)...  :?
Греат сенкс ин адванс....
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #1 : 10-05-2005 18:03 » 

По большому счёту, без дополнительных условий - никак. Проблема стара как мир - все проги автоматического визуального тестирования страдают этим. Наши тестеры обращаются постоянно к нам с просьбой дать контролам (там где это возможно) уникальные имена. Те если у тебя есть возможность и это "твои" окна, то давай им уникальные имена - например ListControl можно дать имя с помощью SetWindowText. Визуально его никто не видит, а опросить можно. Так-же можно поступать и с некоторыми другими контролами, WindowText которых явно не отображается на экране. Так же маловероятно, что у одного родителя будет две кнопки с одинаковым названием. Те тоже можно использовать WindowText.
Но если я тебя правильно понял, тебе хочется сделать это для чужих окон. Сразу скажу, что панацеи нету - в самом худшем случае у тебя ничего не получится. Но попытаться всё-таки стоит. Рассмотрим  некоторые способы.  Один из них - положение отностительно родительского окна (client). В случае со стандартным диалогом координаты контрола не меняются, те всегда можно воспользоваться  WindowFromPoint. Это не работает в окнах переменного размера, если положение контрола зависит от размера родительского окна. Хотя если знаешь алгоритм, то можно их тоже вычислить - например если контроллы всегда выровнены по левому краю (центру и тп).
Другая возможность - использование специфичного индивидуального класса, но это большая редкость. Когда для каждого контрола используется свой класс. Однако и эту возможность не стоит упускать из вида.
Ну и наконец последнее - использование ID из ресурсов - обычно каждому контролу присваивается свой ID (достать можно с помощью ф-ции GetDlgCtrlID), обычно это номер например 101. Только не надо забывать. что разрешено использовать одинаковые ID в разных диалогах например IDOK IDCANCEL итп.
В общем однозначного решения нет. А есть только "комплекс мероприятий направленных на..."
Маленько сумбурно наверно это всё выглядит - поэтому, если что-то не понял, то спрашивай.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #2 : 10-05-2005 18:14 » 

Елки, про WindowFromPoint в обратную сторону я как-то забыл... Вместо этого пытался родительскому окну кинуть чужое сообщение с координатами контрола. Улыбаюсь не прокатило.
Насчет ID - это мысль. А может на одном окне использоваться один ID для разных контролов? По-моему может. Я же могу сделать две IDOK-кнопки.
Впрочем, в таком случае реакция на сообщение чаще всего будет одинаковая... Так что все равно. А как получить контрол по ID ? Или перебором по всем (типа Enum)?
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 10-05-2005 19:02 » 

А может на одном окне использоваться один ID для разных контролов? По-моему может. Я же могу сделать две IDOK-кнопки.
МОжно, (только зачем?) яркий пример IDC_STATIC - речь идёт о присваиваемых ID для получения доступа через GetDlgItem. Обычно редактор ресурсов следит за этим и не разрешает такого делать.
Я же сказал, что в самом худшем случае ничего не поможет. Поэтому... Жаль
А как получить контрол по ID ? Или перебором по всем (типа Enum)?
Если у тебя есть ID контрола и handle родителя, то ::GetDlgItem(hWnd, nID) вернёт тебе хендл контрола.
Я думаю тебе надо создать сначала карту таких ID - ведь где-то тебе это всё-равно надо сделать.
Самое простое прощёлкать мышкой по контролам и получить хендлы (WindowFromPoint), потом GetDlgCtrlID даст тебе ID контрола. А ещё одно забыл, может тоже поможет -  в ресурсах диалога контролы записываются в z-order определяется Tab-order. Или если по-понятнее, то z-order контролов определяется их последовательностью в ресурсах - это на тот случай если ты захчешь идтти по "ресурсному" пути.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #4 : 10-05-2005 19:36 » 

А TabStop есть не у всех контролов. Вернее, не все могут получать фокус.
Тот же static... Но если z-order, то, может, он и есть...
...Вот сейчас проверил. У Static тоже есть TabOrder. Это, конечно, выход.
А как получить эту величину?
----
И еще объясните мне про функции GetProp() и SetProp().
У меня есть описание: GetProp() выбирает дескриптор элемента данных свойств, связанного с дескриптором окна и имеющего такой же строковый идентификатор, который был указан в SetProp(). Здесь была моя ладья...
В общем, я понял, что это хэш каких-то свойств, так? А каких свойств? Пример, пожалуйста. Как-нибудь это здесь можно использовать?
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #5 : 10-05-2005 20:13 » 

Бррр. Так стоп. TabStop совсем тут не причём. Это параметр указыват - надо ли останавливаится на данном элементе при табулировании. Tab-order это порядок элементов на форме (диалоге) и он есть всегда.
Ну хоть какой-то порядок должен же быть. Ага
Эту величину никак не получишь поскольку её нет - в смысле величины нет. Это просто порядок окон (тн z-order). Если он тебе известен, то ты например можешь сказать, что тебе интересует 5-ое окно данного диалога - это например Edit. Посмотри для примера как работают смотрелки ресурсов типа ResHackera.
Недостаток этого метода заключается в том, что если ЕХЕшник сжат, то стандартые методы доступа к ресурсам не действуют (а других я не знаю).

Не думаю, что  GetProp() и SetProp() тебе как-нибудь помогут. Они создаются динамически и разрушаются при Destroy поэтому перенос на другой комп невозможен. Другими словами для  GetProp() и SetProp() тебе нужен хендл окна, а он каждый раз новый. Тут я думаю тебе надо будет создавать сопутствующий файл с необходимой инфой для каждой конкретной проги.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #6 : 10-05-2005 20:20 » 

В этот поздний час не я один не сплю... Улыбаюсь
По-моему я ошибаюсь, но из твоих слов можно понять, что TabOrder показывает такой же порядок положения окон, как если обходить их через EnumChildWindows. Вряд ли это так.
А зачем нам exe-шник, если прога уже запущена? Ресурсы уже должны быть в памяти и пронумерованы.
Про z-order мне идея все равно понравилась. Счас буду ее думать...
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #7 : 10-05-2005 20:34 » 

Я думаю, эту величину как-то можно достать...
А если я создаю контролы не через ресурсы, а динамически? Может, я чистый WinAPI использую... Должно же окно знать в каком порядке отрисовывать объекты?
Вот, нашел функцию BringToFront() - тоже должна, по идее, менять это мифическое число... Правда она, похоже, только в .NET. Жаль
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #8 : 10-05-2005 20:38 » 

У меня только пол одинадцатого.
TabOrder на самом деле всё очень просто. Можешь поэкспериментировать - создай диалог и положи на него кнопку, комбобокс, едит, статик. Если ты откроешь rc файл в блокноте, то ты увидишь, что они находятся именно в этом порядке. Если запустишь Tab-order то увидишь нумерацию этих контролов
1кнопка
2комбобокс
3едит
4статик
Теперь кликай их в таком порядке  едит, статик, комбобокс, кнопка
Сохрани файл и открой его снова в Блокноте. Ты увидишь, что порядок контролов изменился.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 10-05-2005 20:40 » 

ЕЩё раз - это просто порядок в котором элементы находятся в ресурсах. Никакой величины нет.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #10 : 10-05-2005 20:41 » 

Сорри. если ты создаёшь динамически то используется порядок создания
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #11 : 10-05-2005 20:49 » 

А вот имя класса, получаемое через GetClassName() - оно уникально всегда? Мне кажется, на другом компе с другой системой оно может и отличаться.
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #12 : 10-05-2005 22:48 » new

А вот имя класса, получаемое через GetClassName() - оно уникально всегда? Мне кажется, на другом компе с другой системой оно может и отличаться.

Скажем так - оно уникально всегда в самом себе. Но это не значит, что ты не можешь создать десятки окон этого класса. Даже на другом компе должна присутствовать библиотека этого оконного класса. Или же описание этого класса должно находится в ЕХЕшнике и перед использованием обязательно зарегестрировано в системе. Например, если используются в одном диалоге 5 "деревянных" контролов из comctl, то все 5 являются потомками класса SysTreeView32.
Речь шла о собственных контролах например ты делаешь контролы и регистрируешь оконные классы baldr_Button, baldr_ComboBox, baldr_Edit и тд. Тогда ты смело можешь пользоваться GetClassName. При условии, конечно. что у тебя на форме только одна кнопка класса baldr_Button и тд. Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines