Я пытался получить текст из каждого элемента управления в иерархии. Следующий код работает нормально, если я использую метод unsafe
. Однако использование неуправляемой версии, похоже, нарушает hWnd
, в результате чего hWnd = GetAncestor(hWnd, GetAncestorFlags.GA_PARENT)
жалуется:
System.AccessViolationException: 'Попытка чтения или записи в защищенную память. Это часто указывает на то, что другая память повреждена.
Я проверил, что hWnd
не был изменен после возврата из функции GetWindowTextRaw
, и если я закомментирую второй SendMessage
в этой функции, это не вызовет проблемы (хотя он явно не получит текст окна).
(PS: я использую PInvoke.User32 в NuGet)
// using static PInvoke.User32;
public static string GetWindowTextRaw(IntPtr hWnd) {
// Allocate correct string length first
int length = (int)SendMessage(hWnd, WindowMessage.WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero);
char[] buff = new char[length + 1];
IntPtr iptr = Marshal.AllocHGlobal(buff.Length);
SendMessage(hWnd, WindowMessage.WM_GETTEXT, (IntPtr)(length + 1), iptr);
Marshal.Copy(iptr, buff, 0, length + 1);
Marshal.FreeHGlobal(iptr);
//unsafe
//{
// fixed (char* p = buff)
// SendMessage(hWnd, WindowMessage.WM_GETTEXT, (IntPtr)(length + 1), (IntPtr)p);
//}
return new string(buff).TrimEnd('\0');
}
private void button1_Click(object sender, EventArgs {
POINT p;
IntPtr hWnd;
//while (true)
if (GetCursorPos(out p)) {
hWnd = WindowFromPoint(p); ;
Debug.Print($"{p.x} {p.y} 0x{(int)hWnd:x8}");
while (hWnd != IntPtr.Zero) {
Debug.Print($"{GetWindowTextRaw(hWnd)}");
hWnd = GetAncestor(hWnd, GetAncestorFlags.GA_PARENT);
}
Thread.Sleep(500);
}
}
WM_GETTEXT
унижение. - person Jeroen Mostert   schedule 03.05.2017PInvoke.User32
нет ничего святого. В частности, настоящая функцияSendMessage
. Управляемые оболочки вокруг него - это всего лишь управляемые оболочки. Имейте один, имейте тысячу, если это делает вызов неуправляемого кода безболезненным (аStringBuilder
бесконечно безболезненнее, чем передача указателей). Вы даже можете объявить его как частный метод, если не хотите подвергать остальной мир этой версии. - person Jeroen Mostert   schedule 03.05.2017