-
получаю так SendMessage(H, WM_GETTEXT, 256, LParam(@S[1])); ... но только с Edit, Button, Panel, ... как посмотреть что в Label написано, по его координатам
-
лабел не оконный, так что остается только ocr
-
> остается только ocr
Или внедрить туда свой код, перехватывающий TextOut()
-
> Сергей М. © (25.08.09 16:48) [2]
уже легче :)
.... можно по подробней?
-
-
-
вроде то, даже обрадовался переделал так function MyGetWndText(Wnd: HWND): PChar; stdcall; export;
var
Point: TPoint;
Buffer: array[0..256] of char;
begin
GlobalData^.Wnd := Wnd;
GlobalData^.cancapture := True;
Point:= Mouse.CursorPos;
Windows.ScreenToClient(Wnd, Point);
if (Point.x < 0) or (Point.y < 0) then
GetWindowText(Wnd, Buffer, SizeOf(Buffer) - 1);
Result := Buffer;
end;
...
exports
MyGetWndText name 'MyGetWndText';
...
вызываю так
...
function MyGetWndText(Wnd: HWND): PChar; stdcall; external 'TextCapture.dll';
...
var
Wnd: HWND;
begin
Wnd := WindowFromPoint(Mouse.CursorPos);
Label1.Caption := MyGetWndText(Wnd);
end; чтоб функция техт возвращала компилятор ругается, ОС плясать начинает Access violation at address 099CCCBE in module 'TextCapture.dll'. Read of address 00000000.просьба ткнуть носом - с dll полный профан я
-
> ivanoff (26.08.09 04:13) [6]
> вроде то, даже обрадовался
Откуда это? По ссылке [5]? :(
Во-первых, GetWindowText работает с окнами, TLabel окна не имеет. Во-вторых, PChar должен указывать на буфер, распределенный в приложении, например, buf: array [0..255] of Char. И, в-третьих, при таких базовых знаниях можно смело полагать, что получить текст из чужого TLabel невозможно.
-- Regards, LVT.
-
Sleep(INFINITE) - это сильно.
-
> Сергей М. © (26.08.09 09:17) [8]
> Sleep(INFINITE) - это сильно.
Поэзия :)
Это тоже из [5]?
-- Regards, LVT.
-
> Это тоже из [5]?
Угу. Шедевр) Заглянул из любопытства, а там .. Черт ногу сломит как там понахреноверчено ..
-
> > вроде то, даже обрадовался > > Откуда это? По ссылке [5]? :( > > Во-первых, GetWindowText работает с окнами, TLabel окна > не имеет.
а ведь Label-то видит - вот и обрадовался, есть от чего плясать, тока там много всего разбираюсь чего надо, чего не надо .... но как говорил с DLL не работал
- а я и не говорил что в этой области знания у меня большие - чтаю, просвесщаюсь, но пока недопер - вот и прошу чтоб нормальным а не литературным языком объяснили в чем трабл или как правельно делать надо
-
> ivanoff (26.08.09 13:22) [11]
> а ведь Label-то видит
Значит, это не TLabel, а TStaticText. Класс окна выяснял?
Ну, или там не GetWindowText. Хотя, исходный образчик, судя по всему, для дела не пригоден.
> не литературным языком объяснили в чем трабл
Нелитературным нельзя, забанят.
> или как правельно делать надо
Конкретно спрашивай, что осталось непонятым.
-- Regards, LVT.
-
> а ведь Label-то видит
Что значит "видит" ? Прошу чтоб нормальным а не литературным языком объяснили)
И еще прошу, чтоб нормальным а не литературным языком объяснили, зачем тут нужен глобальный хук, если известен конкретный процесс и конкретное окно с конкретным лейблом)
-
есть прога которая принимает некоторые данные от своей серверной части в зашифрованном виде и визуализирует посредством Label
задача получить и использовать инфу которую ставят в те самые Label
"они" не хотят делится этой инфой поэтому надо выдергиватить из их проги
> зачем тут нужен глобальный хук, если известен конкретный > процесс и конкретное окно с конкретным лейблом)
а мне всеравно как лишь бы данные из Label получить
> Что значит "видит" ?
я сделал тестовую программу положил там Label ... так как брал текст из TEdit, к примеру из TLabel не берет ... с примером из [5] - берет
> Конкретно спрашивай, что осталось непонятым.
так как тока разбираюсь с DLL не пойму че не так испаравил дабы по [5] техт получить а не рисовать сверху
цитата из нета "Выдрать текст из Label'a можно, но для этого придется перехватывать TextOutW, так как это так сказать последняя инстанция, когда текст ещё существует в своем состоянии текста"
-
> ivanoff (26.08.09 14:52) [14] > > есть прога
Дельфийская ? Ты уверен в этом ? Ты уверен что это именно TLabel, а не какой-либо иного класса контрол ?
> мне всеравно как лишь бы данные из Label получить
Пример, который ты мусолишь, устанавливает хук во все GUI-процессы. Не исключено (и оч даже вероятно), что среди этих процессов может оказаться более чем один процесс с контролом интересующего класса. И тут к тебе возникает вопрос: как ты намерен идентифицировать нужный тебе процесс, если ты установилл глоб.хук, поскольку тебе "всеравно" ?
-
> Дельфийская ? Ты уверен в этом ? Ты уверен что это именно > TLabel
CBuilder
> "всеравно"
важно получить инфу с Label-а конкретного окна (от которого знаю заголовок) который находится на панелке (Panel), как - не важно главное чтоб правельно
...не заню с какой стороны подойти, вот и кидаюсь из стороны в сторону и мучаю всех вопросами
-
Отсюда следует, что следует ставить локальный хук в процесс, создавший этот лейбл.
> не заню с какой стороны подойти
У тебя есть заголовок окна, в котором отрисовывается искомый лейбл. Для простоты положим, что текст этого заголовка уникален среди заголовков всех окон тек.десктопа. 1. Ищешь хэндл окна по заданному заголовку. 2. Получаешь ID треда, создавшего окно - см. GetWindowThreadProcessId 3. Устанавливаешь локальный (!!!) хук на этот тред - см. SetWindowsHookEx, тип хука выбираешь, например, WH_GETMESSAGE 4. Посылаешь окну сообщение WM_NULL - см. PostMessage() При этом в АП целевого процесса будет внедрена DLL, указанная в п.3 В процедуре инициализации этой DLL перехватываешь ф-цию TexOut (до кучи и все прочие, выводящие текст, фигурирующие в [5]) 5. В теле подмененных ф-ций извещаешь любым удобным способом (например, SendMessage) свой процесс о том, что целевой процесс для вывода некоего текста вызвал такую-то перехваченную тобой ф-цию с такими-то параметрами, в частности с параметрами-координатами, с которыми выводится текст. Остается только сравнить координаты с теми, в которых расположен искомый лейбл - и все, задача решена.
-
> так как тока разбираюсь с DLL не пойму че не так испаравил > дабы по [5] техт получить а не рисовать сверху
Ну во первых заменить wParam: word; на правильное значение, во вторых убрать ненуный слип, втретьих убрать мемлик GDI ресурсов, разрушая в нужное время dtc, , в четвертых начать таки возвращать в MessageProc правильный результат, а не ноль, ну и заменить процедуры отрисовки dtc.Rectangle(300, 3, 900, 20);
dtc.TextOut(305, 5, Copy(Str, 0, Count)); На отправку строки Str своему приложению
-
Сейчас последует "Вы, ...., не умничайте - вы код давайте !!"
-
> Сергей М. © (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 послать текст в мое приложение :(
-
> ну зачем же так сурово
А как же иначе, если это уже стало печальной традицией ?
> сделал так (на базе [5])
Из [5] тебе нужен только перехват WinAPI-вызовов, о котором идет речь в [17] п.4
Все остальное в [5] - абсолютно бесполезный хлам. Нет никакого резона приспосабливать его к твоей задаче.
-
> А как же иначе, если это уже стало печальной традицией ?
я хочу научится с этим работать, понять (понятно что на конкретном примере легче) а не просто решить вознишую проблему и забить
нашел кучу примеров посылки сообсчении из DLL но не втом виде как мне нужно
и еще CallNextHookEx(0, Code, wParam, lparam);
первый параметр не должен быть идетифицатором Hook-а?
> Из [5] тебе нужен только перехват WinAPI-вызовов, о котором > идет речь в [17] п.4 > > Все остальное в [5] - абсолютно бесполезный хлам. > Нет никакого резона приспосабливать его к твоей задаче.
как говорил с самого начала в первые приходится иметь дело с DLL
...для начала хочу добится нужного результата а потом буду ненужное убирать потому как не знаю что там нужное и что не нужное. Начал там коментировать как мне казалось ненужное - перестало работать
Вот и решил для начала принять бы Техт в мое приложение а далее ...
---------- как из DLL послать текст в мое приложение?
-
-
Чтобы вытащить текст из TLabel, не нужно внедряться и ставить хуки для перехвата, достаточно воспользоваться мощью RTTI. Нужно знать имя (или другой уникальный параметр) метки в коде (можно подсмотреть в DFM), чтобы отфильтровать ее от других. А дальше ReadProcessMemory... Я таким образом вытягиваю информацию из TStringGrid.
-
> достаточно воспользоваться мощью RTTI
Структура RTTI отличается от версии к версии. Это раз.
Что если требуется отслеживать изменения текста контрола ? На таймер что ли ставить ReadProcessMemory ? Это два.
-
>Структура RTTI отличается от версии к версии.
Со времен D3 до D2010 ничего того, что помешало бы получению данных, не изменилось. Иначе бы я и заикаться не стал на эту тему.
>Что если требуется отслеживать изменения текста контрола ? >На таймер что ли ставить ReadProcessMemory ?
А что плохого? Это очень быстро.
-
> А что плохого?
Плохое в том, что модификация данных типа string относится к атомарным операциям.
-
Не знаю почему, но у меня из головы вылетело, что нереентерабельность VCL может испортить чтение данных из чужого процесса, когда данные меняются. Потому что чтение осуществляется два раза (длина и сама строка), а нас могут вытеснить в любой момент. Я предлагаю на время чтения останавливать обновление данных (способ индивидуален в каждом конкретном случае, но не имеется в виду делать SuspendThread) и после чтения возобновлять.
-
Модификация данных типа string не относится к атомарным операциям
> предлагаю на время чтения останавливать обновление
И что толку ? Все равно это чревато как минимум недостоверным результатом, а как максимум - отказом ReadProcessMemory.
-
> И что толку ?
Скажем так, в некоторых случаях это - вариант. Возвращаясь к теме, я хотел указать именно на получение текста из неменяющегося TLabel.
-
> в некоторых случаях это - вариант
Для этих "некоторых" случаев проще и удобней будет не лезть в дебри RTTI: опять же внедрить свой код, но не для перехвата WinAPI-вызовов, а работающий напрямую с VCL-объектами в процессе-"жертве".
-
Ну, допустим, будет у нас в чужом процессе дополнительный поток, работающий напрямую с VCL-объектом. ReadProcessMemory заменяем, образно, говоря, на крышки (^), т.е. получаем доступ к данным напрямую, как в своем процессе. Проблем синхронизации это не решает. Или имеется в виду другой подход?
-
> допустим, будет у нас в чужом процессе дополнительный поток
Зачем дополнительный ? Прямо в основном и обращаемся. И крышки тут ни причем.
-
> ivanoff (25.08.09 16:06) > > получаю так > > SendMessage(H, WM_GETTEXT, 256, LParam(@S[1])); > > ... но только с Edit, Button, Panel, ... > как посмотреть что в Label написано, по его координатам
Самый простой и чаще всего работающий способ: - WmPrint окна на котором лежит label, b в качестве канваса указать битмап. - потом распознать каким-то простым алгоритмом (можно даже тупо наложением изображений букв).
|