Конференция "WinAPI" » как прочитать текст с чужого ListView? [D7, WinXP]
 
  • tytus (08.05.08 13:19) [0]
    Добрый день мастера. Вот есть такой код:
    procedure TMainFm.Button1Click(Sender: TObject);
    var
     i,n:integer;
     LI:TLVItem;
     pid:DWORD;
     hProcess:THandle;
     addr:Pointer;
     NumberOfBytesRead:Cardinal;
     vBuffer:array[0..255]of Char;
    begin
    //XLVHandle - хендл чужого ListView
    GetWindowThreadProcessID(XLVHandle,@pid);
    hProcess:=OpenProcess(PROCESS_VM_READ or PROCESS_VM_OPERATION or
     PROCESS_VM_WRITE,false,pid);
    addr:=VirtualAllocEx(hProcess,nil,4096,MEM_RESERVE or MEM_COMMIT,
     PAGE_READWRITE);
    n:=SendMessage(XLVHandle,LVM_GETITEMCOUNT,0,0);
    //Определяется правильно!
    if n=0 then Exit;
    try
     for i:=0 to n-1 do
     begin
       LI.stateMask:=LVIF_TEXT;
       LI.iItem:=i;
       LI.iSubItem:=1;
       Li.cchTextMax:=255;
       LI.pszText:=Pointer(Cardinal(addr)+SizeOf(TLVItem));
       WriteProcessMemory(hProcess,addr,@LI,SizeOf(TLVItem),NumberOfBytesRead);
       SendMessage(XLVHandle,LVM_GETITEM,0,LParam(addr));
       ReadProcessMemory(hProcess,Pointer(Cardinal(addr)+SizeOf(TLVItem)),@vBuffer,SizeOf(vBuffer),NumberOfBytesRead);
       RE1.Lines.Add(vBuffer);
     end;
    finally
     VirtualFreeEx(hProcess,addr,0,MEM_RELEASE);
     CloseHandle(hProcess);
    end;
    end;


    В результате в RichEdit (RE1) записываются пустые строки.
    Что я неправильно делаю...?
  • Rouse_ © (08.05.08 13:21) [1]
    ////////////////////////////////////////////////////////////////////////////////
    //
    //  ****************************************************************************
    //  * Unit Name : RemoteSysListView32
    //  * Purpose   : Демо работы с удаленным SysListView32
    //  * Author    : Александр (Rouse_) Багель
    //  * Copyright : © Fangorn Wizards Lab 1998 - 2007
    //  * Version   : 1.01
    //  * Home Page : http://rouse.drkb.ru
    //  ****************************************************************************
    //

    program RemoteSysListView32;

    {$APPTYPE CONSOLE}

    uses
     Windows,
     SysUtils,
     CommCtrl;

    var
     hwndRemoteSysListView: HWND = 0;
     hProcess: THandle = 0;
     dwProcessID: DWORD = 0;
     dwBytesWriten: DWORD;
     nItemCount: Integer = 0;
     I, nTextLength: Integer;
     cchTextMax: Integer = 255;
     plviRemoteLVItem: PLVItem = nil;
     lviRemoteLVItem: LV_ITEM;
     pszText: PChar = nil;
     svText: ShortString;
     ARect: TRect;
     pRemoteRect: Pointer = nil;

     function GetFirstChild(hwndValue: HWND): HWND;
     begin
       Result := GetWindow(hwndValue, GW_CHILD);
     end;

     function Translate(Value: String): String;
     begin
       SetLength(Result, Length(Value));
       AnsiToOem(@Value[1], @Result[1]);
     end;

    begin
     // Ищем SysListView32 рабочего стола
     hwndRemoteSysListView := GetFirstChild(GetFirstChild(FindWindow('ProgMan', nil)));
     if hwndRemoteSysListView = 0 then ExitProcess(GetLastError);

     // Получаем количество элементов (ярлыков на рабочем столе)
     nItemCount := ListView_GetItemCount(hwndRemoteSysListView);

     // Получаем ID процесса, которому принадлежит найденное окно
     GetWindowThreadProcessId(hwndRemoteSysListView, @dwProcessID);
     if dwProcessID = 0 then ExitProcess(GetLastError);

     // Открываем процесс
     hProcess := OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwProcessID);
     if hProcess = 0 then ExitProcess(GetLastError);

     // Выделяем в нем память под текстовый буффер
     pszText := VirtualAllocEx(hProcess, nil, cchTextMax,
      MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
     if GetLastError <> 0 then ExitProcess(GetLastError);

     // Выделяем в нем память под структуру LVITEM
     plviRemoteLVItem := VirtualAllocEx(hProcess, nil, SizeOf(LV_ITEM),
      MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
     if GetLastError <> 0 then ExitProcess(GetLastError);

     // Заполняем структуру
     ZeroMemory(@lviRemoteLVItem, SizeOf(LV_ITEM));
     lviRemoteLVItem.mask := LVIF_TEXT;
     lviRemoteLVItem.pszText := pszText;
     lviRemoteLVItem.cchTextMax := cchTextMax;

     // Пишем ее в память удаленного процесса
     if not WriteProcessMemory(hProcess, plviRemoteLVItem, @lviRemoteLVItem,
       SizeOf(LV_ITEM), dwBytesWriten) then ExitProcess(GetLastError);

     // Выделяем в нем память под структуру TRect
     pRemoteRect := VirtualAllocEx(hProcess, nil, SizeOf(TRect),
      MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
     if GetLastError <> 0 then ExitProcess(GetLastError);

     // Получаем текст со всех элементов
     for I := 0 to nItemCount - 1 do
     begin
       // Отправляем сообщение с указателем на выделенный буффер под LVITEM
       nTextLength := SendMessage(hwndRemoteSysListView, LVM_GETITEMTEXT,
         I, Integer(plviRemoteLVItem));

       // Читаем результат
       ZeroMemory(@svText, cchTextMax);
       ReadProcessMemory(hProcess, lviRemoteLVItem.pszText,
         @svText[1], nTextLength, dwBytesWriten);

       // Чтобы получить координаты каждого элемента нужно подготовить структуру
       ZeroMemory(@ARect, SizeOf(TRect));
       ARect.Left := LVIR_ICON;
       if not WriteProcessMemory(hProcess, pRemoteRect, @ARect,
         SizeOf(TRect), dwBytesWriten) then ExitProcess(GetLastError);

       // Посылаем сообщение для получения координат каждого элемента
       SendMessage(hwndRemoteSysListView, LVM_GETITEMRECT,
         I, Integer(pRemoteRect));

       // Читаем результат
       ReadProcessMemory(hProcess, pRemoteRect,
         @ARect, SizeOf(TRect), dwBytesWriten);

       Writeln(Translate(PChar(@svText[1])));
       Writeln(Translate(
         Format('- координаты: Left = %d, Top = %d, Right = %d, Bottom = %d',
           [ARect.Left, ARect.Top, ARect.Right, ARect.Bottom])));

     end;

     // Освобождаем ранее выделенную память
     VirtualFreeEx(hProcess, pszText, 0, MEM_RELEASE);
     VirtualFreeEx(hProcess, plviRemoteLVItem, 0, MEM_RELEASE);

     // Закрываем описатель процесса
     CloseHandle(hProcess);

     Readln;
    end.


  • tytus (08.05.08 14:19) [2]
    >Rouse_ ©   (08.05.08 13:21) [1]
    Спасибо, помогло.
  • Одинадцатый (27.04.09 20:52) [3]
    Злравствуйте.
    У меня след. проблема: на форме, на 2 вкладках чего-то типа pagecontrol, не считываются данные из listview32, хотя на остальных вкладках работает.
    В чем может быть дело?
  • Одинадцатый (27.04.09 20:53) [4]
    Злравствуйте.
    У меня след. проблема: на форме, на 2 вкладках чего-то типа pagecontrol, не считываются данные из listview32, хотя на остальных вкладках работает.
    В чем может быть дело?
  • Германн © (28.04.09 01:18) [5]

    > Одинадцатый   (27.04.09 20:52) [3]
    >
    > Злравствуйте.
    > У меня след. проблема

    Модераторы разберутся с твоей проблемой.
    Так что лучше сам задай свой вопрос в своей ветке.
 
Конференция "WinAPI" » как прочитать текст с чужого ListView? [D7, WinXP]
Есть новые Нет новых   [134435   +33][b:0][p:0.004]