I've been fighting with this all night. I just don't what is wrong. I'm trying to get the desktop icon + caption size. I have some functions that find the desktop handle and put it in a variable called SysListView32_hwnd. I have verified it is correct with a windows spy program. Here is the part I am having trouble with.
Rectangle rct = new Rectangle();
IntPtr pRct = Marshal.AllocHGlobal(Marshal.SizeOf(rct));
Marshal.StructureToPtr(rct, pRct, true);
SendMessage(SysListView32_hwnd, LVM_GETITEMRECT, (IntPtr)0, pRct);
Rectangle Rect = (Rectangle)Marshal.PtrToStructure(pRct, typeof(Rectangle));
Marshal.FreeHGlobal(pRct);
Debug.WriteLine(Rect.Height + " " + Rect.Width);
It crashes explorer every time. C# Visual Studio 2010 Windows 7 x64 and I am compiling as a 64 bit program
Here is my full app if needed
This addresses the original question before the extensive edit.
It fails because, the way you have written it can only work when you call from the process that owns the target window handle. This is because you pass a pointer, but that is only valid in your process. As soon as it lands in the other process it refers to an address that is meaningless. And even if it did mean something, a process can't read another processes memory with help from the system. Naturally explorer bombs.
The solution is to use
VirtualAllocEx()to allocate memory in the explorer process. Then send the message. Then useReadProcessMemory()to marshal the contents of the rect back into your process. The most commonly cited code sample for this is this Code Project article. That example is usingLVM_GETITEMTEXTbut the principles are identical.