I need to override the RichTextBox GetPositionFromCharIndex(int index) method and implement it by myself because of a performance issue in my app.
The EM_POSFROMCHAR message return the point in wParam:
EM_POSFROMCHAR
wParam = (LPPOINT) lpPoint; // address of structure receiving character position
lParam = (LPARAM) wCharIndex; // zero-based index of character
I have tried to define the POINT structure as a structure in C# but I'm getting an Attempt to read or write protected memory error at runtime. When I define the POINT structure as a class everything works fine. Since I make an very intensive use of this method in my app I think the structure implementation is the right choice and it will perform better from the garbage collection point of view.
Here are both codes, the POINT class solution and the POINT structure one. Can somebody help me to make the structure version to work?
Thanks in advance.
//Class version (working)
Expand|Select|Wrap|Line Numbers
- [DllImport("user32.dll", CharSet = CharSet.Auto)]
- static extern IntPtr SendMessage(IntPtr hWnd, int msg, POINT wParam, IntPtr lParam);
- private const int WM_USER = 0x400;
- private const int EM_POSFROMCHAR = WM_USER + 38;
- [StructLayout(LayoutKind.Sequential)]
- internal class POINT
- {
- public int x, y;
- public POINT()
- {
- }
- public POINT(int x, int y)
- {
- this.x = x;
- this.y = y;
- }
- }
- public override Point GetPositionFromCharIndex(int index)
- {
- POINT wParam = new POINT();
- SendMessage(this.Handle, EM_POSFROMCHAR, wParam, (IntPtr)index);
- return new Point(wParam.x, wParam.y);
- }
Expand|Select|Wrap|Line Numbers
- [DllImport("user32.dll", CharSet = CharSet.Auto)]
- static extern IntPtr SendMessage(IntPtr hWnd, int msg, ref POINT wParam, IntPtr lParam);
- private const int WM_USER = 0x400;
- private const int EM_POSFROMCHAR = WM_USER + 38;
- [StructLayout(LayoutKind.Sequential)]
- private struct POINT
- {
- public int x, y;
- public POINT(int x, int y)
- {
- this.x = x;
- this.y = y;
- }
- }
- public override Point GetPositionFromCharIndex(int index)
- {
- POINT wParam = new POINT();
- SendMessage(this.Handle, EM_POSFROMCHAR, ref wParam, (IntPtr)index);
- return new Point(wParam.x, wParam.y);
- }