How to get the highlighted item from the desktop or Windows Explorer with syslistview32?
Ho开发者_如何学Gow might I, using Delphi and syslistview32, get the highlighted item from the desktop or Windows Explorer?
I'm not sure what you mean with get item, so I posted here how to get the focused item text. It's more complicated task because list view messages can't fill the buffer between processes, so you need to pass it through the virtual memory pages allocated in the foreign process. But the principle would be the same for any kind of manipulation with foreign items directly. I'm not familiar with process memory allocation; any useful edit will be appreciated.
Note: the code below has been tested on 32 bit 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;
And here's how to call; just pass the handle to it and you'll get the item's text
procedure TForm1.Button1Click(Sender: TObject);
var s: string;
begin
s := GetItemText(123456);
if s <> '' then
ShowMessage(s);
end;
精彩评论