|
Вопрос # 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. Жалею удачи.
Приложение: Переключить в обычный режим- function PressAbortAndReloadBtn: string;
- var
- MenuHnd: THandle;
-
- ItemUint: UINT;
-
- BtnHnd: THandle;
- begin
- result := PRX_UNKNOWN_ERR;
- GetProcList;
- if Prx_MainWHnd <> 0 then
- begin
- BtnHnd := FindWindowEx(Prx_MainWHnd, 0, nil, PChar(PrxABtnName));
- SendMessage(BtnHnd, BM_CLICK, 0, 0);
- Sleep(100);
- MenuHnd := GetMenu(Prx_MainWHnd);
- if Menuhnd <> 0 then
- begin
- ItemUint := GetMenuItemID(Menuhnd, 4);
- if ItemUint <> 0 then
- begin
- SendMessage(Prx_MainWHnd, WM_COMMAND, ItemUint, 0);
- result := PRX_OK;
- end
- else
- result := PRX_ITEM_NOT_FOUND;
- end
- else
- result := PRX_MENU_NOT_FOUND;
- end
- else
- result := PRX_NOT_FOUND;
- if result <> PRX_OK then
- WriteLog(result);
- end;
-
-
-
- procedure ClickOnForm(wnd: HWND; caption: string);
- var
- TheChildHandle: HWND;
- begin
- TheChildHandle := FindWindowEx(wnd, 0, nil, PChar(caption));
- SendMessage(TheChildHandle, WM_LButtonDown, 1, 1);
- SendMessage(TheChildHandle, WM_LButtonUP, 1, 1);
- end;
-
- procedure TForm1.Button4Click(Sender: TObject);
- var
- wnd: HWND;
- caption: string;
- begin
- wnd := GetTopWindow(0);
- repeat
- SetLength(caption, GetWindowtextLength(wnd));
- GetWindowText(wnd, @caption[1], length(caption) + 1);
-
- if (trim(caption) = 'Form caption') then
- ClickOnForm(wnd, 'Button name');
- wnd := GetNextWindow(wnd, GW_HWNDNEXT);
- until wnd = 0;
- 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.
Вторая функция ищет в списке окон определённого родителя, хендл которого можно задать. Первая - в окнах верхнего уровня.
Галочка "подтверждения прочтения" - вселенское зло.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|