none
Ссылки в RichTextBox RRS feed

  • Вопрос

  • Работаю с RichTextBox, и мне необходимо отловить когда пользователь правой кнопкой мыши жмёт на ссылку для вызова контекстного меню, в котором я хочу добавить команду "копировать ссылку", посоветовали воспользоваься winapi, мне удалось отловить правый клик, но текст ссылки получить не удаёться. Вот код моей программы:
    private const int WM_NOTIFY = 0x4E;
    public const int EM_GETTEXTRANGE = 0x44B;
    const int EN_LINK = 1803;
    const int WM_RBUTTONDOWN = 516;
    private struct NMHDR
    {
        public IntPtr hwndFrom;
        public int idFrom;
        public int code;
    }
    private struct CHARRANGE
    {
        public long cpMin;
        public long cpMax;
    }
    private struct ENLINK
    {
        public NMHDR nmhdr;
        public int msg;
        public IntPtr wParam;
        public IntPtr lParam;
        public CHARRANGE chrg;
    }
    private struct TEXTRANGE
    {
        public CHARRANGE chrg;
        public string lpstrText;
    }
    [DllImport("user32")]
    private static extern IntPtr SendMessage(IntPtr hwnd, UInt32 wMsg, IntPtr wParam, IntPtr lParam);
    
    public Form1()
    {
        InitializeComponent();
    }
    
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_NOTIFY)
        {
            NMHDR nm = (NMHDR)m.GetLParam(typeof(NMHDR));
            if (nm.code == EN_LINK)
            {
                ENLINK enlink = (ENLINK)m.GetLParam(typeof(ENLINK));
                if (enlink.msg == WM_RBUTTONDOWN)
                {
                    TEXTRANGE tr = new TEXTRANGE();
                    tr.chrg.cpMin = enlink.chrg.cpMin;
                    tr.chrg.cpMax = enlink.chrg.cpMax;
                    tr.lpstrText = new string(new char[1024]);
                    IntPtr trHandle = Marshal.AllocHGlobal(Marshal.SizeOf(tr));
                    Marshal.StructureToPtr(tr, trHandle,true);
                    IntPtr lLen = SendMessage(rtfBox1.Handle, (UInt32)EM_GETTEXTRANGE, IntPtr.Zero, trHandle);
                    string text = ((String)tr.lpstrText).Substring(0,(int)lLen);
                    Debug.WriteLine(text);
                }
            }
    
        }
        base.WndProc(ref m);
    }
    
    • Перемещено I.Vorontsov 5 февраля 2010 г. 10:28 (От:Visual C#)
    • Перемещено Tagore Bandlamudi 2 октября 2010 г. 22:23 MSDN Forums consolidation (От:Разработка Windows-приложений)
    3 февраля 2010 г. 9:21

Ответы

  • А если обрабатывать событие MouseDown.
    1.Проверить на правую кнопку.
    2. Следующим образом

    int charIndex = rtb.GetCharIndexFromPosition(new Point(e.X, e.Y));

    определить слово на которое сделан клик  (Между двумя пробелами, в RichTextBox линки находятся следующим образом "Link#http://link.link").

    3. И используя

    Regex re = new Regex("http://(www\\.)?([^\\.]+)\\.([^\\.]+)");
    bool isLink = re.IsMatch(clickedWord);

    Определить линку.
    • Предложено в качестве ответа I.Vorontsov 4 февраля 2010 г. 8:20
    • Помечено в качестве ответа I.Vorontsov 4 февраля 2010 г. 8:20
    3 февраля 2010 г. 13:10

Все ответы

  • Посмотрите реализацию в библиотеки RichTextBoxLinks
    3 февраля 2010 г. 11:42
  • К сожалению, в данном примере реалиована вставка ссылок, мне же необходимо отследить нажатие на ссылку и далее взять эту ссылку.
    3 февраля 2010 г. 12:17
  • А если обрабатывать событие MouseDown.
    1.Проверить на правую кнопку.
    2. Следующим образом

    int charIndex = rtb.GetCharIndexFromPosition(new Point(e.X, e.Y));

    определить слово на которое сделан клик  (Между двумя пробелами, в RichTextBox линки находятся следующим образом "Link#http://link.link").

    3. И используя

    Regex re = new Regex("http://(www\\.)?([^\\.]+)\\.([^\\.]+)");
    bool isLink = re.IsMatch(clickedWord);

    Определить линку.
    • Предложено в качестве ответа I.Vorontsov 4 февраля 2010 г. 8:20
    • Помечено в качестве ответа I.Vorontsov 4 февраля 2010 г. 8:20
    3 февраля 2010 г. 13:10
  • Да, спасибо я примерно так и это и сделал, но очень жаль что не вышло это сделать с помощью winapi.
    3 февраля 2010 г. 17:12