![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
например в чужое окно можно записать значение, а как прочесть из
Zert © (2005-10-11 08:16:00)например в чужое окно можно записать значение, а как прочесть из чужого окна?
procedure TForm1.Button5Click(Sender: TObject);
var
df : PChar;
begin
df := '55';
SendMessage(591438, WM_SETTEXT, 0, lParam(PChar(df)));
Edit1.Text := df;
end;
Digitman (2005-10-11 13:20:00) [1]По поводу объекта разделяемой памяти - согласен, ошибку признаю .. мне следовало бы уточнить этот важный момент перед своим утверждением.
Игорь Шевченко (2005-10-11 12:59:00) [2]WM_SET(GET)TEXT, CB_GETLBTEXT, LB_GETTEXT и прочие, при обработке создают объект разделяемой памяти, в которую переписывают данные из структуры окна целевого процесса, после чего переписывают данные из этой разделяемой памяти в буфер вызывающего процесса.
begin...end (2005-10-11 12:46:00) [3]> Digitman © (11.10.05 12:26) [22]
Вы бы Рихтера почитали, что ли...
ShiFT (2005-10-11 12:43:00) [4]2 Digitman
Проверь.
program TestText;
uses Windows, Messages;
const
ClsName : PChar = 'classTMP';
appCapt : PChar = 'TMP';
var
pWnd : HWND;
pMsg : TMsg;
pCls : TWndClassEx;
pCtrl : Array[1..1] of HWND;
function WndProc( wnd: HWnd; msg: LongInt; wParam: wParam; lParam: lParam): LongInt; stdcall;
begin
Result := 0;
case msg of
wm_Destroy : begin
PostQuitMessage( 0);
Exit;
end;
else
Result := DefWindowProc( wnd, msg, wparam, lparam);
end;
end;
begin
with pCls do begin
cbSize := sizeof( pCls);
style := cs_hredraw or cs_vredraw;
lpfnWndProc := @WndProc;
cbClsExtra := 0;
cbWndExtra := 0;
hInstance := HInstance;
hIcon := LoadIcon (0, idi_Application);
hCursor := LoadCursor( 0, idc_arrow);
hbrBackground := COLOR_BTNFACE +1;
lpszMenuName := nil;
lpszClassName := ClsName;
end;
RegisterClassEx( pCls);
pWnd := CreateWindowEx( 0, ClsName, '', ws_overlappedwindow, 100, 100, 250, 45, $0, 0, hInstance, nil);
if pWnd = 0 then Halt;
pCtrl[1] := CreateWindowEx( $0, 'edit', 'Text', ws_visible or ws_child or ws_border, 0, 0, 242, 18, pWnd, 0, hInstance, nil);
SetWindowText( pWnd, appCapt);
ShowWindow( pWnd, SW_SHOW);
UpdateWindow( pWnd);
while GetMessage( pMsg, 0, 0, 0) do begin
TranslateMessage( pMsg);
DispatchMessage( pMsg);
end;
end.
и
Program tmp;
uses Windows, Messages, SysUtils;
var
ndx : word;
p : PChar;
h,h2: THandle;
cls : PChar;
begin
h := FindWindow( 'classTMP', 'TMP');
if h = 0 then Halt(0);
h2 := FindWindowEx( h, 0, 'edit', nil);
if h2 = 0 then Halt(0);
GetMem( cls, 256);
GetClassName( h2, cls, 256);
MessageBox( 0, cls, 'tmp', 0);
ndx := SendMessage( h2, WM_GETTEXTLENGTH, 0, 0);
GetMem( p, ndx+1);
SendMessage( h2, WM_GETTEXT, ndx+1, integer(p));
MessageBox( 0, p, 'tmp', 0);
MessageBox( 0, PChar( IntToStr( Length( p))), 'tmp', 0);
end.
ANB (2005-10-11 12:39:00) [5]
> Digitman © (11.10.05 12:26) [22]
WM_GET/SETTEXT, так же как и WM_COPYDATA умеют работать с разными адресными пространствами в разных процессах. Т.е. параметрами могут служить локальные адреса, винда все разрулит.
ЗЫ. У меня целый кусок проекта на этих сообщениях построен и все работает.
Digitman (2005-10-11 12:26:00) [6]
> ShiFT (11.10.05 12:07) [18]
> проверял как раз в разных процессах.
> У меня работало
не выдумывай небылиц.
В lParam должно быть передано значение адреса в АП именно "чужого", а не "своего" процесса... т.е. того процесса, который создал окно и владеет им, а не того произвольно взятого процесса, который выполняет SendMessage().
В твоем же примере , который якобы "работает", переменная P после вызова GetMem() хранит адрес выделенного блока памяти в "своем", а не "чужом" процессе.
ShiFT (2005-10-11 12:21:00) [7]> Возвращается ровно 254 символа из 260.
из Эдита при использовании GetWindowText( Handle_из_Чужого_Эдита);
GetMem(p,256);
ndx := SendMessage( h, WM_GETTEXTLENGTH, 0, 0);
SendMessage( h, WM_GETTEXT, ndx+1, integer(p));
MessageBox( 0, p, 'tmp', 0);
MessageBox( 0, PChar( IntToStr( Length( p))), 'tmp', 0);
При Этом Возвращаются все 260 символов.
ShiFT (2005-10-11 12:16:00) [8]
> han_malign © (11.10.05 11:30) [11]
AV не вылетает.
Возвращаетсяровно 254 символаиз 260.
Digitman (2005-10-11 12:11:00) [9]
> ShiFT (11.10.05 12:05) [17]
Перечитай [2] и [4] и тему вопроса.
Непосредственная отправка WM_GET/SETTEXT окну чужогоприложения бессмысленна !
Смысл имеет лишь отправка такого сообщения именно при посредничестве Get/SetWindowText, и то - далеко не во всех, а лишь в ряде случаев .. в том самом ряде случаев, который оговорен разработчиками ОС как ряд допустимых случаев успешной работы этих ф-ций.
ShiFT (2005-10-11 12:07:00) [10]Я проверял как раз в разныхпроцессах.
У меня работало (и в Эдитах тоже).
Насчёт 256 символов Знаю.
ShiFT (2005-10-11 12:05:00) [11]
> Digitman © (11.10.05 11:50) [16]
Перечиай Первый и Второй Пост.
Где ты там увидел Get/SetWindowText?
Digitman (2005-10-11 11:50:00) [12]
> han_malign © (11.10.05 11:38) [13]
> где?
известно где - в Караганде !)
речь шла про Get/SetWindowText, а не про WM_GET/SETTEXT
Digitman (2005-10-11 11:47:00) [13]
> ShiFT (11.10.05 11:36) [12]
речь идет о том, что интересующее автора окно - ЧУЖОЕ !
и процесс, создавший интересующее окно, соответственно, - ЧУЖОЙ !
и у этого ЧУЖОГО процесса - свое собственное виртуальное адресное пространство !
и адрес буфера, переданный lParam-параметром сообщения WM_GETTEXT, соответственно, должен быть адресом в ЧУЖОМ (а не СВОЁМ !) адресном пространстве !
так что думай головой, когда советы раздаешь а-ля "Проверено. Работает."
ANB (2005-10-11 11:41:00) [14]WM_GETTEXT работает не всегда (она читает заголовок окна). А вот GetText() - почему то работает.
han_malign (2005-10-11 11:38:00) [15]
> вчитайся в [5]
> там черным по белому написано про случай с EDIT-контролом.
- где?
An application sends a WM_GETTEXT message to copy the text that corresponds to a window into a buffer provided by the caller.
.......................
Note, for non-textstatic controls this gives you the text with which the control was originally created, that is, the ID number.
.......................
For other windows, the text is the window title . To copy the text of an item in a list box, an application can use the LB_GETTEXTmessage.
.......................
When the WM_GETTEXT message is sent to a static control with the SS_ICON style, a handle to the icon will be returned in the first four bytes of the bufferpointed to by lParam. This is true only if the WM_SETTEXT message has been used to set the icon.
.......................
Rich Edit:If the text to be copied exceeds 64K, use either the EM_STREAMOUT or EM_GETSELTEXT message.
.......................
Windows 2000/XP:Sending a WM_GETTEXT message to a non-textstatic control, such as a static bitmap or static icon control, does not return a string value. Instead, it returns zero.
ShiFT (2005-10-11 11:36:00) [16]
> читай справку :
> GetWindowText
> This function cannot retrieve the text of an edit control
> in another application.
Справка для WM_GETTEXT
For an edit control, the text to be copied is the content of the edit control. For a combo box, the text is the content of the edit control (or static-text) portion of the combo box. For a button, the text is the button name. For other windows, the text is the window title. To copy the text of an item in a list box, an application can use the LB_GETTEXT message.
When the WM_GETTEXT message is sent to a static control with the SS_ICON style, the handle of the icon will be returned in the first four bytes of the buffer pointed to by lpszText. This is true only if the WM_SETTEXT message has been used to set the icon.
In a rich edit control, if the text to be copied exceeds 64K, use either the message EM_STREAMOUT or EM_GETSELTEXT
han_malign (2005-10-11 11:30:00) [17]
> ShiFT (11.10.05 11:15) [9]
GetMem(p, 256);
ndx:= SendMessage( 590592, WM_GETTEXTLENGTH, 0, 0);
SendMessage( 590592, WM_GETTEXT, ndx, integer(p));
> Проверено. Работает.
- ну-ну, а если длинна текста больше 256, что будет?
Можно даже не гадать - AV будет... И зачем вообще запрашивать длинну, если буфер от балды выделять?
Digitman (2005-10-11 11:22:00) [18]
> ShiFT (11.10.05 11:15) [9]
вчитайся в [5]
там черным по белому написано про случай с EDIT-контролом.
> Проверено. Работает
работает, но лишь в частных случаях.
ShiFT (2005-10-11 11:15:00) [19]
procedure TForm1.Button5Click(Sender: TObject);
var
ndx : word;
p : PChar;
begin
GetMem(p,256);
ndx := SendMessage( 590592, WM_GETTEXTLENGTH, 0, 0);
SendMessage( 590592, WM_GETTEXT, ndx, integer(p));
MessageBox( 0, p, 'tmp', 0);
end;
Проверено. Работает.
Digitman (2005-10-11 10:51:00) [20]
> Zert (11.10.05 10:38) [6]
> что такая невыполнимая задача
ну отчего ж невыполнимая ? выполнимая)
но для решения тех данных, которыми ты владеешь (известен только хэндл окна), недостаточно - нужно как минимум знать класс окна.. от этого и решение и сложность решения будет напрямую зависеть ..