Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 2 068

/ вопрос открыт /

Здравствуйте ,уважаемые эксперты !
Есть некое приложение A, реализующее определенную функцию.
Требуется написать приложение B, которое бы записало бы что-нибудь в Edit1 приложения A,"нажало" бы Button1 и прочитало бы из окна Edit2 того же приложения А.
В форумах для "чайников" я узнал, что все это делается через дескрипторы окон. Даже первый успех имею : получил дескриптор открытого окна ( некое число - ни уму, ни сердцу ).А вот дальше продвинуться - никак : как добраться в этом окне до дочерних окон (Edit, Button) и как с ними общаться. Получил чрезвычайно ценный совет "Читай MSDN Library", да толку-то...
Вспоминается овечий муж и новые ворота :-( А пару строк кода им кинуть лениво. Здесь надеюсь на отклик.

Яуген Таляныч Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Яуген Таляныч (статус: Посетитель)
Вопрос отправлен: 9 ноября 2008, 09:40
Состояние вопроса: открыт, ответов: 2.

Ответ #1. Отвечает эксперт: Вадим К

Здравствуйте, Гена Гутницкий!
Если вы научились получать хендл с помощью пары функций FindWindow/FindWindowEx, то получить текст будет несложно. Например этой функцией

function GetText(WindowHandle: hwnd): string;
var
  txtLength: integer;
  buffer: string;
begin
  TxtLength := SendMessage(WindowHandle, WM_GETTEXTLENGTH, 0, 0);
  txtlength := txtlength + 1;
  setlength(buffer, txtlength);
  sendmessage(WindowHandle, wm_gettext, txtlength, longint(@buffer[1]));
  result := buffer;
end;
Предупреждаю, что некоторые окна сопротивляются получению текста и/или могут обрабатывать его самостоятельно в своих целях.

Для установки текста можно использовать сообщение WM_SETTEXT или функцию SetDlgItemText(Dlg: HWnd; IDDlgItem: Integer; Str: PChar);
Как это сделать оставляю в виде домашнего задания, для подсказки оставлю строку
SendMessage(AHandle, WM_SETTEXT, 0, Integer(PChar(S)));

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 9 ноября 2008, 17:17

Ответ #2. Отвечает эксперт: Feniks

Здравствуйте, Гена Гутницкий!
Что-то похожее уже спрашивали... Почитайте Вопросы вопрос #1861, вопрос #1813.
А в приложении смотрите пример для нажатия Кнопки. Возможно он вас наталкнет на хорошие мысли ;-)

P.S. Жалею удачи.

Приложение:
  1. function PressAbortAndReloadBtn: string;
  2. var
  3. MenuHnd: THandle;
  4.  
  5. ItemUint: UINT;
  6.  
  7. BtnHnd: THandle;
  8. begin
  9. result := PRX_UNKNOWN_ERR;
  10. GetProcList;
  11. if Prx_MainWHnd <> 0 then
  12. begin
  13. BtnHnd := FindWindowEx(Prx_MainWHnd, 0, nil, PChar(PrxABtnName));
  14. SendMessage(BtnHnd, BM_CLICK, 0, 0);
  15. Sleep(100);
  16. MenuHnd := GetMenu(Prx_MainWHnd);
  17. if Menuhnd <> 0 then
  18. begin
  19. ItemUint := GetMenuItemID(Menuhnd, 4);
  20. if ItemUint <> 0 then
  21. begin
  22. SendMessage(Prx_MainWHnd, WM_COMMAND, ItemUint, 0);
  23. result := PRX_OK;
  24. end
  25. else
  26. result := PRX_ITEM_NOT_FOUND;
  27. end
  28. else
  29. result := PRX_MENU_NOT_FOUND;
  30. end
  31. else
  32. result := PRX_NOT_FOUND;
  33. if result <> PRX_OK then
  34. WriteLog(result);
  35. end;
  36.  
  37.  
  38.  
  39. procedure ClickOnForm(wnd: HWND; caption: string);
  40. var
  41. TheChildHandle: HWND;
  42. begin
  43. TheChildHandle := FindWindowEx(wnd, 0, nil, PChar(caption));
  44. SendMessage(TheChildHandle, WM_LButtonDown, 1, 1);
  45. SendMessage(TheChildHandle, WM_LButtonUP, 1, 1);
  46. end;
  47.  
  48. procedure TForm1.Button4Click(Sender: TObject);
  49. var
  50. wnd: HWND;
  51. caption: string;
  52. begin
  53. wnd := GetTopWindow(0);
  54. repeat
  55. SetLength(caption, GetWindowtextLength(wnd));
  56. GetWindowText(wnd, @caption[1], length(caption) + 1);
  57.  
  58. if (trim(caption) = 'Form caption') then
  59. ClickOnForm(wnd, 'Button name');
  60. wnd := GetNextWindow(wnd, GW_HWNDNEXT);
  61. until wnd = 0;
  62. end;


Ответ отправил: Feniks (статус: Бакалавр)
Время отправки: 14 ноября 2008, 12:11


Мини-форум вопроса

Всего сообщений: 5; последнее сообщение — 12 ноября 2008, 17:04; участников в обсуждении: 3.
Яуген Таляныч

Яуген Таляныч (статус: Посетитель), 9 ноября 2008, 18:18 [#1]:

Спасибо, почти понял. Непонятно только, почему во втором случае адрес integer, в первом - longint, хотя в обоих случаях это указатель на строку ( сегментный регистр - смещение) .
Что касается моего умения получать HWND, то оно немножко переоценено : я получаю только дескриптор окна приложения, а вот "углубиться" в него и получить дескрипторы дочерних окон - так ни статьи типа "подсматриваем в чужие окна", ни книжка "Delphi. Трюки и эффекты" ответа не дали. Книжка эта рассчитана на опытного программера, а не чайнико-дельфиста, как я. И еще непонятно, как имитировать нажатие кнопки. Но оптимизма не теряю :-)
Вадим К

Вадим К (статус: Академик), 9 ноября 2008, 18:47 [#2]:

Под 32 битной платформой нет "сегментный регистр - смещение". Точнее оно есть, 16 бит сегмент, 32 - смещение. Но обычному приложению это не нужно, да и сама операционка без надобности не даст приложению управлять этим.
Поэтому обычно говорят, что память плоская.
А то, что то integer, то longint - нет особой разницы (пока, пока делфи компилирует в 32битный код) всё равно это будет 4 байта.
Галочка "подтверждения прочтения" - вселенское зло.
Яуген Таляныч

Яуген Таляныч (статус: Посетитель), 11 ноября 2008, 09:31 [#3]:

С этим ясно. Остался вопрос с дочерними окнами и нажатием кнопки.
Странно, что Help ничего не знает про FindWindow, поэтому так и не смог выяснить разницу между FindWindow и FindWindowEx.
Паровоз

Паровоз (статус: 10-ый класс), 12 ноября 2008, 16:46 [#4]:

"Странно, что Help ничего не знает про FindWindow"
В меню Help есть подменю Windows SDK
Вадим К

Вадим К (статус: Академик), 12 ноября 2008, 17:04 [#5]:

>разницу между FindWindow и FindWindowEx.
Вторая функция ищет в списке окон определённого родителя, хендл которого можно задать. Первая - в окнах верхнего уровня.
Галочка "подтверждения прочтения" - вселенское зло.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:32
Выполнено за 0.03 сек.