Ваша проблема на самом деле в том, что вы передаете sb.Length
в сообщении WM_GETTEXT
, когда на самом деле вы должны передавать sb.Capacity
или даже просто length
.
Я бы сделал это такэто:
if (length > 0 && length < int.MaxValue)
{
StringBuilder sb = new StringBuilder(length+1);
SendMessageGetText(handler, WM_GETTEXT, (IntPtr)length+1, sb);
return sb.ToString();
}
Я бы также отметил, что WM_GETTEXT
не вернет больше, чем 64 000 символов, к length < int.MaxValue
не то, что вам нужно.
ИзКонечно, в более долгосрочной перспективе может быть лучше использовать Unicode повсеместно, чтобы вы могли поддерживать международный текст.
Я лично всегда выбрал бы использование API Unicode и использовал бы следующие объявления p / invoke:
[DllImport("User32.dll", EntryPoint = "SendMessage",
CharSet = CharSet.Unicode, SetLastError = true)]
extern static int SendMessageGetTextLength(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
[DllImport("User32.dll", EntryPoint = "SendMessage",
CharSet = CharSet.Unicode, SetLastError = true)]
extern static IntPtr SendMessageGetText(IntPtr hWnd, int msg, IntPtr wParam, StringBuilder lParam);
[DllImport("user32.dll", EntryPoint = "FindWindowEx",
CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);