Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Получить текст из компонента другого приложения


Автор: bagos 17.8.2011, 11:42
Потребовалось из стороннего приложения получать текст из компонента класса Static.
Для начала нахожу нужное мне окно родителя, затем начинаю перечислять все окна потомки
Код

function EnumChildProc(H: hWND;Param:Pointer): BOOL; stdcall;
var
  WindowText:array [0..255] of Char;
begin
  Result := h <> 0;
  if Result then
    begin
      GetWindowText(h,WindowText,255);
      Form1.ListBox1.Items.Add(IntToStr(h)+'--->'+WindowText);
      EnumChildWindows(h, @EnumChildProc, 0);
    end;
end;


в списке нахожу то что мне надо. Вопрос в следующем как мне организовать получение текста нужного мне контрола в найденном окне, где то проскользнуло слово "смещение" что это? номер по порядку?

Автор: bagos 17.8.2011, 12:01
немного изменил код:
Код

  if Result then
    begin
      GetWindowText(h,WindowText,255);
      if count = 51066 then
        begin
          Form1.ListBox1.Items.Add(IntToStr(h)+'--->'+WindowText);
           inc(count);
        end;

      //Form1.ListBox1.Items.Add(inttostr(count)+') '+intToStr(h)+'--->'+WindowText);
      inc(count);
      EnumChildWindows(h, @EnumChildProc, 0);
    end;


в списке посмотрел номер объекта по нумерации, затем делаю проверочку тот ли объект. В след. раз при запуске буду получать хендл окна по номеру 51066 и вытаскивать текст getwindowtext, все верно?
может кто знает другие пути решения?

Автор: Keeper89 18.8.2011, 11:46
Какие отличительные особенности у целевого окна?

Автор: bagos 18.8.2011, 15:52
Трудно так сказать, а какие предположим могут быть?
Данный код использую для получения хендла нужного мне объекта на форме, затем уже обращаюсь по хендлу к нему.

Автор: Keeper89 18.8.2011, 19:03
Может там текст особенный или еще что?

Автор: bagos 18.8.2011, 20:20
с label и edit проблем нет, а вот с listview имеются.
пробил класс SysListView32, удалось получить ListView_GetItemCount кол-во итемов, на этом все)))
ListView_GetItem ничего не дает? может кто выдирал данные из listview стороннего процеса? поделитесь примером
делаю так, приходит полная белеберда:
Код

 function LVIEW__GetSelectedItemText(HLVIEW: HWND): string;
  const
    BufLen = 255;
  var
    Item: TLVItem;
    ItemsCount: integer;
    i: integer;
  begin
    ItemsCount:=ListView_GetItemCount(HLVIEW);
    Result:='';
    for i:=0 to ItemsCount-1 do begin
      try
        with Item do begin
          mask:=LVIF_STATE or LVIF_TEXT;
          iSubItem:=0;
          Item.iItem:=i;
          Item.state:=0;
          Item.cchTextMax:=BufLen;
          Item.pszText:=StrAlloc(BufLen);

        end;
        ListView_GetItem(HLVIEW,Item);
          Result:=Item.pszText;
      finally
        StrDispose(Item.pszText);
      end;
      if Result<>'' then exit;
    end;
  end;

Автор: bagos 19.8.2011, 01:02
нарыл рабочий код по выдергиванию из Listview
Код

function ListViewColumnCount(mHandle: THandle): Integer;
begin
  Result := Header_GetItemCount(ListView_GetHeader(mHandle));
end; { ListViewColumnCount }
function GetListViewText(mHandle: THandle; mStrings: TStrings): Boolean;
var
  vColumnCount: Integer;
  vItemCount: Integer;
  I, J: Integer;
  vBuffer: array[0..255] of Char;
  vProcessId: DWORD;
  vProcess: THandle;
  vPointer: Pointer;
  vNumberOfBytesRead: Cardinal;
  S: string;
  vItem: TLVItem;
begin
  Result := False;
  if not Assigned(mStrings) then Exit;
  vColumnCount := ListViewColumnCount(mHandle);
  if vColumnCount <= 0 then Exit;
  vItemCount := ListView_GetItemCount(mHandle);
  GetWindowThreadProcessId(mHandle, @vProcessId);
  vProcess := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
    PROCESS_VM_WRITE, False, vProcessId);
  vPointer := VirtualAllocEx(vProcess, nil, 4096, MEM_RESERVE or MEM_COMMIT,
    PAGE_READWRITE);
  mStrings.BeginUpdate;
  try
    mStrings.Clear;
    for I := 0 to vItemCount - 1 do begin
      S := '';
      for J := 0 to vColumnCount - 1 do begin
        with vItem do begin
          mask := LVIF_TEXT;
          iItem := I;
          iSubItem := J;
          cchTextMax := SizeOf(vBuffer);
          pszText := Pointer(Cardinal(vPointer) + SizeOf(TLVItem));
        end;
        WriteProcessMemory(vProcess, vPointer, @vItem,
          SizeOf(TLVItem), vNumberOfBytesRead);
        SendMessage(mHandle, LVM_GETITEM, I, lparam(vPointer));
        ReadProcessMemory(vProcess, Pointer(Cardinal(vPointer) + SizeOf(TLVItem)),
          @vBuffer[0], SizeOf(vBuffer), vNumberOfBytesRead);
        S := S + #9 + vBuffer;
      end;
      Delete(S, 1, 1);

      mStrings.Add(S);
    end;
  finally
    VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);
    CloseHandle(vProcess);
    mStrings.EndUpdate;
  end;
  Result := True;
end; { GetListViewText }

пробовал из разных listview дергать данные - получилось, но из которого надо мне вытащить не получается, у кого какие мысли с чег может быть связанно? может из-за того что Listview создается динамически? структура заполняется не полностью например

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)