Как использовать EM_CHARFROMPOS с RichTextBox в C # - PullRequest
2 голосов
/ 04 октября 2010

Я пытаюсь использовать следующий код для получения индекса символа по позиции в RichTextBox . Я знаю, что могу использовать метод GetCharIndexFromPosition , предоставленный RichTextBox Class, но я хочу знать, что не так с кодом:

SendMessage это импорт:

[DllImport("User32.dll", EntryPoint = "SendMessage", CharSet= CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, ref POINTL lParam);

А потом этот звонок:

int returnVal = (int)WinUser.SendMessage(this._textBox.Handle, (int)WinUser.Message.EM_CHARFROMPOS, 0, ref p);

где p - экземпляр POINTL , содержащий координаты экрана с верхним левым углом RichTextBox в качестве источника.

Структура POINTL определяется как

[StructLayout(LayoutKind.Sequential)]
public struct POINTL
{
    public long x;
    public long y;
}

POINTL p было инициализировано как:

WinUser.POINTL p;
p.x = 0;
p.y = 0;

СЕЙЧАС ПРОБЛЕМА:

Если p инициализируется, как указано выше, returnVal равно 0

Если p - это что-то вроде { x = 10, y = 10} или { x = 1 и y = 1} returnVal равно 1

В обоих случаях функция GetCharIndexFromPosition дает правильный индекс.

1 Ответ

2 голосов
/ 04 октября 2010

Изменить long на int.
(Win32 LONG s - 32-разрядные целые числа, соответствующие .Net int s) * Определен метод

.Net * GetCharIndexFromPosition.как

    public override int GetCharIndexFromPosition(Point pt) { 
        NativeMethods.POINT wpt = new NativeMethods.POINT(pt.X, pt.Y);
        int index = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, Handle), NativeMethods.EM_CHARFROMPOS, 0, wpt); 

        string t = this.Text;
        // EM_CHARFROMPOS will return an invalid number if the last character in the RichEdit
        // is a newline. 
        //
        if (index >= t.Length) { 
            index = Math.Max(t.Length - 1, 0); 
        }
        return index; 
    }

Тип NativeMethods.POINT определяется как

    [StructLayout(LayoutKind.Sequential)] 
    public class POINT {
        public int x; 
        public int y; 

        public POINT() { 
        }

        public POINT(int x, int y) {
            this.x = x; 
            this.y = y;
        } 

#if DEBUG
        public override string ToString() { 
            return "{x=" + x + ", y=" + y + "}";
        }
#endif
    } 
...