![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
RichEdit20A. Как взять текст?
DmitrichJ © (2007-05-21 02:18:00)Привет, мастера. Собственно и весь вопрос. Как взять текст данного класса из чужого окна? Хэндлы окна и объекта имеются.
Спасибо.
Leonid Troyanovsky (2007-05-21 12:43:00) [21]
> DmitrichJ (21.05.07 11:56) [5]
> ???????????????????????
Ну, и здесь-то чего?
--
Regards, LVT.
DmitrichJ (2007-05-21 12:37:00) [22]XP SP2
Rouse_ (2007-05-21 12:35:00) [23]Система у тебя какая?
DmitrichJ (2007-05-21 12:19:00) [24]Project Projext1.exe raised exception class EOSError with message 'System Error. Code 6: Неверный дескриптор'...
Rouse_ (2007-05-21 12:10:00) [25]
> Rouse_, проблема с выделением памяти. PStructTextLength
> = nil !!!
А RaiseLastOSError что говорит?
DmitrichJ (2007-05-21 12:00:00) [26]Rouse_, проблема с выделением памяти. PStructTextLength = nil !!!
DmitrichJ (2007-05-21 11:56:00) [27]var
Form,obj,h:HWND;
...
Form:=FindWindow(nil, 'Нужное мне окно');
if Form<>0 then begin
ShowMessage('Окно есть!');
h:=FindWindowEx(form, 0, 'RichEdit20A', nil);
if h<>0 then begin
ShowMessage('Класс найден');
???????????????????????
end;
end else ShowMessage('Нет окна =(');
Leonid Troyanovsky (2007-05-21 11:30:00) [28]
> DmitrichJ (21.05.07 11:12) [3]
> Leonid Troyanovsky, пустую строчку, хотя я в этом пока только
> начинаю разбераться.
Добро пожаловать в "Начинающие".
SendMessage, воо-ще-то, возвращает LRESULT.
И, еще, как идентифицирован RICHEDIT (хендл, класс), показывай.
--
Regards, LVT.
DmitrichJ (2007-05-21 11:12:00) [29]Leonid Troyanovsky, пустую строчку, хотя я в этом пока только начинаю разбераться.
Rouse_, спасибо. Надеюсь заработает.
Leonid Troyanovsky (2007-05-21 10:04:00) [30]
> DmitrichJ (21.05.07 02:18)
> Привет, мастера. Собственно и весь вопрос. Как взять текст
> данного класса из чужого окна? Хэндлы окна и объекта имеются.
А что возвращает SendMessage with WM_GETTEXT?
--
Regards, LVT.
Rouse_ (2007-05-21 09:35:00) [31]
unit MainUnit;
interface
uses
Windows, Messages, Graphics, Controls, Forms, ComCtrls,
StdCtrls, Classes, SysUtils, Dialogs;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Memo1: TMemo;
Edit2: TEdit;
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
uses RichEdit;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
{$DEFINE DEBUG_FIND}
var
MainWindowHandle, RichEditWHandle: THandle;
ProcessID : Cardinal;
ProcessHandle : THandle;
StructTextEx: TGetTextEx;
StructTextLength: TGetTextLengthEx;
PStructTextLength, PStructTextEx, PTextBuffer: Pointer;
BytesWriten, RichEditTextLength: DWORD;
TextBuffer: array of Char;
begin
{$IFDEF DEBUG_FIND}
// Заполняем данные для отладки
// В качестве примера работаем с WordPad-ом
Edit1.Text := 'Document - WordPad';
Edit2.Text := 'RICHEDIT50W';
{$ENDIF}
// Ищем окно
MainWindowHandle := FindWindow(nil , PChar(Edit1.Text));
if MainWindowHandle = 0 then RaiseLastOSError;
RichEditWHandle := FindWindowEx(MainWindowHandle, 0, PChar(Edit2.Text), nil);
if RichEditWHandle = 0 then RaiseLastOSError;
// Узнаем ID процесса
GetWindowThreadProcessId(MainWindowHandle, @ProcessID);
if ProcessID = 0 then RaiseLastOSError;
// Открываем процесс
ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, True, ProcessID);
if ProcessHandle = 0 then RaiseLastOSError;
try
// Выделяем в нем память под структуру TGetTextLengthEx
PStructTextLength := VirtualAllocEx(ProcessHandle, nil,
SizeOf(TGetTextLengthEx), MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
if PStructTextLength = nil then RaiseLastOSError;
try
// Подготавливаем структуру...
StructTextLength.flags := GTL_NUMBYTES or GTL_USECRLF;
StructTextLength.codepage := CP_ACP;
// ...и пишем ее в память процесса
if not WriteProcessMemory(ProcessHandle, PStructTextLength,
@StructTextLength, SizeOf(TGetTextLengthEx),
BytesWriten) then RaiseLastOSError;
if BytesWriten <> SizeOf(TGetTextLengthEx) then RaiseLastOSError;
// Отправляем сообщение удаленному RichEdit,
// чтобы узнать необходимый размер буффера
RichEditTextLength := SendMessage(RichEditWHandle,
EM_GETTEXTLENGTHEX , Integer(PStructTextLength), 0);
finally
// Освобождаем выделенную под TGetTextLengthEx память
VirtualFreeEx(ProcessHandle, PStructTextLength, 0, MEM_RELEASE);
end;
// Выделяем память под структуру TGetTextEx
PStructTextEx := VirtualAllocEx(ProcessHandle, nil,
SizeOf(TGetTextEx), MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
if PStructTextEx = nil then RaiseLastOSError;
try
// Подготавливаем структуру...
ZeroMemory(@StructTextEx, SizeOf(TGetTextEx));
StructTextEx.flags := GT_USECRLF;
StructTextEx.cb := RichEditTextLength;
// ...и пишем ее в память процесса
if not WriteProcessMemory(ProcessHandle, PStructTextEx,
@StructTextEx, SizeOf(TGetTextEx),
BytesWriten) then RaiseLastOSError;
if BytesWriten <> SizeOf(TGetTextEx) then RaiseLastOSError;
// Выделяем память под текстовый буффер
PTextBuffer := VirtualAllocEx(ProcessHandle, nil,
RichEditTextLength, MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
if PTextBuffer = nil then RaiseLastOSError;
try
// отправляем сообщение
SendMessage(RichEditWHandle, EM_GETTEXTEX, Integer(PStructTextEx),
Integer(PTextBuffer));
// Читаем, то, что у нас скопировалось
SetLength(TextBuffer, RichEditTextLength);
if not ReadProcessMemory(ProcessHandle, PTextBuffer, @TextBuffer[0],
RichEditTextLength, BytesWriten) then RaiseLastOSError;
Memo1.Text := String(TextBuffer);
finally
// Освобождаем выделенную под тестовый буффер память
VirtualFreeEx(ProcessHandle, PTextBuffer, 0, MEM_RELEASE);
end;
finally
// Освобождаем выделенную под TGetTextEx память
VirtualFreeEx(ProcessHandle, PStructTextEx, 0, MEM_RELEASE);
end;
finally
// Закрываем процесс
CloseHandle(ProcessHandle);
end;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
SendMessage(Handle, WM_SYSCOMMAND, SC_MOVE or HTCAPTION, 0);
end;
end.