Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
3-16185
klyonov
2004-01-13 17:47
2004.02.06
TDBGridEh.STFilter


3-16142
dummy
2004-01-15 12:13
2004.02.06
названия полей в таблице


3-16068
Cerber
2004-01-10 20:15
2004.02.06
Локалки против Клиент серверов


1-16456
Галинка
2004-01-28 06:43
2004.02.06
О типах данных в Delphi


1-16245
denis24
2004-01-26 15:58
2004.02.06
strtofloat( 150.00 )





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский