首页  编辑  

如何抓取外部的ListView?

Tags: /超级猛料/VCL/ListView/   Date Created:

Q:我想抓取外部的程序的Listview,并在自己的程序中写出来,怎么做?我用ListView_GetItem进行获取,可是不能获取数据,而且出现AV错误?

A:原因在于,ListView_GetItem读取和写入数据的时候,它必须访问本进程内的内存才会正常工作,如果不是本进程内地数据,就会发生AV错误。因此我们必须用特殊的方式分配内存。附件中的例子,就很好的演示了如何或取其他程序中的ListView。

运行程序,用鼠标指向一个ListView控件,然后按F12,回到程序,你就会发现,ListView已经被抓下来了。

zswang:

获取不同进程ListView的内容~~

(*//

标题:获取不同进程ListView的内容

说明:适用于WindowsNT

日期:2003-02-27

设计:Zswang

//*)

unit Unit1;

interface

uses

 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

 Dialogs, StdCtrls, ComCtrls;

type

 TForm1 = class(TForm)

   MemoText: TMemo;

   EditCount: TEdit;

   LabelNote: TLabel;

   procedure FormCreate(Sender: TObject);

   procedure FormDestroy(Sender: TObject);

 private

   { Private declarations }

   procedure WMHOTKEY(var Msg: TWMHOTKEY); message WM_HOTKEY;

 public

   { Public declarations }

 end;

var

 Form1: TForm1;

implementation

{$R *.dfm}

uses CommCtrl;

function VirtualAllocEx(hProcess: Cardinal; lpAddress: Pointer;

 dwSize, flAllocationType, flProtect: Cardinal): Pointer; stdcall;

 external kernel32 name ''VirtualAllocEx'';

function VirtualFreeEx(hProcess: Cardinal; lpAddress: Pointer;

 dwSize, dwFreeType: Cardinal): Boolean; stdcall;

 external kernel32 name ''VirtualFreeEx'';

   

const cHotKeyWinF2 = 1;

procedure TForm1.FormCreate(Sender: TObject);

begin

 Application.Title := ''获取ListView内容 1.0'';

 Caption := Application.Title;

 RegisterHotKey(Handle, cHotKeyWinF2, MOD_WIN, VK_F2);

end;

procedure TForm1.WMHOTKEY(var Msg: TWMHOTKEY);

var

 I, J: Integer;

 S: string;

 vItem: TLVItem;

 vCount: Integer;

 vHandle: THandle;

 vBuffer: array[0..255] of Char;

 pBuffer: PChar;

 vProcess: THandle;

 vProcessId: DWORD;

 vPointer: Pointer;

 vNumberOfBytesRead: Cardinal;

begin

 case Msg.HotKey of

   cHotKeyWinF2: begin

     MemoText.Clear;

     FillChar(vBuffer, 256, 0);

     vHandle := WindowFromPoint(Point(Mouse.CursorPos.X, Mouse.CursorPos.Y));

     vCount := ListView_GetItemCount(vHandle);

     if vCount = 0 then Exit;

     GetWindowThreadProcessId(vHandle, @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);

     try

       for I := 0 to vCount - 1 do begin

         S := '''';

         for J := 0 to StrToIntDef(EditCount.Text, 0) - 1 do begin

           with vItem do begin

             mask := LVIF_TEXT;

             iItem := I;

             iSubItem := J;

             cchTextMax := 255;

             pszText := Pointer(Cardinal(vPointer) + SizeOf(TLVItem));

           end;

           WriteProcessMemory(vProcess, vPointer, @vItem,

             SizeOf(TLVItem), vNumberOfBytesRead);

           SendMessage(vHandle, LVM_GETITEM, I, lparam(vPointer));

           pBuffer := vBuffer;

           ReadProcessMemory(vProcess, Pointer(Cardinal(vPointer) + SizeOf(TLVItem)),

             pBuffer, DWORD(256), vNumberOfBytesRead);

           S := S + #9 + vBuffer;

         end;

         Delete(S, 1, 1);

         MemoText.Lines.Add(S);

       end;

     finally

       VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);

       CloseHandle(vProcess);

     end;

   end;

 end;

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

 UnRegisterHotKey(Handle, cHotKeyWinF2);

end;

end.

GrabListView.zip (227.8KB)