AgentAmine
AgentAmine

Reputation: 73

LVM_GETITEMPOSITION

iam trying to set/get desktop icons positions, using LVM_GETITEMPOSITION. setting position works as expected, but getting them is not.

when i sendmessage(DeskHandle, LVM_GETITEMPOSITION, 1, ppt); explorer crashes, and thats obviously because ppt is only valid adress in my process, so i need to inject a dll into explorer's memory adress space.. and thats where i'am stuck again

the problem is returned position is always 0,0

dll :

library Project2_dll;

uses
  SysUtils,Classes,windows,messages,dialogs,commctrl;

{$R *.res}

procedure hookit; stdcall;
var ppt:tpoint;
    Desktop,DeskHandle : hwnd;
    DeskThread : cardinal;
begin
  Desktop := FindWindow('ProgMan', nil);
  Desktop := FindWindowEx(Desktop, 0, 'SHELLDLL_DefView', nil);
  DeskThread := GetWindowThreadProcessID(Desktop, nil);
  DeskHandle := FindWindowEx(Desktop, 0, 'SysListView32', nil);

  sendmessage(DeskHandle, LVM_GETITEMPOSITION, 1, Longint(@ppt) );
  showmessage(inttostr(ppt.X)+'  '+inttostr(ppt.Y));
end;

exports hookit;

begin

end.

exe :

var
  lib : hwnd;
  prc: procedure; stdcall;

procedure TForm2.Button1Click(Sender: TObject);
var hListView : HWND;
    DeskThread : cardinal;
begin
  hListView := FindWindow('ProgMan', nil);
  hListView := FindWindowEx(hListView, 0, 'SHELLDLL_DefView', nil);
  DeskThread := GetWindowThreadProcessID(hListView, nil);

  lib:= LoadLibrary('Project2_dll.dll');
  prc := GetProcAddress(lib, 'hookit');

  HH := SetWindowsHookEx(WH_MOUSE,GetProcAddress(lib, 'getit'),lib,DeskThread);

  prc;
end;

i already seen some similar questions here at SO, none was helpful.

ps : running this in Delphi XE, windows 7 x64, and assuming SysListView32 is always a child of progman (not a WorkerW)

any help is appreciated ^_^

Upvotes: 1

Views: 1101

Answers (1)

David Heffernan
David Heffernan

Reputation: 613392

You can't inject a 32 bit DLL into a 64 bit process. In order to inject a DLL into 64 bit explorer you are going to need to get XE2 or XE3 and build a 64 bit DLL. Or write this part of your code in C++ if you do not have access to 64 bit Delphi.

As it happens, your code doesn't inject anyway. It just calls SendMessage from your process. Injection typically involves a call to CreateRemoteThread.

In fact you don't need to inject. You can use VirtualAllocEx to allocate memory in the explorer process. You can then pass that address in your SendMessage. Since that memory is in the other process, you'll have to use ReadProcessMemory and WriteProcessMemory to access it. You will still need to do this from a 64 bit process though.

I would have thought that the shell provides facilities for you to obtain this information without hacking the explorer processes memory.

Upvotes: 4

Related Questions