Получение размера иконки на рабочем столе с сообщением LVM_GETITEMRECT - PullRequest
3 голосов
/ 16 сентября 2011

Я боролся с этим всю ночь. Я просто не понимаю, что не так. Я пытаюсь получить значок на рабочем столе + размер подписи. У меня есть некоторые функции, которые находят дескриптор рабочего стола и помещают его в переменную с именем SysListView32_hwnd. Я подтвердил, что это правильно с шпионской программой Windows. Вот часть, с которой у меня проблемы.

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);

Вылетает исследователь каждый раз. C # Visual Studio 2010 Windows 7 x64, и я компилирую как 64-битную программу

Здесь - мое полное приложение, если необходимо

Ответы [ 2 ]

2 голосов
/ 17 сентября 2011

Здесь рассматриваются дополнительные вопросы, заданные в расширенном редактировании вопроса.

Мне кажется, что мы работаем с LVITEMs, но VirtualAllocEx указывает sizeof(uint).

Документация по параметру dwSize для VirtualAllocEx() в MSDN гласит:

Размер области памяти, выделяемой в байтах.

Если lpAddress равен NULL, функция округляет dwSize до границы следующей страницы.

Если lpAddress не равен NULL, функция выделяет все страницы, содержащие один или несколько байтов в диапазоне от lpAddress до lpAddress + dwSize. Это означает, например, что 2-байтовый диапазон, который пересекает границу страницы, заставляет функцию выделять обе страницы.

Другими словами, он выделяет целые страницы. Поскольку страница размером 4 КБ, вам повезло. Вы должны убедиться, что dwSize достаточно большой для нужного вам буфера.

Почему pszText = (IntPtr) ((int) lpBaseAddress + Marshal.SizeOf (typeof (LVITEM)))? Разве это не просто указывает на конец структуры.

Да, это указывает на конец структуры. Дело в том, что поле pszText в LVITEM должно указывать на буфер, выделенный вызывающей стороной. Кто бы ни написал этот код, он решил использовать свободное место в буфере в конце структуры. Поскольку структура объявляет, что pszText содержит 256 байтов, это легко уместится в остатки страницы размером 4 КБ. Так что это работает, но немного непрозрачно.

1 голос
/ 16 сентября 2011

Это относится к исходному вопросу перед расширенным редактированием.

Не удается, потому что, как вы написали, он может работать только при вызове из процесса, которому принадлежит дескриптор целевого окна,Это потому, что вы передаете указатель, но это допустимо только в вашем процессе.Как только он попадает в другой процесс, он обращается к бессмысленному адресу.И даже если это действительно что-то значит, процесс не может прочитать память другого процесса с помощью системы.Естественно, бомбы исследователя.

Решение состоит в том, чтобы использовать VirtualAllocEx() для выделения памяти в процессе проводника.Затем отправьте сообщение.Затем используйте ReadProcessMemory(), чтобы перенести содержимое прямоугольника обратно в ваш процесс.Наиболее часто цитируемым примером кода для этого является статья проекта кода .В этом примере используется LVM_GETITEMTEXT, но принципы идентичны.

...