Сейчас на форуме: asfa, bartolomeo, hgdagon (+6 невидимых)

 eXeL@B —› Программирование —› Вопрос по дочерним окнам
Посл.ответ Сообщение

Ранг: 9.3 (гость)
Активность: 0.010
Статус: Участник

Создано: 07 мая 2006 04:09 · Поправил: Obsession
· Личное сообщение · #1

Привет.
У меня 2 вопроса тут назрело:
1)Я пишу прогу,которая шлет много разных сообщений окнам в одном приложении("чужом". Приложение Delphi)
В этом приложении встречаются несколько окон одинакового типа и с одинаковыми заголовками.
Я написал специальный класс, в котором есть функция поиска окон.Такая:
ReturnCaptionHandle(number,handle,caption)

Она сначала смотрит на handle:если он NULL,то она перебирает все окна-родители функцией EnumWindows и сравнивает их заголовки с параметром caption.

Если не NULL, - то EnumChildWindows

Так вот, в чужом приложении есть окна-дети с одинаковыми типами и заголовками. Для их идентификации я использую параметр number.
Т.е. я сначала ставлю его в 1, посылаю сообщение - если не дошло - ставлю в 2 и т.д.
Естественно, тут расчет идет на то, что все окна перечисляются в одном и том же порядке.
Чтоб когда я закрыл приложение и открыл его еще раз - порядок дочерних окон остался прежним.

Но, у меня возникло такое ощущение, что Windows каждый раз произвольно раздает handlы дочерним окнам ,т.е. нельзя сказать, что всегда handle(окно-ребенок с таким же заголовком и типом)<handle(другое окно-ребенок с таким же заголовком и типом), если так было в момент отладки.

Вот, чтоб окончательно развеять сомнения - решил спросить.

2)В заголовке одного окна одного приложения встретил некий символ. Похож на 2 вертикальные палочки
||, только низенькие и жирные. Такие еще встречаются в тэгах Winamp'а. Фишка в том, что если этот символ скопировать и вставить, то ничего не вставляется. И в тэгах винампа, кстати, тоже:там ведь как бы левая часть есть и правая. И есть кнопочка скопировать все в другую часть. И если ее нажать, то тот символ не копируется. Наверное, это используется для того, чтоб отличить лизензионную версию от нелизензионной. Хотя, не знаю. Никогда не сталкивался.
Не подскажете, что это может быть?

Хотя, не пожалуй тогда сразу еще дораспрошу. Чтоб сразу. Раз уж начал.
3)Не подскажете, зачем нужен этот тип окон?
Мне иногда встречаются такие типы окон. Например в проге Intellij: там окно: на нем куча кнопок, а ,однако, оно как единое целое выделяется с помощью spy++, и spy++ выдает какой-то странный тип.

4)Есть окно типа TChart для вывода диаграмм(в "чужом" приложении).
Оно выводит графики на каком-то градиентном фоне. Короче, если их печатать, то много чернил расходуется.
А я хотел как-нибудь изменить цвет фона на ровный или даже вообще белый, чтоб графики выводились на белый экран.
Ну, короче, поискал. И нашел только функцию по рисованию прямоугольника на окне.
Как я понял, если сначала послать фон(закрашенный прямоугольник), а потом нажать построить - то градиентный фон все равно выведется (закроя собой ровный).
А если фон послать после вывода графика - то не будет видно самого графика.
Можно как-либо, не вмешиваясь в код приложения,с помощью функций winapi послать сообщение этому окну TChart, чтоб оно изменило фон?



Ранг: 68.8 (постоянный)
Активность: 0.120
Статус: Участник

Создано: 07 мая 2006 04:16 · Поправил: bash
· Личное сообщение · #2

Obsession пишет:
Похож на 2 вертикальные палочки

Возможно это в ANSI-ACSII пара символов , хекс - 7F
Просто это смотря каким шрифтом смотреть - в некоторых действительно вертикальные палочки ,
например в MS Sans Serif, а вот в Tahoma - 



Ранг: 9.3 (гость)
Активность: 0.010
Статус: Участник

Создано: 07 мая 2006 04:20 · Поправил: Obsession
· Личное сообщение · #3

bash пишет:
Возможно это в ANSI-ACSII пара символов , хекс - 7F

Спасибо, проверю.
PS А почему он не копируется?(ctr-ins shift-ins или ctr-C ctr-V)



Ранг: 68.8 (постоянный)
Активность: 0.120
Статус: Участник

Создано: 07 мая 2006 04:25 · Поправил: bash
· Личное сообщение · #4

Obsession пишет:
если этот символ скопировать и вставить, то ничего не вставляется.

Скорее ничего не копируется, чем не вставляется
Это смотря откуда копировать, какие апи для этого применяются (?).
Скопируй прямо из топика.



Ранг: 9.3 (гость)
Активность: 0.010
Статус: Участник

Создано: 07 мая 2006 15:56
· Личное сообщение · #5

bash пишет:
Скорее ничего не копируется, чем не вставляется
Это смотря откуда копировать, какие апи для этого применяются (?).
Скопируй прямо из топика.


Большое спасибо, bash. Да, похоже, действительно, это тот символ.
Почему-то, если копировать из окна spy++, то он копируется, но вставляется как знак переноса каретки(соответственно, я попробовал в этом топике - курсор переносится на следующую строку)
А сейчас, скопировал из топика и вставил в окно spy++ - действительно, это палочка.
Еще раз спасибо.
PS Ответьте,плиз, кто-нибудь на мои остальные вопросы, потому что я правда искал, но не нашел.



Ранг: 158.4 (ветеран), 123thx
Активность: 0.140.49
Статус: Участник

Создано: 07 мая 2006 16:59
· Личное сообщение · #6

Obsession пишет:
но вставляется как знак переноса каретки


потому что это и есть знаки переноса каретки (0D 0A)
в однострочных редакторах они отображаются как черточки




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 08 мая 2006 00:20 · Поправил: ToBad
· Личное сообщение · #7

rmn пишет:
потому что это и есть знаки переноса каретки (0D 0A)
в однострочных редакторах они отображаются как черточки

Да, а вообще так отображаются все символы диапазона 00h - 08h, 0Ah - 1Fh и символ 7Fh.
Посоветую автору топика в каждом конкретном случае переводить строку в HEX или на крайний случай сохранять в бинарный файл после чего открывать его в hiew и смотреть что за символ (если конечно это нужно).




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 08 мая 2006 00:52
· Личное сообщение · #8

Сразу прошу прощения если не много не в тему вопроса, немного недопонял сути проблемы, но попытаюсь ответить.
Я на бейсике реализовывал обращение к дочерним объектам окна следующим образом (привожу кусок кода ниже). В общем принцип такой: есть окно с каким либо заголовком, в нём объекты кнопки, поля ввода и т.д. Hwnd у окна и у любого объекта будет при каждом запуске разное, но вот порядок расположения относительно родительского окна - нет. Например получить hwnd определённой кнопки в окне можно так: hwnd=GetElement("Test app", "", 0, 5, "", "Button") Вот и получается, что не важно что написано на кнопке, мы получим её hwnd. А вообще если цель отличать одно окно с одинаковым классом и заголовком от другого, то можно попробовать сравнивать размеры окна или содержимое. Кол-во элементов или внутренний текст.

GetElementNum(Tit, Cls, Hwnd, SearchHWND) - Выдаёт номер объекта в родительском окне.
\___________/ - один из возможных параметров родительского окна.

GetElement(Tit, Cls, Hwnd, num, Tit1, Cls1) - Выдаёт Hwnd объекта из родительского окна,
заданного одним из параметров (Tit,Cls,Hwnd). Поиск осуществляется по номеру, титрам или классу.
Для точности допускается ввод как всех параметров, так и отдельных.

Function GetElementNum(Tit, Cls, hwnd, SearchHWND) As Long
If hwnd > 0 Then GoTo xx
If Tit = "" Then Tit = vbNullString
If Cls = "" Then Cls = vbNullString
hwnd = FindWindow(Cls, Tit)
If hwnd <> 0 Then
xx: hwnd = GetWindow(hwnd, GW_CHILD)
a = 0
Do
a = a + 1
If hwnd = SearchHWND Then GetElementNum = a: Exit Function
hwnd = GetWindow(hwnd, GW_HWNDNEXT)
Loop While hwnd <> 0
End If
GetElementNum = 0
End Function

Function GetElement(Tit, Cls, hwnd, num, Tit1, Cls1) As Long
tmph = hwnd
If hwnd > 0 Then GoTo xx
If Tit = "" Then Tit = vbNullString
If Cls = "" Then Cls = vbNullString
hwnd = FindWindow(Cls, Tit)
If hwnd <> 0 Then
xx: hwnd = GetWindow(hwnd, GW_CHILD)
a = 0
Do
a = a + 1
b = False
If Tit1 = "" Then b = 0 Else If GetWinText(hwnd) <> Tit1 Then b = -1 Else b = 1
If Cls1 = "" Then c = 0 Else If GetClassName(hwnd) <> Cls1 Then c = -1 Else c = 1
If (Tit1 = Cls1) And (Tit1 = "") Then b = b + (-3 - (c + b))
If num > 0 Then
If (a = num) And ((b + c >= 1) Or (c + b = -3)) Then GetElement = hwnd: hwnd = tmph: Exit Function
Else
If (a = num) Or (b + c >= 1) Then GetElement = hwnd: hwnd = tmph: Exit Function
End If
hwnd = GetWindow(hwnd, GW_HWNDNEXT)
Loop While hwnd <> 0
End If
hwnd = tmph
GetElement = 0
End Function




Ранг: 9.3 (гость)
Активность: 0.010
Статус: Участник

Создано: 08 мая 2006 05:04 · Поправил: Obsession
· Личное сообщение · #9

1)
ToBad пишет:
В общем принцип такой: есть окно с каким либо заголовком, в нём объекты кнопки, поля ввода и т.д. Hwnd у окна и у любого объекта будет при каждом запуске разное, но вот порядок расположения относительно родительского окна - нет.


Боюсь, что это не так. Я провел специально эксперимент.
Вообще, я тоже думал сначала, что это так. Или сначало так работало, а потом, почему-то стало по-другому работать, не знаю.
Но сначала должен сказать, какое у меня приложение.
Это такая лаба, там все нужно вводить руками, а меня это злит ужасно, тем более, что можно все сделать "оптом".

Так вот, там есть несколько окон типа TMaskEdit. Заголовок у них совпадает с тем, что в них написано.
Есть 2 окна с заголовком "00" и 3 - с "0,0000"
(все окна одинакового размера и текст,соответственно, у двух из них и у трех из них одинаковый,т.е. "00" и "0,0000")

(Я сначала, когда не разобрался, как текст внутри менять, менял их заголовки, текст, естественно, не менялся. А заголовки окон тоже в приложении не отображаются - тоже через spy++ смотреть приходилось. Если менять текст - заголовки не меняются. Это понятно.)

Правда, 3 окна с заголовками "0,0000" располагаются на каких-то странных окнах типа TPanel.
На одном окне TPanel 2 окна TMaskEdit, а на другом TPanel - третье окно TMaskEdit (0,0000)
(А 2 окна с заголовками "00" располагаются тоже каждый на своем TPanel)

А, вот сейчас посмотрел - TPanel родители окон TMaskEdit.

Но самое интересное, у окон TPanel тоже заголовки совпадают (заголовки ""). Типы, естественно, одинаковые.
Прям, как будто нарочно сделали, что не подкопаешься. Хотя, это обычнейшая лаба. И никакого там пароля.
На форме TPanel отличаются тем, что на каждой есть надпись. Причем, эта надпись - не окно,т.е. у нее нет хэндла.
Всего разных надписей 6: v,n,k,l,l0,l1.
Так вот эксперимент.
Я каждое из окон TMaskEdit мысленно проидентифицировал своей буквой(хотя в приложении, очевидно, через букву нельзя добраться до окна)
И запустил приложение 5 раз, записав хэндлы каждого из окон TMaskEdit.
Получился такой результат:

n k l l0 l1 v
a7c a84 a74 a6c a68 a60
394 e78 8cc 3a4 3b0 3a8
b98 9d0 ba0 9c8 b9c 9c4
148 124 f88 150 144 f8c
d08 d10 d1c d30 d2c d38


В десятичном виде это будет

n k l l0 l1 v
2684 2692 2676 2668 2664 2656
916 3704 2252 932 944 936
2968 2512 2976 2504 2972 2500
328 292 3976 336 324 3980
3336 3344 3356 3376 3372 3384


Потом я это все загнал в exel и посортировал по разным строчкам (вернее, по столбцам, по строчкам нельзя, поэтому пришлось транспонировать)

Получилсь разные последовательности:

№строчки:1 2 3 4 5

v n v k n
l1 l0 l0 l1 k
l0 v k n l
l l1 n l0 l1
n l l1 l l0
k k l v v




Очевидно, винда раздает хэндлы произвольно.
Еще, кстати, не известно с какого конца EnumWindows просматривает хэндлы: всегда по возрастанию или по убыванию или чередует.

Но мне, в принципе, понравилась идея искать по положению. В принципе, мне приходила в голову такая мысль, но, поскольку я не знал, как это реализовать, я не заострял на этом свое внимание. Короче, сколько ни наталкивался на мысль - удавалось увернуться
2)Спасибо за совет по поводу редактора.

3)Все же хотелось бы получить ответы на следующие вопросы:
а)Почему у некоторых окон есть вроде бы элементы: поля ввода, кнопки, а spy++ видит все как одно единое целое окно.
При этом тип у этих окон какой-то странный.
Например, intellij... да нет, хотя бы даже тот самый эксплорер IE. У него тип Shell DocObject View
Ну, эксплорер, это отдельная песня. Там доступ можно получить через функции shell и javascript, но все-таки...
б)Зачем вообще нужен тип окон и с чем его едят? Что от него можно получить?
в)Можно ли послать сообщение окну типа TChart "чужого" приложения , чтоб оно (окно) сменило фон (например, с градиентного на ровный)?




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 09 мая 2006 01:21
· Личное сообщение · #10

Сколько эта софтина весит ? Если не много - выложи.



Ранг: 9.3 (гость)
Активность: 0.010
Статус: Участник

Создано: 09 мая 2006 01:29
· Личное сообщение · #11

6 МБ.
Но я ее уже победил, так что не беспокойся особо.
Или тебе интересно просто было?




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 09 мая 2006 12:57
· Личное сообщение · #12

Obsession пишет:
Но я ее уже победил, так что не беспокойся особо.
Или тебе интересно просто было?

Что в итоге сделал с хитрыми TMaskEdit в панелях ?



Ранг: 9.3 (гость)
Активность: 0.010
Статус: Участник

Создано: 09 мая 2006 14:46 · Поправил: Obsession
· Личное сообщение · #13

ToBad пишет:
Что в итоге сделал с хитрыми TMaskEdit в панелях ?


Нашел их по координатам, как ты и советовал. Большое спасибо!
Координаты у них у всех, слава Богу, разные.

Но самое интересное, там еще есть 2 кнопки. С одинаковыми заголовками "Сброс", одинакового размера, с одинаковыми координатами, с одинаковым типом TBitBtn. Правда, у них разные родители: окна типа TGroupBox, одинакового размера, с одинаковыми координатами(т.к. они во весь экран приложения), и одинаковыми заголовками "".

А уж у них один родитель непосредственный - TPageControl с заголовком "".
Разработчики, наверное, хотели создать иллюзию, что это одна и та же кнопка "Сброс".
А когда переключаешься между TGroupBox'ами(там специальные такие закладочки сделаны с надписями, но это не окна=>к ним не подобраться) - типа кнопка стирает график с нужного групбокса (т.е не групбокса а tcharta на нужном групбоксе)

Ну,т.е. типа это "умная" кнопка и сама знает, откуда стирать. А на самом деле-то их там 2 кнопки "сброс", реализация другая, а в итоге - не подкопаешься.

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


 eXeL@B —› Программирование —› Вопрос по дочерним окнам
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати