Einzelnen Beitrag anzeigen

Gast
(Gast)

n/a Beiträge
 
#1

Text aus Common Control in fremden Prozess (anhand TreeView)

  Alt 7. Jul 2003, 01:38
Windows läßt aus Kompatibilitätsgründen zu, daß bei den grundlegenden Controls (Button, Static, Listbox etc) der Text auch prozessübergreifend zu holen ist. Windows kümmert sich dabei intern um die Formalitäten. Die neueren Controls (zB Common Controls) bieten keine solche Möglichkeit, weshalb man andere Maßnahmen erfreifen muß (anhand eines TreeView):

Delphi-Quellcode:
function GetTreeViewText(hTVwnd: HWND; memo1, memo2: TMemo): pchar;
const
  MAX_TEXT = 256;
type
  TVITEM = TTVITEM;
var
  lpBuf: array[0..MAX_TEXT - 1] of char;
  tvi: TVITEM;

  dwPId: DWORD;
  hProc: THANDLE;
  pText, pAddr: pointer;
  dwTmp: DWORD;
  i, i2, nCount, size: integer;
  chan: integer;
  is_chan: boolean;
// ret, ret_usr, res: TStringList;
begin
// Get ThreadID and ProzessID
  if BOOL(GetWindowThreadProcessId(hTVwnd, @dwPId)) then
// Get a handle to the process with the needed access
    hProc := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, FALSE, dwPId);
  if hProc <> 0 then
  begin
// Allocate memory for thet text to hold in the target process ...
    pText := VirtualAllocEx(hProc, nil, MAX_TEXT, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
// Allocate memory for the TVITEM structure in target process ...
    pAddr := VirtualAllocEx(hProc, nil, sizeof(tvi), MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
// Get number of nodes in the target treeview ...
    nCount := SendMessage(hTVwnd, TVM_GETCOUNT, 0, 0);
// We want the text only ... set some flags in structure
    tvi.mask := TVIF_TEXT;
    tvi.pszText := pText;
    tvi.cchTextMax := MAX_TEXT - 1;
// Get root item handle ...
    tvi.hItem := HTREEITEM(SendMessage(hTVwnd, TVM_GETNEXTITEM, TVGN_ROOT, 0));
// Iterate through the whole treeview and collapse all root child items
// (to avoid flickering and stuff)
    for i := 0 to nCount - 1 do
    begin
// Write our structure (with flags) to the process
      if WriteProcessMemory(hProc, pAddr, @tvi, sizeof(tvi), dwTmp) and
// Get the stuff we need back
      (SendMessage(hTVwnd, TVM_GETITEM, 0, Integer(pAddr)) <> 0) and
// Read the text from the pointer we got ... respect MAX_TEXT
      ReadProcessMemory(hProc, pText, @lpBuf, MAX_TEXT, dwTmp) then
      begin
// If successful and not root item, collapse it.
        if (i > 0) then
// Collapse the item ... next visible item will be a child item of the root, too
          SendMessage(hTVwnd, TVM_EXPAND, TVE_COLLAPSE, Integer(tvi.hItem));
// Get handle to next visible item ...
        tvi.hItem := HTREEITEM(SendMessage(hTVwnd, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, Integer(tvi.hItem)));
// Break here if we face the last visible item ...
        if tvi.hItem = HTREEITEM(0) then break;
      end
// If not successful break here ...
      else
        break;
    end;
// Get root item again
    tvi.hItem := HTREEITEM(SendMessage(hTVwnd, TVM_GETNEXTITEM, TVGN_ROOT, 0));
// ... and iterate through the treeview once more ...
    for i := 0 to (nCount - 1) do
    begin
// Write our structure (with flags) to the process
      if WriteProcessMemory(hProc, pAddr, @tvi, sizeof(TV_ITEM), dwTmp) and
// Get the stuff we need back
      (SendMessage(hTVwnd, TVM_GETITEM, 0, Integer(pAddr)) <> 0) and
// Read the text from the pointer we got ... respect MAX_TEXT
      ReadProcessMemory(hProc, pText, @lpBuf, MAX_TEXT, dwTmp) then
      begin
// If successful and not root item, get text ...
        if (i > 0) then
          memo1.Lines.Append(string(lpBuf));
// Get handle to next visible item ...
        tvi.hItem := HTREEITEM(SendMessage(hTVwnd, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, Integer(tvi.hItem)));
      end else break;
    end;
// Get root item again
    tvi.hItem := HTREEITEM(SendMessage(hTVwnd, TVM_GETNEXTITEM, TVGN_ROOT, 0));
// ... and iterate through the treeview once more ...
    for i := 0 to (nCount - 1) do
    begin
      if WriteProcessMemory(hProc, pAddr, @tvi, sizeof(TV_ITEM), dwTmp) and
        (SendMessage(hTVwnd, TVM_GETITEM, 0, Integer(pAddr)) <> 0) and
        ReadProcessMemory(hProc, pText, @lpBuf, MAX_TEXT, dwTmp) then
      begin
        if (i > 0) then SendMessage(hTVwnd, TVM_EXPAND, TVE_EXPAND, Integer(tvi.hItem));
        tvi.hItem := HTREEITEM(SendMessage(hTVwnd, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, Integer(tvi.hItem)));
      end else break;
    end;
// Get Items
    tvi.hItem := HTREEITEM(SendMessage(hTVwnd, TVM_GETNEXTITEM, TVGN_ROOT, 0));
    for i := 0 to (nCount - 1) do
    begin
      if WriteProcessMemory(hProc, pAddr, @tvi, sizeof(TV_ITEM), dwTmp) and
        (SendMessage(hTVwnd, TVM_GETITEM, 0, Integer(pAddr)) <> 0) and
        ReadProcessMemory(hProc, pText, @lpBuf, MAX_TEXT, dwTmp) then
      begin
        if (i > 0) then
          memo2.lines.Append(string(lpBuf));
        tvi.hItem := HTREEITEM(SendMessage(hTVwnd, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, Integer(tvi.hItem)));
      end else break;
    end;
  end; // else: "could not get process handle"

  if Assigned(pAddr) then
    VirtualFreeEx(hProc, pAddr, 0, MEM_RELEASE);
  if Assigned(pText) then
    VirtualFreeEx(hProc, pText, 0, MEM_RELEASE);
  CloseHandle(hProc);
end;
Angehängte Dateien
Dateityp: rar treeviewtext.rar (3,7 KB, 92x aufgerufen)
  Mit Zitat antworten Zitat