Как с помощью Delphi получить значения всех элементов Edit диалога формы?
Приветствую Вас, дорогие посетители! На этом блоге уже написана статья, как на Delphi с помощью библиотеки Synapse отправлять письма. Также было рассказано о получении с помощью Delphi IP-адреса тут и здесь. Эта статья поможет нам разобраться как прочитать все значения элементов диалога Edit из окна другого приложения, средствами Delphi, используя функции WinAPI. Итака, начнем!
Мы будем пользоваться функциями WinAPI для получения элементов диалога класса Edit. Например, нам нужно получить значения Edit c формы с заголовком «MyProgram», поэтому воспользуемся функцией WinAPI FindWindow.
HWND FindWindow( LPCTSTR lpClassName, // указатель на имя класса LPCTSTR lpWindowName // указатель на имя окна );
В первой строке мы запишем:
Hndl:=FindWindow(nil, 'MyProgram');
Как видим, с помощью этой функции мы получаем указатель на окно (Нandle — дескриптор окна). Заносим дескриптор окна в переменную Hndl. Этот Handle нужен нам для следующего действия:
Hedt:=FindWindowEx(Hndl,0,'Edit',''); // получаю первый Edit
Для поиска воспользуемся функцией WinAPI FindWindowEx (ПоискОкнаУлучшенная):
[Не поддерживается в Windows NT] Функция FindWindowEx отыскивает данные о дескрипторе окна, имя класса и имя окна которого соответствуют определенным строкам. Функция поиска дочерних окон начинается с первого до последнего заданного дочернего окна. HWND FindWindowEx ( HWND hwndParent, // дескриптор родительского окна HWND hwndChildAfter, // дескриптор дочернего окна LPCTSTR lpszClass, // указатель имени класса LPCTSTR lpszWindow // указатель имени окна );
Теперь мы получаем в переменную Hedt, дескриптор дочернего окна, первого Edit. Осталось открыть перебор по элементам диалога окна. Для этого используем функцию WinAPI GetWindow:
Функция GetWindow возвращает дескриптор окна, которое определено отношением (Z индекса или родительским) к указанному окну. HWND GetWindow ( HWND hWnd, // дескриптор родительского окна UINT uCmd // флаг отношений );
Поэтому запишем следующий текст:
Hedt:=GetWindow(Hedt,GW_HWNDFIRST);
Теперь в переменной Hedt установлен указатель на первый Edit. Параметр GW_HWNDFIRST указывает на выбор первого элемента. Выборка началась, чтобы её продолжить запишем следующее:
repeat //получаю next Edit Hedt:=GetWindow(Hedt,GW_HWNDNEXT); if Hedt<>0 then SendMessage(Hedt,WM_GETTEXT,WPARAM(512),lparam(HoldString)); HoldString__ := HoldString__ + ' ' + String(HoldString); until Hedt=0;
Теперь в переменной Hedt установлен указатель на следующий Edit. Параметр GW_HWNDNEXT указывает на выбор следующего элемента. Выборка будет продолжаться, пока не будут перебраны все элементы. Также мы воспользовались функцией WinAPI SendMessage, с помощью которой мы считываем значение элемента диалога.
LRESULT SendMessage( HWND hWnd, // дескриптор окна назначения UINT Msg, // сообщение WPARAM wParam, // первый параметр сообщения LPARAM lParam // второй параметр сообщения );
Параметр WM_GETTEXT указывает окну с дискриптором Hedt, что нам нужно считать его значение в переменную HoldString, размером не больше, чем 512. Давайте проверим нашу работу. Создадим новый проект. Бросим кнопку на форму. Вот весь листинг:
procedure Form1.Button1Click(Sender: TObject); var HoldString: PChar; HoldString__: String; Hndl,Hedt: HWND; begin Hndl:=FindWindow(nil, 'MyProgram'); Hedt:=FindWindowEx(Hndl,0,'Edit',''); // получаю первый Edit Hedt:=GetWindow(Hedt,GW_HWNDFIRST); //указатель на первый Edit repeat //установливаем указатель на следующий Edit Hedt:=GetWindow(Hedt,GW_HWNDNEXT); if Hedt<>0 then SendMessage(Hedt,WM_GETTEXT,WPARAM(512),lparam(HoldString)); HoldString__ := HoldString__ + ' ' + String(HoldString); until Hedt=0; end;
Будет Acces Violation. Как минимум нужно написать
var HoldString: array[0..512] of char;
Хорошо напишите, у меня Acces Violation не выходил.
Все то может и правильно только у меня FindWindowEx упорно возвращает 0
ChildWnd:=FindWindowEx(ParentWnd, 0,’Button’,»);
if(ChildWnd <> 0) then
SendMessage(ChildWnd, BM_CLICK, 0, 0)
else ShowMessage(‘But в Proba не найден!’);
Не помогает запись 4 параметра как nil.
Аналогично не может найти Edit1
Но окно проги находит!!!
Я делал этот скрипт для XP и в XP, на Delphi 5, может из-за этого проблема?
И я под Win XP но на Delphi7
Посмотрите не изменилась ли сама функция FindWindowEx, например по параметрам или не появился ли ей какой-нибудь аналог?
Есть 2 имени — имя (однооконного) приложения
и подпись (Caption) окна формы.
Самое интересное FindWindow возвр не нулевой дескриптор в обоих случаях. А вот FindWindowEx работает только по дескриптору найденному по Caption.
Это так? даже когда окна не дельфевые, а скажем Web-приложения?