Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как можно в Edit'ы другого приложения вывести требуемый текст?

397
10 марта 2007 года
SergPas
527 / / 03.02.2007
Доброго времени суток! Проблема состоит в следующем.
Как можно в Edit'ы другого приложения вывести требуемый текст?
Для решения использовал следующие действия:

function proc(wnd:HWND):boolean; stdcall;
begin
SendMessage(wnd,WM_SETTEXT,0,LParam(PAnsiChar('Text')));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
EnumChildWindows(window,@proc,0);//window-родительское окно; Handle получен верно
end;

В файле справки о функции EnumChildWindows говорится, что функция, переданная ей в качестве 2-го
аргумента выполняется для всех дочерних окон. У меня либо выводит текст для последнего Edit'а
( вслучае, если я пытаюсь заполнить Edit'ы приложения, созданного в Delphi) родительского окошка, либо вообще ничего и никуда не выводит (для других приложений). в чём дело?
257
10 марта 2007 года
kosfiz
1.6K / / 18.09.2005
 
Код:
function proc(wnd:HWND):boolean; stdcall;
begin
SendMessage(wnd,WM_SETTEXT,0,LParam(PAnsiChar('Tex t')));
Result:=true;
end;

но этот код изменит текст даже на кнопках, так что добавь проверку на то, что дочерний элемент это Edit, например можно сделать так:
 
Код:
var wndClass:array[0..255] of char;
begin
Result:=True;
GetClassName(wnd, wndClass, sizeof(wndClass));
if wndClass='TEdit' then
 SendMessage(wnd,WM_SETTEXT,0,LParam(PAnsiChar('Text')));
end;

кстати в исходниках есть подобное.
397
10 марта 2007 года
SergPas
527 / / 03.02.2007
Спасибо! Вот что невнимательность делает с людьми! Забыл вернуть результат функции! А как можно присвоить разным Edit'ам разные значения?
257
11 марта 2007 года
kosfiz
1.6K / / 18.09.2005
если это надо сделать при перечислении, то просто смотри какой по счету данный найденный Edit, и отсылай характерный для данного значения счетчика текст.
397
11 марта 2007 года
SergPas
527 / / 03.02.2007
А как это оформить на практике?
257
11 марта 2007 года
kosfiz
1.6K / / 18.09.2005
ну например так можно:
Код:
var i:word; //счетчик - глобальная переменная
<skip>
function proc(wnd:hWnd):boolean;stdcall;
var wndClass:array[0..255] of char;
begin
Result:=True;
GetClassName(wnd, wndClass, sizeof(wndClass));
if wndClass='TEdit' then
 begin
 case i of //выбираем Edit по счету и отсылаем сообщение
 0: SendMessage(wnd,WM_SETTEXT,0,LParam(PAnsiChar('Text0')));
 1: SendMessage(wnd,WM_SETTEXT,0,LParam(PAnsiChar('Text1')));
 2: SendMessage(wnd,WM_SETTEXT,0,LParam(PAnsiChar('Text2')));
 end;
 inc(i); //увеличиваем счетчик на 1
 end;
end;
<skip>
EnumChildWindows(window,@proc,0);
397
11 марта 2007 года
SergPas
527 / / 03.02.2007
Огромнейшее СПАСИБО! Всё работает! Чтобы я без Вас делал, наверное, разбирался бы сам! Ещё раз огромное СПАСИБО!
397
11 марта 2007 года
SergPas
527 / / 03.02.2007
Опять проблема! Проблема с теми же Edit'ми. Дело в том, что данный код я проверил, тестируя его на вспомогательной программе, написанной в Delphi. Действительно, в такой программе в Edit'ы записываются
определённые строки, button'ы нажимаются и прочее. Но кардинально иначе обстоят дела с другими приложениями. Так, например,после
первого нажатия на кнопку появляется другое окно с тем же Handle'ом, именем класса окна и его названием, в котором
Edit'ы остаются пустыми, кнопки не нажимаются и т.д. Трассируя, я выяснил, что имя класса Edit'ов не 'Edit', как принято, а непонятно что, в связи с чем они и не заполняются. Кнопки в этом же окне не нажимаются. В чём причина такого поведения?
257
11 марта 2007 года
kosfiz
1.6K / / 18.09.2005
ну так и не обязательно имя класса долно быть Edit или TEdit. впринципи может быть все что угодно, хоть абракадабра. уточни свою задачу а там может что и придумать можно будет.
397
11 марта 2007 года
SergPas
527 / / 03.02.2007
Странно получается... Я использую WinAPI функцию WindowFromPoint для получения Handle'а окна.
Вызвав функцию GetWindowClass с параметром полученного ранее Handle'a я получаю название "Edit"
для Edit'a, а не белеберду... Это у меня не укладывается в голове.
Задача стоит передо мной следующая... Упростить процесс установки приложений на ПК, а именно
автоматизировать его. Конечно можно написать bat-файл для этой цели или создать дистрибутив.
Либо воспользоваться платной программой LazySetupCD... Меня ни тот, ни другой вариант не устраивает...
Я решил писать программу... Вначале у меня была задумка (вполне приемлемая) запускать инсталяшки,
используя функцию ShellExecute с параметром '/qn' или '/qb'- приложения устанавливаются те,
где не требуется ввод серийного номера в процессе установки. Поэтому мне приходится нажимать
программно на кнопки, вводить программно серийные номера в Edit'ы и т.д.
334
11 марта 2007 года
HexEdit
809 / / 27.07.2006
Цитата: kosfiz
ну так и не обязательно имя класса долно быть Edit или TEdit. впринципи может быть все что угодно, хоть абракадабра. уточни свою задачу а там может что и придумать можно будет.


Вовсе нет, есть стандартизированный класс для edit'а "EDIT"
Есть конечно какие-нибудь надстройки, но это редко... в основном "EDIT"

397
11 марта 2007 года
SergPas
527 / / 03.02.2007
Я тоже так думал до поры до времени. Оказывается, что нет... Edit'ы могут иметь другой класс, отличный от 'Edit'... К сожалению так показывает моя практика...
334
12 марта 2007 года
HexEdit
809 / / 27.07.2006
Ну так... я тож знаю.
Цитата:
Есть конечно какие-нибудь надстройки, но это редко... в основном "EDIT"


Ну... кстати лучше думаю искать по ID

Как я делал:
беру прогу, SIW, там есть смотреть класс окна и handle.
Запускаю Delphi, простенький код

 
Код:
...
ShowMessage(IntToStr(GetDlgCtrlID(<хендл_полученный_из_проги>)));
...

И все... а дальше уж дело техники :)
257
12 марта 2007 года
kosfiz
1.6K / / 18.09.2005
SergPas
тоже такое когда-то делал, всмысле прогу для упрощения инсталляции. напиши парочку названий программ, с которыми не получается провзаимодействовать, только плиз, чтоб они не редки были и найти можно было. будем разбираться.
397
12 марта 2007 года
SergPas
527 / / 03.02.2007
В качестве примера для трассировки я выбрал InstallShield Wizard Borland Delphi 6 Enterprise Edition.
Буду пробывать ещё использовать функцию GetDlgCtrlID.
257
12 марта 2007 года
kosfiz
1.6K / / 18.09.2005
[quote=SergPas]В качестве примера для трассировки я выбрал InstallShield Wizard Borland Delphi 6 Enterprise Edition.
Буду пробывать ещё использовать функцию GetDlgCtrlID.[/quote]
вообщем я попробовал. кнопки и эдиты находит исправно, но... ненажимаются кнопки и не вставляется текст в эдиты. присмотрелся я к классу окна установщика и заметил, что класс MsiDialogCloseClass. особенно меня заинтересовало это Close. вообщем-то мне кажется(это лишь гипотеза), что стоит что-то вроде защиты от подобных нажиманий кнопок. у меня с данной прогой несправляется LazySetupCD, если выбрать опцию наподобие нашей, но вот если имитируются действия пользователя так, что движется курсор, то здесь все работает. возможно тебе придется тогда что-то предпринять, чтобы твоя программа поступала аналогично, т.е. движение курсора в определенную точку и клик.
397
12 марта 2007 года
SergPas
527 / / 03.02.2007
LazySetupCD не справляется? Хм.... Имитация действий пользователя... Так это же практически те же самые действия надо выполнить...
Хотя нет... Вначале необходимо поместить курсор над кнопкой... Но для этого опять таки надо знать Handle кнопки окна приложения, иначе как узнать её расположение на экране? (GetWindowRect). Далее осуществляем щелчок по кнопке... Для этого используем всё тот же Handle и эмулируем действия пользователя, посылая сообщение SendMessage(button,BM_CLICK,0,button)... Это что касается кнопок... Но вернёмся к нашим Edit'ам. В принципе в таких приложениях фокус передаётся Edit'у. Может можно воспользоваться буфером? Копируем в буфер часть серийного номера, вставляем из него в Edit, при этом фокус передастся другому Edit'у, снова копируем в буфер часть серийного номера и вставляем из него... Может быть это и будет решением проблемы? Как считаете?
257
12 марта 2007 года
kosfiz
1.6K / / 18.09.2005
[quote=SergPas]В принципе в таких приложениях фокус передаётся Edit'у. Может можно воспользоваться буфером? Копируем в буфер часть серийного номера, вставляем из него в Edit, при этом фокус передастся другому Edit'у, снова копируем в буфер часть серийного номера и вставляем из него... Может быть это и будет решением проблемы? Как считаете?[/quote]
возможно это решит твою проблему: здесь тебе выбирать реализацию. а про нажатие кнопок могу сказать, что у меня SendMessage с WM_LBUTTONDOWN и WM_LBUTTONUP(и с BM_CLICK) не справлялась с нажатием, но... есть функция SendInput с помощью неё у меня легко получилось нажать на кнопку в инсталляции Delphi. кроме того, с помощью этой функции можно и набивку сомволов осуществить(не пробовал, но должно сработать), т.е. ввод серийника. так что можно сделать так как ты предложил или посмотреть в сторону SendInput(в эту сторону стоит глянуть, если ты еще не знаком с этой функцией: вдруг пригодится).
397
14 марта 2007 года
SergPas
527 / / 03.02.2007
А что это за функция? И где есть справка о ней? Неужели только в MSDN? Вот что-то с Clipboard'ом ни получается... Текст то я скопировал в буфер, а вот вставить из него в требуемый Edit не получается. Для получения Handle'а Edit'а я использовал функцию GetFocus, но она позволяет получить его для текущего приложения. Также пытался использовать функцию EnumChildWindows, но и это не помогло... у меня остаётся только один вариант- это использовать функцию SendInput.
257
14 марта 2007 года
kosfiz
1.6K / / 18.09.2005
ну для начало можно что-нибудь поискать здесь. точнее получить представление об этой функции, посмотреть как её используют. ну а если появятся вопросы то сюда - поможем.
397
18 марта 2007 года
SergPas
527 / / 03.02.2007
Я заменил функцию SendInput на функцию keybd_event. Хотя у ф-ции SendInput больше возможностей, но и keybd_event ничем не хуже. Вообщем мне всё таки удалось ввести текст в Edit. Но возникла новая проблема. На этот раз я никак не могу получить Handle переключателя (радиокнопки). Ф-ция FindWindowEx находит Handle для обычной кнопки, а вот с расширенным её стилем работать не хочет... Вопрос: Как можно получить Handle радиокнопки?
1.9K
18 марта 2007 года
AxXxB
229 / / 21.11.2006
Я, конечно, не мастер в Delphi, но кое-что подсказать смогу. Что если сымитировать нажатие клавиш на клавиатуре? Имитируем нажатие <Tab> и постепенно смещаемся к кнопке, а потом "жмем" <Enter>. Или имитируем нажатие горячих клавиш для кнопки (скажем, <Alt>+<N> - для "Next"). В VB есть функция SendKeys. Может быть, есть аналог в API или в самом Delphi?
397
18 марта 2007 года
SergPas
527 / / 03.02.2007
В WinAPI есть аналог- это либо функция keybd_event, либо функция SendInput. Проблема заключается в том, что не получается симитировать нажатие на переключатель (стрелка "вверх", стрелка "вниз"). Для других, обычных кнопок , этот трюк срабатывает... Но не для переключателей. Поэтому приходится получать Handle радиокнопки и использовать функцию SendMessage... Только так...
397
20 марта 2007 года
SergPas
527 / / 03.02.2007
Ну так что? Никто не знает?
257
20 марта 2007 года
kosfiz
1.6K / / 18.09.2005
[quote=SergPas]Но возникла новая проблема. На этот раз я никак не могу получить Handle переключателя (радиокнопки). Ф-ция FindWindowEx находит Handle для обычной кнопки, а вот с расширенным её стилем работать не хочет...[/quote]
так ты все с InstallShield Wizard Borland Delphi 6 Enterprise Edition работаешь? я щас попробовал с помощью функции EnumChildWindows найти хэндлы переключателей(класс Button вроде) - находит.
397
29 марта 2007 года
SergPas
527 / / 03.02.2007
А каким образом можно узнать, завершило ли приложение свою
работу, ожидает ли действия пользователя и т.д.?
334
29 марта 2007 года
HexEdit
809 / / 27.07.2006
WaitForSingleObjectEx
397
02 апреля 2007 года
SergPas
527 / / 03.02.2007
Обнаружен НОВЫЙ КЛАСС!!! Название ему RichEdit20W!!! Кто-нибудь слышал о таком? Возвращаясь к теме Edit'ов... Почему функции WindowFromPoint и EnumChildWindows работают совершенно по разному? Так, функция WindowFromPoint возвращает название класса "Edit" для Edit'a, для Button'a- "Button"... Функция EnumChildWindows перебирает все контроллеры и нигде не встречается класс "Edit"- вместо всех Edit'ов находит единый класс "RichEdit20W". Число 20 соответсвует общему числу цифробукв, которые нужно ввести во все Edit'ы. Символ "w"-Word... В чём причина такого странного поведения?
257
03 апреля 2007 года
kosfiz
1.6K / / 18.09.2005
[quote=SergPas]находит единый класс "RichEdit20W". Число 20 соответсвует общему числу цифробукв, которые нужно ввести во все Edit'ы. Символ "w"-Word... [/quote]
да нет это не число символов и не word, это вроде юникод(W) версия класса richedit20, 20 - это версия 2.0 - вроде так. вот смотри подробней здесь. вот тебе цитатка:
[quote=]The name of the Rich Edit 1.0 window class is RichEdit. Rich Edit 2.0 has both ANSI and Unicode window classes&#8212;RichEdit20A and RichEdit20W, respectively.[/quote]
[quote=SergPas]Так, функция WindowFromPoint возвращает название класса "Edit" для Edit'a, для Button'a- "Button"... Функция EnumChildWindows перебирает все контроллеры и нигде не встречается класс "Edit"- вместо всех Edit'ов находит единый класс "RichEdit20W".[/quote]
а что Spy++ показывает?
397
03 апреля 2007 года
SergPas
527 / / 03.02.2007
АА... Вот оно что... Spy++ показывает класс "Edit". В это же время
функции WindowFromPoint и EnumChildWindows работают в разнобой...
257
20 апреля 2007 года
kosfiz
1.6K / / 18.09.2005
SergPas
[quote=SergPas]В это же время
функции WindowFromPoint и EnumChildWindows работают в разнобой...[/quote]
время конечно достаточно много прошло, но что за программка, на которой данные функции работают в разнобой?

P.S. любопытно мне.
397
21 апреля 2007 года
SergPas
527 / / 03.02.2007
Тот же самый инсталятор Borland Delphi. Функция WindowFromPoint получает класс Edit, утилита Spy++ получает класс Edit, а вот функция EnumChildWindow среди всех получаемых ей дочерних окон находит класс RichEdit20w. Две функции, предназначенные для получения Handle'а одного и того же дочернего окна дают разные результаты... В чём причина такого поведения я так до сих пор и не выяснил...
257
23 апреля 2007 года
kosfiz
1.6K / / 18.09.2005
взял непосредственно инсталлятор Borland Delphi 7. использовал для установления классов окон и поиска оных: Spy++(6 версии), FSpy(EnumChildWindows), и еще одну утилку собственного написания(WindowFromPoint). все находят и Edit'ы и RichEdit20W там где положено, за одним исключением: Spy++ Edit'ы почему-то не видит. вообще результаты не могут быть разными, т.к. класс окна определяется с помощью функции GetClassName и в случае с WindowFromPoint и в случае с EnumChildWindows, так что можно сделать вывод что результат разный так как видимо функции GetClassName переданы разные хэндлы.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог