C# - How can I get a text range from WordPad by sending the EM_GETTEXTRANGE message?
I'm having trouble getting a text range from a running instance of WordPad. I have gotten the following Windows messages to work for WordPad without a problem: WM_GETTEXT, WM_GETTEXTLENGTH, EM_REPLACESEL, EM_GETSEL, and EM_SETSEL. I'm not having any luck with the EM_GETTEXTRANGE message though.
In my C# test app I have some code that runs at startup which looks for a running instance of WordPad, then searches it's child windows for the window with the class name RICHEDIT50W. This is the window that I send messages to. Again, all of the messages I have sent this window work fine except for EM_GETTEXTRANGE. After sending EM_GETTEXTRANGE, Marshal.GetLastWin32Error returns 5, which MSDN says is ERROR_ACCESS_DENIED. Below is some of my interop code. Can someone please help me solve the problem? Thanks!
const uint WM_USER = 0x0400;
const uint EM_GETTEXTRANGE = WM_USER + 75;
[StructLayout(LayoutKind.Sequential)]
struct CharRange
{
public int min;
public int max;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct TextRange
{
public CharRange charRange;
[MarshalAs(UnmanagedType.LPWStr)]
public string text;
}
[DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
extern static int SendMessage(IntPtr hWnd, uint Msg, int wParam, ref TextRange lParam);
public static string GetTextRang开发者_运维技巧e(IntPtr wnd, int min, int max)
{
TextRange textRange = new TextRange();
textRange.charRange.min = min;
textRange.charRange.max = max;
textRange.text = new string('\0', max - min);
int length = SendMessage(wnd, EM_GETTEXTRANGE, 0, ref textRange);
int error = Marshal.GetLastWin32Error();
return error == 0 ? textRange.text : string.Empty;
}
I found the answer to my own problem. When calling SendMessage targeting a window in another process, the parameters have to be allocated in target process memory for all messages that are >= WM_USER. Everything needed can be done by pinvoking the functions VirtualAllocEx, VirtualFreeEx, ReadProcessMemory, and WriteProcessMemory. It was brought up in another question at how to use EM_GETTEXTRANGE with WriteProcessMemory and ReadProcessMemory, but I originally didn't think this was applicable to what I was doing because I didn't fully understand the problem.
精彩评论