Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.02.06;
Скачать: CL | DM;

Вниз

WM_GETTEXT   Найти похожие ветки 

 
GrandleBugenShpreh   (2003-11-25 17:48) [0]

Мне надо извлекать текст из контролов находящихся под курсором мыши. Эти контролы не обязательно находятся в моей программе... Нашел в форуме :
the sequence is this:

1. call GetCursorPos to get mouse cursor position
2. call WindowFromPoint to get a window handle for the window under the
cursor.
3. call ChildWindowFromPoint recursively, starting with the handle you got
in step2, until the handle does no longer change on a call. You have now
found the control under the cursor.
4. send a WM_GETTEXTLENGTH message to the control. If the return value is
anything other than 0 you may have an edit control or at least some
control that will propably respond to WM_GETTEXT (buttons and other
controls will return their caption, edit controls their text).
5. allocate a buffer with the returned size +1 and send a WM_GETTEXT
message to the control, passing the address of this buffer in lparam.
WM_GETTEXT is one of the few messages that take a pointer and still work
across processes.
6. Inspect what you got in the buffer.

Вот что я реализовал :

var a:TPoint;
h,h1,h2:THandle;
aaa:PChar;
Length:Integer;
begin
getCursorPos(a);
h:=WindowFromPoint(a);

if h<>0 then
begin
h1:=ChildWindowFromPoint(h,a);
h2:=1;

while h2<>0 do
begin
h2:=ChildWindowFromPoint(h1,a);
if h2<>0 then h1:=h2;
if h2=h1 then break;
end;

if h1<>0 then
begin
Length:=SendMessage(h1,WM_GETTEXTLENGTH,0,0);
if Length>0 then
begin
inc(Length);
SendMessage(h1,WM_GETTEXT,100,LParam(aaa));
Label6.Caption:=aaa;
end;
end;
end;

Работает, но не правильно т.е. иногда выдает совсем не тот текст, а иногда просто вызывает access violation.

Подскажите в чем может быть проблема ?
Нет ли у кого-нибудь примера как это можно реализовать ?


 
Dimka Maslov ©   (2003-11-25 17:56) [1]

Под PChar память кто выделять будет?


 
GrandleBugenShpreh   (2003-11-25 18:03) [2]

Да конечно :)
Забыл.... Сейчас конечно уже не виснет, но все равно текст часто показывается неправильно.... Видимо я все-таки не могу добраться до Child контрола... Да же у меня на форме в ГрупБоксе находится Едит, а я получаю Form1 :((((


 
Dimka Maslov ©   (2003-11-25 18:10) [3]

Получаешь Handle Form1. Переводишь координаты курсора мыши в систему координат формы. Опять вызываешь ChildWindowFromPoint. Получаешь Handle GroupBox. Переводишь координаты курсора мыши с систему координат GroupBox. Опять вызываешь ChildWindowFromPoint. Получаешь Нandle Edit. Это частный случай.

В общем случае создаём цикл в котором перебираем handle пока не найдём искомый. Признак нахождения смотрим в MSDN.


 
GrandleBugenShpreh   (2003-11-25 18:15) [4]

Хм... а почему не работает мой цикл по нахождению нужного хендла ? Я вроде все так сделал - нахожу хеднл окна под курсором, и рекурсивно ищу Child-окна пока предыдущий найденные хендл не совпадает с только что найденным. Как совпало - значит это именно тот контрол который под курсором... Или нет ?


 
sr   (2003-11-25 18:17) [5]

попробуй API getwindowtext(..) вместе WindowFromPoint и еще SetCapture(handle) не забудь, чтоб форма получала сообщения мыши, даже если курсор вне формы.
примерно так:
...
SetCapture(handle);
GetCursorPos(Point);
Wnd:=WindowFromPoint(Point);
GetWindowText(wnd,str,8);
...
вот и в буфер str получишь текст контрола


 
Dimka Maslov ©   (2003-11-25 18:33) [6]

Если всё в цикле запустить, то получим бред, почему непонятно. Тебе надо действовать так:

function GetMouseHoverControlText: string;
var
Point: TPoint;
Handle: THandle;
P: PChar;
Len: Integer;
begin
Result := "";
GetCursorPos(Point);
Handle := WindowFormPoint(Point);
if Handle <> 0 then begin
Len := SendMessage(Handle, WM_GETTEXTLENGTH, 0, 0);
if Len <> 0 then begin
Inc(Len);
GetMem(P, Len);
SendMessage(Handle, WM_GETTEXT, Len, Integer(P));
Result := P;
FreeMem(P, Len);
end;
end;
end;

SetCapture лучше делать - будет притормаживать. Вызвать функцию надо по таймеру.


 
chi   (2003-11-26 00:52) [7]

по -моему GetWindowText очень удобная функция, зачем лишний раз SendMessage(Handle, WM_GETTEXT, Len, Integer(P)) когда и так все просто ??? Ничего не тормозит если в обработчике нажатий кнопки мыши прослеживать изменения окна, например, так
if WND <> wndPREV then ...


> Dimka Maslov

зачем таймер, надо либо ловить сообщения мыши, либо пользоаться стандартной для окна процедуры OnMouseMove..если не ошибаюсь


 
Dimka Maslov ©   (2003-11-26 08:49) [8]

>chi (26.11.03 00:52) [7]
OnMouseMove ловит только те сообщения мыши, которые произошли над контролом. Если сделать SetCapture - это значит, что весь поток мышиных сообщений будет направлен контролу, при этом другие окна ничего не получат. По-этому лучше делать по таймеру.

Что же касается GetWindowText цитата из MSDN:
To retrieve the text of a control in another process, send a WM_GETTEXT message directly instead of calling GetWindowText.
Цитата из первого поста ветки:
Эти контролы не обязательно находятся в моей программе

Теперь понятно?


 
sr   (2003-11-26 12:55) [9]

все мне понятно было сразу.. но SetCapture(handle) верное решение!! Могу отписать работающий код


 
Dimka Maslov ©   (2003-11-26 12:59) [10]

Код работает, но во время работы этого кода ни один другой контрол формы не получит сообщения от мыши.


 
Ascan ©   (2003-11-26 16:55) [11]

Dimka Maslov [3]
> Получаешь Handle GroupBox. Переводишь координаты курсора мыши с систему координат GroupBox.

Подскажи, пожалуйста, функцию для "перевода координат курсора мыши" для чужого Handle
Или функцию для определения коодинат чужого окна/объекта, т.е. для определения .Left и .Top


 
Dimka Maslov ©   (2003-11-26 18:02) [12]

GetWindowRect


 
Xtz ©   (2003-11-28 18:23) [13]

В орешнике есь юнит ExApi так вот там есть Function ExGetHndlInMouse:thandle; которая ловит хендлак компанента под курсором и есть такая штука ExGetText(Handle:Thandle):String;//ExWnd.Text которая по хендлаку хватает текст еэемента вот!


 
xtz ©   (2003-11-28 23:47) [14]

Ой изеняюся в кладовке / компоненты


 
Diamond Cat ©   (2003-11-29 01:46) [15]

вобще не правильный подход к самому сообщению wm_gettext, насколько я помню оно требует больше деликатности типа
var
Cds: TCopyDataStruct;
begin
Cds.dwData := Top;
GetMem (Cds.lpData, Cds.cbData );
SendMessage (твой хендл,WM_GetText, 20, Cardinal(Pchar(Cds.lpdata)));
edit1.text:= Pchar(Cds.lpdata);
FreeMem (Cds.lpData);
в принципе у меня есть програмка которая выдирает текст почти отовсюду, при этом не тормозит работу как в варианте с setcapture работает через длл, могу слить , пиши на почту,
diamond_cat@newmail.ru


 
chi   (2003-11-29 15:15) [16]

могу слить хук на мышку, кот. по нажатии правой кнопки над контролом показывает текст, если он есть..


 
DeMoN-777 ©   (2003-11-30 11:01) [17]

procedure TForm1.Timer1Timer(Sender: TObject);
var
h : HWND;
n : integer;
s : string;
begin
h := WindowFromPoint(Mouse.CursorPos);
if h <> 0 then begin
n := SendMessage(h, WM_GETTEXTLENGTH, 0, 0) + 1;
SetLength(s, n);
SendMessage(h, WM_GETTEXT, WPARAM(n), LPARAM(PChar(s)));
Edit1.Text := s;
end;



Страницы: 1 вся ветка

Текущий архив: 2004.02.06;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.027 c
6-16580
Dimman1
2003-12-04 13:02
2004.02.06
Формат пакета MailSlot


1-16378
Тимохов
2004-01-23 16:32
2004.02.06
Потоковые модели и COM


1-16410
HES
2004-01-22 17:14
2004.02.06
Написание собственных событий для компонента


4-16824
Владислав
2003-11-27 10:16
2004.02.06
Tooltips в Toolbar под XP.


1-16395
buka
2004-01-21 19:51
2004.02.06
Вопрос к тому кто занимался с Wise Installer