Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   [решено] *Решено* | *Delphi* | Работа с чужими окнами (http://forum.oszone.net/showthread.php?t=55812)

Admiral 28-10-2005 19:45 368539

*Решено* | *Delphi* | Работа с чужими окнами
 
Доброе время суток знатоки Делфи.

Как записать значение переменной (String, Integer, etc)
в поле ввода данных, НО другой программы (чужого окна) если известен ХЕНДЛ (который найден с помощью FindWindow)?

Пишу на Делфи 6-й версии.

Заранее спасибо за ответ.

DillerInc 29-10-2005 13:01 368682

Admiral
Если поле ввода данных - это объект класса TEdit,то,к примеру,для начала можно сделать так:
Код:

var
 SearchedWnd : HWND;
 EDITCtrl : HWND;
begin
 SearchedWnd := FindWindow(nil, 'Заголовок искомого окна');
 EDITCtrl := FindWindowEx(SearchedWnd, 0, 'EDIT', nil);
end;

...тут мы пытаемся найти дескриптор(хендл) нужного нам поля ввода данных.
Последний параметр функции FindWindowEx - это имя искомого элемента.У меня он указан как nil,т.к. я не думаю,что имя этого элемента будет известно.Следовательно может возникнуть затруднительная ситуация,если на искомом окне будет расположено несколько подобных объектов класса TEdit...
Ну,и,в конце концов,устанавливаем в окне(поле ввода данных) свой текст:
Код:

SendMessage(EDITCtrl, WM_SETTEXT, 0, lParam('Наш текст,который мы хотим вставить в поле ввода данных'));
Подходит такой вариант?

Admiral 03-11-2005 18:13 370148

Спасибо за ответ DillerInc.
Цитата:

Код:
SendMessage(EDITCtrl, WM_SETTEXT, 0, lParam('Наш текст,который мы хотим вставить в поле ввода данных'));
Подходит такой вариант?
Код немного не верен (судя из ругательств Делфи и хелпа) второй параметр это сообщение, а вот 3 и 4 уже Nil.
Но даже так требуется второй параметр типа Cardinal, а это продлённый (в положительную область) всё тот же Integer. Эта функцию посылает СИСТЕМНЫЕ команды, а не какой то текст, что программист захотел.

DillerInc, а у тебя удавалось в чужое окно программы отправить сообщение (ну или хотя бы символ что ли)?

DillerInc 03-11-2005 19:39 370173

Admiral
Цитата:

Код немного не верен
...если ты про функцию SendMessage,то,по-моему,ты мне мозги пудришь ;) .
Посмотри на MSDN(я указал тебе ссылку).
Цитата:

а у тебя удавалось в чужое окно программы отправить сообщение (ну или хотя бы символ что ли)?
...если хочешь я могу запросто привести код,который меняет заголовок чужого окна.

P.S. Да,кстати,что Delphi то пишет?


Admiral 03-11-2005 20:41 370186

Алгоритм
Есть поле ввода пароля. Я из файла словаря вытаскиваю по слову и отправляю туда и жму ЕНТЕР и всё это программно.


К чему это?
А подбираю я пароли к mcd файлу. Это файл от мат пакета МатКад. http://www.mathsoft.com/

Немного не традиционный способ подбора пароля (умные люди посоветовали бы искать пароль в самом mcd посредством HEX кодов).
Или мож кто знает где эту прогу скачать (а она точно существует как и другие проги которые подбирают пароли к архивам, Ворд файлам и прочие).

Спасибо за внимание.

Admiral 06-11-2005 20:51 370857

DillerInc
Я проверел подробно почему сообщения не идут.
EDITCtrl := FindWindowEx(SearchedWnd, 0, 'EDIT', nil);
Не находит поля ввода.

А переименовать окно ето просто
SetWindowText(SearchedWnd, 'Новое название')
Для етого даже SendMessage не надо использовать.

P.S
Окно само находит и делает его активным SetForegroundWindow(SearchedWnd);
но строку ввода не находит, EDITCtrl
а по пустому хендлу много не отправиш SendMessage(EDITCtrl, WM_SETTEXT, 0, lParam('Текст');
Есть какието соображения.

hasherfrog 07-11-2005 10:12 370980

Admiral
Может, посмотрите на это окошко каким-нибудь Microsoft Spy++ (из комплекта visual studio)? Там ведь все хендлы дочерний контролов видно, ЕМНИП. А значит, Вы можете их получить. Хотя бы (первым в голову приходит) по номеру, типа "второй дочерний контрол в окне"?

DillerInc 07-11-2005 17:42 371199

Admiral
Да,в самом деле эта функция FindWindowEx ничего не находит,и я не могу понять,почему...
С другой стороны,можно использовать следующий код:
Код:

// CallBack-функция,используемая функцией EnumChildWindows
function ChildWndProc(h : HWND) : BOOL; stdcall;
begin
 SendMessage(h, WM_SETTEXT, 0, lParam(LPCTSTR('Текст,который надо поместить')));
 Result := True;
end;

var
 SearchedWnd : HWND;
begin
 SearchedWnd := FindWindow(nil, 'Заголовок искомого окна');
 EnumChildWindows(SearchedWnd, @ChildWndProc, 0);
end;

Код работает(читай: заголовки дочерних окон меняются),но изменяет абсолютно все дочерние окна окна-родителя.Нам необходимо как-то выделить то окно,которое нас конкретно интересует :huh: .

Хотя возможно,что можно сделать всё это как-то иначе и проще...

Admiral 08-11-2005 02:07 371358

СПАСИБО.
Выручили.

Что получилось

var
UnPro : HWND;
PassText: HWND;
OKbutton: HWND;

begin
UnPro:= FindWindow(nil, 'Unprotect Worksheet'); //Где меню с вводом пароля
PassText := FindWindowEx(UnPro, 0, 'Edit', nil); // Где само поле на этом меню

//Тут будет цикл и он будет зависеть от количества паролей
SendMessage(PassText, WM_SETTEXT, 0, lParam(LPCTSTR('НАШ ПАРОЛЬ'))); //Пихаем пароль
OKbutton :=FindWindowEx(UnPro, 0, 'Button', nil); //Ищем сокровенную OK
SendMessage(OKbutton, BM_CLICK, 0, 0); //Жмёт ОК принять пароль (кстати если пароль подойдёт то значение этой функции и будет обрабатываться как выход из цикла)
end;

Ну а если неправильно, то форма с этим алгоритмом повиснет, так как МАТКАД видал MSGBOX (Incorrect password…) который и прерывает дальнейший алгоритм (а дальше я планировал глушить этот ответ и продолжения цикла).
Что б повисания не было (вернее что б оно было кратковременным, а не бесконечным), создадим отдельную программу которая и глушит этот MSGBOX.

procedure TForm1.Timer1Timer(Sender: TObject);
var
BadPass :HWND;
begin
BadPass :=FindWindow(nil, 'Mathcad'); //Имя MSGBOX – Mathcad. Находим это табло
SendMessage(BadPass, WM_SYSCOMMAND, SC_CLOSE, 0); //Просим его закрыться
end;

Інтервал у таймера 1000мс. Если сделать слишком маленьким, то всё начнёт дико тормозить ну, а большой интервал нагрузит и без того длинный алгоритм.

Что натолкнуло меня на мысль
hasherfrog
использования Spy++ позволило проверять себя на каждом шаге программирования.

DillerInc
в твоём ответе за 14:01, 29-10-2005 было уже всё, искать Едит надо было в окне не самой проги, а в окне, где сам Едит находится (Spy++ указал на это). Кстати мне повезло что кнопка ОК первая, и поэтому твоё предостережение, что кому именно отправится сообщения не коснулось меня(у тебя всем окнам, а у меня могло всем кнопкам; я искал хендл по Button, а (их там двое – OK Cancel см рис за 21:41, 03-11-2005 ) и Делфи выбирался хендл первого). FindWindowEx находит!

P.S
Алгоритм готов, осталось сделать перебор по словарю, и определения правильного слова – конца цикла. И переборщих готов. (Прим – но лучше найти взломщик mcd ибо эти Ding.wav от msgbox…, хотя их можно отключить через звуковую схему, но все равно ефективность алгоритма от этого не сильно выиграет ).


Время: 13:06.

Время: 13:06.
© OSzone.net 2001-