procedure ShowItems;
var
ben, zona, ama, selha: THandle;
ListView: hWnd;
PTBButton: ^TTBButton;
Amiga2: TTBButton;
pid: dword; // process ID
ph: dword; // process handle
c1: dword; // dummy variable
begin
ben := FindWindow('IEframe', nil);
zona := FindWindowEx(ben, 0, 'WorkerW', nil);
ama :=FindWindowEx(zona, 0, 'ReBarWindow32', nil);
selha :=FindWindowEx(ama, 0, 'Toolbarwindow32', nil);
// ask the process ID of the other process
GetWindowThreadProcessID(selha, @pid);
// open the other process
ph := OpenProcess(PROCESS_ALL_ACCESS, false, pid);
// allocate memory in the other process
PTBButton := VirtualAllocEx(ph, nil, sizeOf(TBButton), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
SendMessage (selha, TB_GETBUTTON, 2, PTBButton^);
// read the item back from the other process
ReadProcessMemory(ph, PTBButton, @Amiga2, SizeOf(TBButton), c1);
// free the memory of the other process
VirtualFreeEx(ph, PTBButton 0, MEM_RELEASE);
// close handle
CloseHandle(ph);
// now do whatever you please with Amiga2
end;
DragonSlayer
Comment from DragonSlayer
Date: 08/25/2003 08:56AM PDT
Comment
OK some explanation... (umm... I actually just modified a bit of what madshi said in a previous post... hope you dun mind, madshi!):
"Well, you are sending a pointer to the toolbar of another process. The other process now wants to write the requested information to the address you gave in. But the other process writes the information in the address in its own memory/address context. Now in NT we can do the following:
(1) Allocate memory in the context of the other process by using VirtualAllocEx.
(2) Send the toolbar message, giving in the pointer you got from (1). Now the other process can correctly save the requested info to the requested address.
(3) But the info is now in the context of the other process, so we have to use ReadProcessMemory to get access to that info.
(4) Finally you should free the allocated memory from (1) by using VirtualFreeEx.
I'm using this logic quite often, it works absolutely fine. Unfortunately win9x doesn't support VirtualAllocEx/VirtualFreeEx, there comes the undocumented part: You can set up a memory mapped file (CreateFileMapping(-1, ...) + MapViewOfFile). The buffer will be in shared memory (which is shared between all processes system wide), so the other process can successfully write to the address and you can successfully read it - without even using ReadProcessMemory."
There! hope you are happy with the explanation :)