Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> выдрать текст из RichEdit20A, например из WordPad 
:(
    Опции темы
Smailik
  Дата 16.5.2006, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 8.5.2006

Репутация: нет
Всего: нет



если класс ричедита TRichEdit - все пашет
а с родными ричедитами Windows - вышибает прогу которой принадлежит ричедит. где грабли? подскажите плиз!!!

Код

procedure TForm1.Button1Click(Sender: TObject);
var
  TextRange: TGetTextEx;
  gtl : TGetTextLengthEx;
  mass : Pchar;
  tmp : integer;
  AHandle : THandle;
begin
  AHandle := FindWindow(nil,Pchar(Edit1.Text));

  enumChildWindows(AHandle, @enumListOfChildTasks, LongInt(Self)); //возвращает handle ричедита - проверял верно работает 

  getmem(mass,4048);

  if EditHandle = 0 then begin
    ShowMessage('not found.');
  end
  else begin
    Memo1.Lines.Clear;
      with gtl do begin
        flags := GTL_DEFAULT;
        codepage := CP_ACP;
      end;


    with TextRange do begin
      cb := 0;
      flags := GT_DEFAULT;
      codepage := cp_ACP;
      lpDefaultChar := nil;
      lpUsedDefChar := nil;
    end;

// вот тут аварийно завершается прога которой принадлежит ричедит, например WordPad
    tmp := SendMessage(EditHandle, EM_GETTEXTEX, integer(@textrange), integer(mass)); 
    Memo1.Lines.Add(string(mass));
//    tmp := SendMessage(EditHandle, EM_GETTEXTLENGTHEX , integer(@gtl), 0); //количество букв
    ShowMessage(inttostr(tmp));
  end;

  freemem(mass);
end;
 
PM MAIL   Вверх
RA
Дата 16.5.2006, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Брутальный буратина
****


Профиль
Группа: Участник Клуба
Сообщений: 3497
Регистрация: 31.3.2002
Где: Лес

Репутация: 7
Всего: 115



Там нужно не сенд месаджи слать а GetWindowText

Добавлено @ 17:40 
Хотя сендмесаджем нужно проверить длинну данных. 
PM   Вверх
Yanis
Дата 16.5.2006, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 13
Всего: 111



Цитата(RAdmin @  16.5.2006,  18:38 Найти цитируемый пост)
Там нужно не сенд месаджи слать а GetWindowText

Ну можно же WM_GETTEXT+SendMessage использовать smile 


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
Smailik
Дата 17.5.2006, 06:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 8.5.2006

Репутация: нет
Всего: нет



Цитата(RAdmin @  16.5.2006,  17:38 Найти цитируемый пост)
Там нужно не сенд месаджи слать а GetWindowText


у ричедита нет title и caption


Цитата(Yanis @  16.5.2006,  19:45 Найти цитируемый пост)
Ну можно же WM_GETTEXT+SendMessage использовать   



только для edit работает

 smile  
PM MAIL   Вверх
RA
Дата 17.5.2006, 09:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Брутальный буратина
****


Профиль
Группа: Участник Клуба
Сообщений: 3497
Регистрация: 31.3.2002
Где: Лес

Репутация: 7
Всего: 115



Цитата(Smailik @  17.5.2006,  06:28 Найти цитируемый пост)
у ричедита нет title и caption



GetwindowText возвращает не только заголовки окон.

Добавлено @ 09:51 
Точнее сказать будет - GetwindowText возвращает текст окон.
если окно формы то её caption, если окно рича то текст рича.

Вот правда на счёт рича не знаю возвратит она форматированный текст или Plain.

 
PM   Вверх
Yanis
Дата 17.5.2006, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 13
Всего: 111



Посмотрел сейчас через WIS - текст RichEdit нельзя получить через GetwindowText.

Цитата(RAdmin @  17.5.2006,  10:44 Найти цитируемый пост)
Вот правда на счёт рича не знаю возвратит она форматированный текст или Plain.
См. выше. А вообще текст возвращается как plain.
 


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
RA
Дата 17.5.2006, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Брутальный буратина
****


Профиль
Группа: Участник Клуба
Сообщений: 3497
Регистрация: 31.3.2002
Где: Лес

Репутация: 7
Всего: 115



а в форме с двумя ричами можно  smile  
Код

procedure TForm1.Button1Click(Sender: TObject);
var text : array [0..255] of Char;
begin
Windows.GetWindowText(RichEdit1.Handle,text,100);
RichEdit2.lines.add(text);
end;


ЗЫ: Таже CustomEdit, тьфу. 

Это сообщение отредактировал(а) RAdmin - 17.5.2006, 12:58
PM   Вверх
Rouse_
Дата 17.5.2006, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 469
Регистрация: 23.4.2005

Репутация: 18
Всего: 29



Прежде нужно учить матчасть и разбираться в каком АП выделен буффер, куда будет ложиться данные и как обойти границу адресных пространств двух и более процессов. Сколько раз уже повторял - читайте Рихтера, там все по полкам разложено.


Smailik, код конкретно для твоей задачи с комментариями:

Код

unit MainUnit;

interface

uses
  Windows, Graphics, Controls, Forms, ComCtrls,
  StdCtrls, Classes, SysUtils, Dialogs;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Memo1: TMemo;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

uses RichEdit;

{$R *.dfm}

function SetDebugPriv: Boolean;
var
  Token: THandle;
  tkp: TTokenPrivileges;
begin
  Result := False;
  if OpenProcessToken(GetCurrentProcess,
    TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token) then
  begin
    if LookupPrivilegeValue(nil, PChar('SeDebugPrivilege'),
      tkp.Privileges[0].Luid) then
    begin
      tkp.PrivilegeCount := 1;
      tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
      Result := AdjustTokenPrivileges(Token, false,
        tkp, 0, PTokenPrivileges(nil)^, PDWord(nil)^);
    end;
  end;
end;

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;

  // Включаем отладочные привилегии
  if SetDebugPriv then
  begin

    // Узнаем 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;
end;

end.
 


--------------------
 Vae Victis
(Горе побежденным (лат.))
Демо с открытым кодом: http://rouse.drkb.ru 
PM MAIL WWW ICQ   Вверх
Rouse_
Дата 17.5.2006, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 469
Регистрация: 23.4.2005

Репутация: 18
Всего: 29



Кстати, RAdmin, по поводу GetWindowText. Неаккуратненько как то давать такие советы smile

Цитата

The GetWindowText function copies the text of the specified window's title bar (if it has one) into a buffer. If the specified window is a control, the text of the control is copied. However, GetWindowText cannot retrieve the text of a control in another application.
 


--------------------
 Vae Victis
(Горе побежденным (лат.))
Демо с открытым кодом: http://rouse.drkb.ru 
PM MAIL WWW ICQ   Вверх
RA
Дата 18.5.2006, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Брутальный буратина
****


Профиль
Группа: Участник Клуба
Сообщений: 3497
Регистрация: 31.3.2002
Где: Лес

Репутация: 7
Всего: 115



Мда, не отмерил 7 раз, а сразу отрезал.  smile  
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.1157 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.