如何利用Win32API取得另一支程式中的ListView內的所有值

unit GetListViewDatas;

interface

uses
  Windows, Messages, SysUtils, CommCtrl, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TFormGetListViewDatas = class(TForm)
    mmoText: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    procedure WMHOTKEY(var Msg: TWMHOTKEY); message WM_HOTKEY;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FormGetListViewDatas: TFormGetListViewDatas;

implementation

{$R *.dfm}

function ListViewColumnCount(mHandle: THandle): Integer;  
begin 
  Result := Header_GetItemCount(ListView_GetHeader(mHandle));  
end;

function GetListViewSelectText(mHandle: THandle;var mStrings: string): Boolean;  
var 
  vColumnCount: Integer;
  I, J: Integer;
  vBuffer: array[0..255] of Char;  
  vProcessId: DWORD;  
  vProcess: THandle;  
  vPointer: Pointer;  
  vNumberOfBytesRead: Cardinal;  
  vItem: TLVItem;
begin 
  Result := False;  
  I := ListView_GetNextItem(mHandle, -1, LVNI_SELECTED);  
  if I = -1 then 
    Exit;  

  vColumnCount := ListViewColumnCount(mHandle);  
  if vColumnCount <= 0 then Exit;
  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);  

  try
    mStrings := '';  
    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);  
      mStrings := mStrings + #9 + vBuffer;  
    end;  
  finally 
    VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);  
    CloseHandle(vProcess);
  end;  
  Result := True;  
end;

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;

procedure TFormGetListViewDatas.FormCreate(Sender: TObject);
begin
  RegisterHotKey(Handle, 1, MOD_WIN, VK_F3);
end;

procedure TFormGetListViewDatas.WMHOTKEY(var Msg: TWMHOTKEY);
begin
  case Msg.HotKey of
    1:
      GetListViewText(
        WindowFromPoint(Point(Mouse.CursorPos.X, Mouse.CursorPos.Y)),
        mmoText.Lines);
  end;  
end;

procedure TFormGetListViewDatas.FormDestroy(Sender: TObject);
begin
  UnRegisterHotKey(Handle, 1);
end;

end.

你可能感兴趣的:(如何利用Win32API取得另一支程式中的ListView內的所有值)