![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
прочесть что написано в Label другого приложния [D7, WinXP]
ivanoff © (2009-08-25 16:06:00)получаю так
SendMessage(H, WM_GETTEXT, 256, LParam(@S[1]));
... но только с Edit, Button, Panel, ...
как посмотреть что в Label написано, по его координатам
AntiZOG (2009-09-15 02:12:00) [1]
> ivanoff (25.08.09 16:06)
>
> получаю так
>
> SendMessage(H, WM_GETTEXT, 256, LParam(@S[1]));
>
> ... но только с Edit, Button, Panel, ...
> как посмотреть что в Label написано, по его координатам
Самый простой и чаще всего работающий способ:
- WmPrint окна на котором лежит label, b в качестве канваса указать битмап.
- потом распознать каким-то простым алгоритмом (можно даже тупо наложением изображений букв).
Сергей М. (2009-09-09 13:24:00) [2]
> допустим, будет у нас в чужом процессе дополнительный поток
Зачем дополнительный ?
Прямо в основном и обращаемся.
И крышки тут ни причем.
rrader (2009-09-09 13:10:00) [3]Ну, допустим, будет у нас в чужом процессе дополнительный поток, работающий напрямую с VCL-объектом. ReadProcessMemory заменяем, образно, говоря, на крышки (^), т.е. получаем доступ к данным напрямую, как в своем процессе. Проблем синхронизации это не решает. Или имеется в виду другой подход?
Сергей М. (2009-09-09 12:44:00) [4]
> в некоторых случаях это - вариант
Для этих "некоторых" случаев проще и удобней будет не лезть в дебри RTTI: опять же внедрить свой код, но не для перехвата WinAPI-вызовов, а работающий напрямую с VCL-объектами в процессе-"жертве".
rrader (2009-09-09 11:18:00) [5]> И что толку ?
Скажем так, в некоторых случаях это - вариант. Возвращаясь к теме, я хотел указать именно на получение текста из неменяющегося TLabel.
Сергей М. (2009-09-09 10:31:00) [6]Модификация данных типа string неотносится к атомарным операциям
> предлагаю на время чтения останавливать обновление
И что толку ?
Все равно это чревато как минимум недостоверным результатом, а как максимум - отказом ReadProcessMemory.
rrader (2009-09-09 09:53:00) [7]Не знаю почему, но у меня из головы вылетело, что нереентерабельность VCL может испортить чтение данных из чужого процесса, когда данные меняются. Потому что чтение осуществляется два раза (длина и сама строка), а нас могут вытеснить в любой момент. Я предлагаю на время чтения останавливать обновление данных (способ индивидуален в каждом конкретном случае, но не имеется в виду делать SuspendThread) и после чтения возобновлять.
Сергей М. (2009-09-09 08:31:00) [8]
> А что плохого?
Плохое в том, что модификация данных типа string относится к атомарным операциям.
rrader (2009-09-09 04:27:00) [9]>Структура RTTI отличается от версии к версии.
Со времен D3 до D2010 ничего того, что помешало бы получению данных, не изменилось. Иначе бы я и заикаться не стал на эту тему.
>Что если требуется отслеживать изменения текста контрола ?
>На таймер что ли ставить ReadProcessMemory ?
А что плохого? Это очень быстро.
Сергей М. (2009-09-08 20:20:00) [10]
> достаточно воспользоваться мощью RTTI
Структура RTTI отличается от версии к версии.
Это раз.
Что если требуется отслеживать изменения текста контрола ?
На таймер что ли ставить ReadProcessMemory ?
Это два.
rrader (2009-09-08 12:15:00) [11]Чтобы вытащить текст из TLabel, не нужно внедряться и ставить хуки для перехвата, достаточно воспользоваться мощью RTTI. Нужно знать имя (или другой уникальный параметр) метки в коде (можно подсмотреть в DFM), чтобы отфильтровать ее от других. А дальше ReadProcessMemory... Я таким образом вытягиваю информацию из TStringGrid.
Сергей М. (2009-08-27 20:59:00) [12]
> как из DLL послать текст в мое приложение?
Один из множества возможных вариантов:
http://www.google.ru/search?hl=ru&client=firefox&rls=org.mozilla%3Aru%3Aofficial&hs=s2N&newwindow=1&q=delphi+wm_copydata&btnG=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA&lr=&aq=f&oq=
ivanoff (2009-08-27 20:53:00) [13]
> А как же иначе, если это уже стало печальной традицией ?
я хочу научится с этим работать, понять (понятно что на конкретном примере легче) а не просто решить вознишую проблему и забить
нашел кучу примеров посылки сообсчении из DLL но не втом виде как мне нужно
и еще
CallNextHookEx(0, Code, wParam, lparam);
первый параметр не должен быть идетифицатором Hook-а?
> Из [5] тебе нужен только перехват WinAPI-вызовов, о котором
> идет речь в [17] п.4
>
> Все остальное в [5] - абсолютно бесполезный хлам.
> Нет никакого резона приспосабливать его к твоей задаче.
как говорил с самого начала в первые приходится иметь дело с DLL
...для начала хочу добится нужного результата а потом буду ненужное убирать потому как не знаю что там нужное и что не нужное.
Начал там коментировать как мне казалось ненужное - перестало работать
Вот и решил для начала принять бы Техт в мое приложение а далее ...
----------
как из DLL послать текст в мое приложение?
Сергей М. (2009-08-27 20:35:00) [14]
> ну зачем же так сурово
А как же иначе, если это уже стало печальной традицией ?
> сделал так (на базе [5])
Из [5] тебе нужен только перехват WinAPI-вызовов, о котором идет речь в [17] п.4
Все остальное в [5] - абсолютно бесполезный хлам.
Нет никакого резона приспосабливать его к твоей задаче.
ivanoff (2009-08-27 19:52:00) [15]
> Сергей М. © (26.08.09 21:00) [19]
> Сейчас последует "Вы, ...., не умничайте - вы код давайте
> !!"
ну зачем же так сурово ...
... если не трудно ... код дайте :)
... Спасибо
а если серъезно
сделал так (на базе [5])
...
type
TWM_TextCapture = record
Text: PAnsiChar;
end;
const
WM_TextCapture = WM_USER + 1;
var
processWnd: HWND;
WMTextCapture: TWM_TextCapture;
...
procedure GetWndText(Wnd, SourceWnd: HWND); stdcall; export;
...
processWmd := SourceWnd;
...
добавил в для проверки
function MessageProc(code: integer; wParam: word;
lParam: longint): longint; stdcall;
...
WMTextCapture.Text := TimeToStr(Time);
SendMessage(processWnd, WM_TextCapture, 0, 0);
...
-----------------------------------------------------------
в тестовой программе ловлю так
...//так сообщение принимаю - ОК
private
procedure WMTextCapture(var Msg: TWM_TextCapture); message WM_TextCapture;
...
procedure GetWndText(Wnd, SourceWnd: HWND); stdcall; external 'TxCapture.dll';
...
procedure TForm1.prWMsd(var Msg: TWM_TextCapture);
begin
Label1.Caption := TimeToStr(Time);
Label1.Caption := Msg.Text;//Так - Error
end;
где ошибаюсь?
как из DLL послать текст в мое приложение :(
Сергей М. (2009-08-26 21:00:00) [16]Сейчас последует "Вы, ...., не умничайте - вы код давайте !!"
Rouse_ (2009-08-26 17:53:00) [17]
> так как тока разбираюсь с DLL не пойму че не так испаравил
> дабы по [5] техт получить а не рисовать сверху
Ну во первых заменить wParam: word; на правильное значение, во вторых убрать ненуный слип, втретьих убрать мемлик GDI ресурсов, разрушая в нужное время dtc, , в четвертых начать таки возвращать в MessageProc правильный результат, а не ноль, ну и заменить процедуры отрисовки
dtc.Rectangle(300, 3, 900, 20);
dtc.TextOut(305, 5, Copy(Str, 0, Count));
На отправку строки Str своему приложению
Сергей М. (2009-08-26 17:32:00) [18]Отсюда следует, что следует ставить локальныйхук в процесс, создавший этот лейбл.
> не заню с какой стороны подойти
У тебя есть заголовок окна, в котором отрисовывается искомый лейбл.
Для простоты положим, что текст этого заголовка уникален среди заголовков всех окон тек.десктопа.
1. Ищешь хэндл окна по заданному заголовку.
2. Получаешь ID треда, создавшего окно - см. GetWindowThreadProcessId
3. Устанавливаешь локальный(!!!) хук на этот тред - см. SetWindowsHookEx, тип хука выбираешь, например, WH_GETMESSAGE
4. Посылаешь окну сообщение WM_NULL - см. PostMessage()
При этом в АП целевого процесса будет внедрена DLL, указанная в п.3
В процедуре инициализации этой DLL перехватываешь ф-цию TexOut (до кучи и все прочие, выводящие текст, фигурирующие в [5])
5. В теле подмененных ф-ций извещаешь любым удобным способом (например, SendMessage) свойпроцесс о том, что целевой процесс для вывода некоего текста вызвал такую-то перехваченную тобой ф-цию с такими-то параметрами, в частности с параметрами-координатами, с которыми выводится текст. Остается только сравнить координаты с теми, в которых расположен искомый лейбл - и все, задача решена.
ivanoff (2009-08-26 16:28:00) [19]
> Дельфийская ? Ты уверен в этом ? Ты уверен что это именно
> TLabel
CBuilder
> "всеравно"
важно получить инфу с Label-а конкретного окна (от которого знаю заголовок) который находится на панелке (Panel), как - не важно главное чтоб правельно
...не заню с какой стороны подойти, вот и кидаюсь из стороны в сторону и мучаю всех вопросами
Сергей М. (2009-08-26 15:44:00) [20]
> ivanoff (26.08.09 14:52) [14]
>
> есть прога
Дельфийская ? Ты уверен в этом ? Ты уверен что это именно TLabel, а не какой-либо иного класса контрол ?
> мне всеравно как лишь бы данные из Label получить
Пример, который ты мусолишь, устанавливает хук во всеGUI-процессы.
Не исключено (и оч даже вероятно), что среди этих процессов может оказаться более чем один процесс с контролом интересующего класса.
И тут к тебе возникает вопрос: как ты намерен идентифицировать нужный тебе процесс, если ты установилл глоб.хук, поскольку тебе "всеравно" ?