Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Список дочерных объектов 
V
    Опции темы
Serebrus
Дата 22.12.2011, 09:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 333
Регистрация: 22.5.2007
Где: Ташкент

Репутация: нет
Всего: нет



Привет всем.
В окне другой программы (разработан не в Delphi) имеются несколько объектов: (в языке delphi) 1 Panel, в нем 2 GroupBox и в каждом из них по две button..

Хотел узнать, как можно создать список всех имеющихся объектов, включая их классы (если можно по иерархии).
Главное (родительское) окно нашел с помощью FindWindow, а вот самих объектов не смог функцией FindWindowEx

Спасибо
PM MAIL   Вверх
Serebrus
Дата 22.12.2011, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 333
Регистрация: 22.5.2007
Где: Ташкент

Репутация: нет
Всего: нет



Функции GetWindow и GetNextWindow с флагом GW_HWNDNEXT тоже не помогли, они зацикливаются в одном объекте (т.е. не переходят на другой, после нахождения второго объекта повторяют отображать его)
PM MAIL   Вверх
Coder
Дата 22.12.2011, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 5
Всего: 11



Нужно использовать функцию EnumChildWindows().
Есть пример обхода формы и составления иерархи объектов, но он на C++. Если разбираешься могу скинуть.
PM MAIL   Вверх
Serebrus
Дата 22.12.2011, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 333
Регистрация: 22.5.2007
Где: Ташкент

Репутация: нет
Всего: нет



Coder, был бы очен презнателен.
PM MAIL   Вверх
Coder
Дата 22.12.2011, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 5
Всего: 11



Держи smile
Unicode версия.

Код

// Вывод строки на экран
void __log(TCHAR *_str, HWND _hWnd){
    int i = SendMessage(g_StatusList, LB_ADDSTRING, 0, LPARAM(_str));
    if (i != LB_ERR)
        SendMessage(g_StatusList, LB_SETITEMDATA, i, LPARAM(_hWnd));
}

TCHAR WindowName[MAX_PATH], ClassName[MAX_PATH], FullName[MAX_PATH*2+1]; 

// ф-ия обратного вызова. 
// hWnd - найденное окно
// _lParam - используется для передачи уровня иерархии
bool CALLBACK EnumWindowsProc(HWND hWnd, LPARAM _lParam) {    
    ZeroMemory(FullName, sizeof(FullName));
    ZeroMemory(WindowName, sizeof(WindowName));
    ZeroMemory(FullName, sizeof(FullName));

    // Получаем класс и имя окна
    GetWindowText(hWnd, WindowName, sizeof(WindowName)); 
    GetClassName(hWnd, ClassName, sizeof(ClassName));

    // форматируем текст для вывода
    
    // в зависимости от уровня иерархии сдвигаем надпись вправо
    for (int i=0; i<_lParam; i++)
        wcscat_s(FullName, ARRAYSIZE(FullName), L"        ");
    // если это не 0 уровень, добавим >
    if (_lParam)
        wcscat_s(FullName, ARRAYSIZE(FullName), L"> ");

    // добавляем имя класса
    wcscat_s(FullName, ARRAYSIZE(FullName), ClassName);
    // если окно имеет имя, выводим его чере точку.
    if (wcslen(WindowName) > 0){
        wcscat_s(FullName, ARRAYSIZE(FullName), L".");
        wcscat_s(FullName, ARRAYSIZE(FullName), WindowName);
    }

    // выводим на экран полученную строку - Класс.ИмяОкна
    __log(FullName, hWnd);

    // начинаем поиск дочерних окно для текущего. увеличиваем уровень иерархии на 1
    EnumChildWindows(hWnd, (WNDENUMPROC)EnumWindowsProc, _lParam+1);

    return true;
}

void _EnumWindows(){
    // Родительское окно - начинаем поиск с него
    HWND TopWnd = FindWindow(NULL, L"new 1 - Notepad++");
    EnumChildWindows(TopWnd, (WNDENUMPROC)EnumWindowsProc, 0);

    return;
}

PM MAIL   Вверх
Serebrus
Дата 22.12.2011, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 333
Регистрация: 22.5.2007
Где: Ташкент

Репутация: нет
Всего: нет



Спасибо Coder.

Вот мой код:
Код

function GetNew(hw: HWND): BOOL; stdcall;
var s:Pchar;
begin
s:=GetMemory(200);
SendMessage(hw,WM_GetText,200,integer(s));
Form1.ListBox1.Items.Add(IntToStr(hw)+' - '+s);
FreeMemory(s);
EnumChildWindows(hw, @GetNew, 0);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 s:Pchar;
 p, Wnd, h:Hwnd;
 buff: ARRAY [0..127] OF Char;
begin
ListBox1.Items.Clear;
p:=FindWindow(nil,'Single Code');
if p<>0 then
 GetNew(p);
else
 ShowMessage('Окно не найдено');


Но почемуто этот код не отображает все компоненты, как буд-то функции EnumChildWindows сказано найти только n-ое количество компонентов.
В чем может быть "ограничение"?
PM MAIL   Вверх
Coder
Дата 23.12.2011, 03:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 5
Всего: 11



Держи...

Код

var
  WindowName, ClassName : array[0..MAX_PATH] of char;
  FullName : array[0..MAX_PATH*2] of char;

// ф-ия обратного вызова. 
// hWnd - найденное окно
// _lParam - используется для передачи уровня иерархии
function EnumWindowsProc(hWnd : HWND; _lParam : LPARAM) : boolean; stdcall;
var
  i : Integer;
begin
  ZeroMemory(@FullName, sizeof(FullName));
  ZeroMemory(@WindowName, sizeof(WindowName));
  ZeroMemory(@FullName, sizeof(FullName));

  // Получаем класс и имя окна
  GetWindowText(hWnd, @WindowName, sizeof(WindowName));
  GetClassName(hWnd, @ClassName, sizeof(ClassName));

  // форматируем текст для вывода
    
  // в зависимости от уровня иерархии сдвигаем надпись вправо
  for i:=0 to _lParam-1 do
    StrCat(FullName, '        ');

  // если это не 0 уровень, добавим >
  if (_lParam>0) then
    StrCat(FullName, '> ');

  // добавляем имя класса
  StrCat(FullName, ClassName);
  // если окно имеет имя, выводим его чере точку.
  if (strlen(WindowName) > 0) then
    begin
      StrCat(FullName, '.');
      StrCat(FullName, WindowName);
    end;

  // выводим на экран полученную строку - Класс.ИмяОкна
  Form1.Memo1.Lines.Add(FullName);

  // начинаем поиск дочерних окно для текущего. увеличиваем уровень иерархии на 1
  EnumChildWindows(hWnd, @EnumWindowsProc, _lParam+1);

  result:=true;
end;

procedure _EnumWindows();
var
  TopWnd : HWND;
begin
    // Родительское окно - начинаем поиск с него
    TopWnd := FindWindow(0, 'The Bat!');
    EnumChildWindows(TopWnd, @EnumWindowsProc, 0);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Clear;
  _EnumWindows();
end;

PM MAIL   Вверх
Serebrus
Дата 23.12.2011, 07:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 333
Регистрация: 22.5.2007
Где: Ташкент

Репутация: нет
Всего: нет



Coder, огромное спасибо вам.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0470 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.