Reputation: 73
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
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