Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Делфи _ GetWindowText

Автор: Unconnected 7.08.2010 23:34

Привет, ещё раз) Никак мне апи с первого разу не даётся.

Вопрос в следующем. На формах приложений, как принято, лежат компоненты, их можно посмотреть например прогой Spy++ (наводишь прицел и отображается, что это). А некоторых приложениях этим прицелом отдельные поля и кнопки обнаружить нельзя, они там идут как бы "блоками", то есть, например, несколько кнопок, эдитов, чек-боксов объединены в один внутрипрограммный класс. И по отдельности они не определяются. Вопрос, возможно ли вытащить допустим текст из текстового поля, который является частью экземпляра такого класса? Сработает ли здесь GetWindowText? Я пытался вытащить все надписи с компонентов формы с помощью EnumChildWindows, и, вот, столкнулся..

Автор: volvo 8.08.2010 0:20

Цитата
И по отдельности они не определяются.
Да? Можешь привести код программы, которая создает вот такие "внутренние" элементы, не определяемые по отдельности? Очень потестировать хочется smile.gif Может, ты просто ищешь их не так, как надо искать вложенные элементы?

Автор: Unconnected 8.08.2010 0:47

Цитата
Да? Можешь привести код программы, которая создает вот такие "внутренние" элементы, не определяемые по отдельности?


Не могу, да и эти все вроде с закрытым кодом) А вложенные элементы - не child-элементы? Их иначе искать надо?


Автор: volvo 8.08.2010 1:17

Цитата
А вложенные элементы - не child-элементы? Их иначе искать надо?
А я что, знаю, как именно ты ищешь их? Я не телепат.

Вот такая форма:
Прикрепленное изображение

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

А дальше уже посмотрим, что там отображается, а что - нет. smile.gif

Автор: Unconnected 8.08.2010 2:19

Вот, что то такое:


Автор: volvo 8.08.2010 2:47

Вот в этом и твоя ошибка. Кто ж перечисляет все компоненты? А если у тебя окно на чистом API, что будет? Неужели тоже будут найдены компоненты? smile.gif

"Все проще гораздо" (С) Ирония судьбы
Проходишь по всем элементам одного уровня, используя GetNextWindow + GW_HWNDNEXT, а для вложенных - используешь GetWindow + GW_CHILD и рекурсию:

procedure TForm1.Build_Tree(Node: TTreeNode; myHandle: HWND; myLevel: Integer);
var
szClassName, szCaption: array[0..MAXCHAR - 1] of Char;
s: string;

begin
while myHandle <> 0 do begin
GetClassName(myHandle, szClassName, MAXCHAR);
GetWindowText(myHandle, szCaption, MAXCHAR);
s := Format('%s Caption = %s, Handle = %d',
[String(szClassName), String(szCaption), myHandle]);

Build_Tree(TreeView1.Items.AddChild(Node, s),
GetWindow(myHandle, GW_CHILD), myLevel + 1); // Вот она - рекурсия !!!

myHandle := GetNextWindow(myHandle, GW_HWNDNEXT);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var h: HWND;
begin
h := FindWindow(nil, 'Form1');
if h <> 0 then
begin
Build_Tree(nil, GetWindow(h, GW_CHILD), 0);
end
else ShowMessage('Cannot find window');
end;

Автор: Unconnected 8.08.2010 2:59

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

Автор: volvo 8.08.2010 3:01

Хитрый, да? Мозилла не показывает свои заголовки. Об нее уже столько копий сломано, на многих форумах поднимались темы, не удается получить заголовки вкладок/адресных строк

Автор: Unconnected 8.08.2010 3:09

Интересно. Надежно её защитили от вторжений, наверное) Ну, один заголовок она всё же показывает..

Спасибо за помощь smile.gif

Автор: volvo 8.08.2010 3:12

Цитата
Надежно её защитили от вторжений, наверное
Хочешь такую же "защиту" от вторжений? Могу рецептом поделиться smile.gif

Автор: Unconnected 8.08.2010 3:13

Хочу. Странно, winapi вроде один на всех, ан нет, не для всех законы писаны.
Можно и противоядие, в комплект)

Автор: volvo 8.08.2010 3:18

Противоядия не существует. Вернее, оно настолько сложное, что связываться с этим не надо.

А рецепт - очень простой: GetWindowText "берет" только то, что установлено через SetWindowText (дельфийское component.caption := 'что-то там' тоже работает подобным образом). А ты не устанавливай через SetWindowText. Рисуй текст на контроле вручную: http://msdn.microsoft.com/en-us/library/ms901121.aspx в помощь. Тогда твои заголовки тоже не будут читаться через GetWindowText.

Автор: Unconnected 8.08.2010 3:23

Значит, там рисованное всё.. Прикольно, при вводе текста в адресную строку каждый символ наверное удаляется и перерисовывается ) Наверное, им сложнее внутри программы брать caption-ы, нарисованный-то не так просто взять.

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