Форум: "WinAPI";
Текущий архив: 2004.02.06;
Скачать: [xml.tar.bz2];
Вниз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 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.02.06;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.355 c