如何使用syslistview32从桌面或Windows资源管理器中获取突出显示的项目?

时间:2011-05-11 02:34:35

标签: delphi

我如何使用Delphi和syslistview32从桌面或Windows资源管理器中获取突出显示的项目?

1 个答案:

答案 0 :(得分:0)

我不确定你对get item的意思,所以我在这里发布了如何获得重点项目文本。这是一项更复杂的任务,因为列表视图消息无法填充进程之间的缓冲区,因此您需要将其传递到外部进程中分配的虚拟内存页。但是对于任何直接操纵外国物品的原则都是一样的。我不熟悉进程内存分配;任何有用的编辑将不胜感激。

注意:以下代码已经在32位Windows XP上进行了测试

function GetFocusedItemText(const LVHandle: HWND): string;
var Size: cardinal;
    Process: THandle;
    ProcessId: DWORD;
    MemLocal: pointer;
    MemRemote: pointer;
    NumBytes: cardinal;
    ItemIndex: integer;

begin
  Result := '';

  ItemIndex := SendMessage(LVHandle, LVM_GETNEXTITEM, -1, LVNI_SELECTED);

  GetWindowThreadProcessId(LVHandle, @ProcessId);
  Process := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False, ProcessId);

  if (ItemIndex <> -1) and (Process <> 0) then
  try
    Size := SizeOf(TLVItem) + SizeOf(Char) * MAX_PATH + 1;
    MemLocal := VirtualAlloc(nil, Size, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
    MemRemote := VirtualAllocEx(Process, nil, Size, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);

    if Assigned(MemLocal) and Assigned(MemRemote) then
      try
        ZeroMemory(MemLocal, SizeOf(TLVItem));

        with PLVItem(MemLocal)^ do
          begin
            mask := LVIF_TEXT;
            iItem := ItemIndex;
            pszText := LPTSTR(Cardinal(MemRemote) + Cardinal(SizeOf(TLVItem)));
            cchTextMax := MAX_PATH;
          end;

        NumBytes := 0;

        if WriteProcessMemory(Process, MemRemote, MemLocal, Size, NumBytes) then
          if SendMessage(LVHandle, LVM_GETITEM, 0, LPARAM(MemRemote)) <> 0 then
            if ReadProcessMemory(Process, MemRemote, MemLocal, Size, NumBytes) then
              Result := string(PChar(Cardinal(MemLocal) + Cardinal(SizeOf(TLVItem))));

      except on E: Exception do
        ShowMessage('Something bad happened :(' + sLineBreak + E.Message);
      end;

    if Assigned(MemRemote) then
      VirtualFreeEx(Process, MemRemote, 0, MEM_RELEASE);

    if Assigned(MemLocal) then
      VirtualFree(MemLocal, 0, MEM_RELEASE);

  finally
    CloseHandle(Process);
  end;
end;

以下是如何打电话;只需将句柄传递给它,你就会得到项目的文字

procedure TForm1.Button1Click(Sender: TObject);
var s: string;
begin
  s := GetItemText(123456);

  if s <> '' then
    ShowMessage(s);
end;