using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace WindowsFormsApplication20 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private static Regex word_searcher = new Regex(@"\w+", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private void textBox1_MouseUp(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Middle) {
int global_char_index = textBox1.GetCharIndexFromPosition(new Point(e.X, e.Y));
int line_index = textBox1.GetLineFromCharIndex(global_char_index);
int line_start = textBox1.GetFirstCharIndexFromLine(line_index);
int char_index = global_char_index - line_start;
string line = TextBoxtHelper.GetTextBoxLine(textBox1, line_index);
foreach (Match match in word_searcher.Matches(line)) {
if (match.Success &&
match.Index <= char_index && char_index <= match.Index + match.Length) {
textBox1.SelectionStart = line_start + match.Index;
textBox1.SelectionLength = match.Length;
break;
}
}
}
}
}
static unsafe class TextBoxtHelper {
private const int EM_GETLINE = 0xc4;
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, sbyte* lParam);
public static string GetTextBoxLine(TextBoxBase text_box, int line) {
const int BUFFER_SIZE = 4086;
sbyte[] buffer = new sbyte[BUFFER_SIZE];
fixed (sbyte* p_buffer = buffer) {
// первым word-ом ставим длину буфера, так требует протокол работы сообщения
*((short*)p_buffer) = (short)BUFFER_SIZE;
if (0 == SendMessage(text_box.Handle, EM_GETLINE, line, p_buffer))
return string.Empty;
return new string(p_buffer);
}
}
}
}
C#: правый клик в textBox
Тулза создается, да есть у меня непонятка:
дано: richTextBox, его событие MouseClick, его же многострочный текст, две регексы для выделяемого слова.
цель: тыкнуть правой кнопкой где-то в боксе и, если клик выпал на слово, совпадающее с одной из регекс, выделить слово и вывести контексту с передачей ей самого слова для дальнейших извращений.
что есть: что-то быдлоиндусское, что даже не буду описывать, которое работает только условно, "для вида" и через не тот проход.
Прошу помощи - как выделить правым кликом слово целиком с проверкой по регексе? Перерыл много ресурсов, но либо не могу сформулировать у гугла вопрос, либо глаза слишком косые.
Цитата: BanShee42
как выделить правым кликом слово целиком с проверкой по регексе?
1) обработать ПКМ на вашем контроле
2) получить слово под курсором мыши
3) наложить регулярные выражения на это слово
4) выделить слово
(Извиняюсь, что создал новую тему, вместо сообщения в теме для новичков, ибо не заметил)
Цитата: BanShee42
hardcase, именно так. 1, 3 и 4й пукнты реализуемы, проблема только со вторым.
(Извиняюсь, что создал новую тему, вместо сообщения в теме для новичков, ибо не заметил)
(Извиняюсь, что создал новую тему, вместо сообщения в теме для новичков, ибо не заметил)
Для того, чтобы получить слово, находящееся аккуратно под указателем мыши можно использовать следующий код (к сожалению без unsafe не обошлось):
Код:
- получаем глобальный индекс символа над которым (возле которого) находится курсор мыши
- получаем индекс строки в которой он находится
- получаем глобальный индекс символа с которого начинается эта строка
- вычисляем позицию нашего символа в строке (простое вычитание)
- получаем строку
- получаем все слова (все что подходит под регулярное выражение \w+) и находим то, в котором находится наш символ
Огромное спасибо, все работает.