下划线充当分隔符C#RTF Box

时间:2013-07-26 02:09:52

标签: c# find richtextbox

我正在使用Winforms应用程序并在RichTextBox控件上使用Find来查找要设置样式的特定关键字。

出于某种原因,尽管指定了WholeWord标志,但Find似乎将带有下划线的单词视为2个单独的单词(并将匹配的一半设置为样式)。

函数调用是:

richTextBox1.Find("Keyword", RichTextBoxFinds.MatchCase | RichTextBoxFinds.WholeWord);

为什么会这样?我能以某种方式覆盖/修复它吗?

1 个答案:

答案 0 :(得分:1)

你可以,虽然它有点毛茸茸。您需要为富文本框指定custom word breaking procedure,并且要覆盖某些情况,否则使用默认处理程序。在C ++中,它非常简单;在C#中,没有那么多。 This question描述了设置;我已经更新它以保存旧的proc以处理其他情况。

namespace q6359774
{
    class MyRichTextBox : RichTextBox
    {
        const int EM_SETWORDBREAKPROC = 0x00D0;
        const int EM_GETWORDBREAKPROC = 0x00D1;


        delegate int EditWordBreakProc(string lpch, int ichCurrent, int cch, int code);

    EditWordBreakProc oldEditWordBreakProc; 

        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            this.Text = "abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz";
            if (!this.DesignMode)
        {
                IntPtr oldproc;
                oldproc = SendMessage(this.Handle, EM_SETWORDBREAKPROC, IntPtr.Zero, Marshal.GetFunctionPointerForDelegate(new EditWordBreakProc(MyEditWordBreakProc)));
                oldEditWordBreakProc = Marshal.GetDelegateForFunctionPointer(oldproc, typeof(EditWordBreakProc));
            }
        }

        [DllImport("User32.DLL")]
        public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);


        int MyEditWordBreakProc(string lpch, int ichCurrent, int cch, int code)
        {
            const int WB_ISDELIMITER = 2;
            const int WB_CLASSIFY = 3;
            if (code == WB_ISDELIMITER)
            {
                if (lpch.Length == 0 || lpch == null) return 0;
                char ch = lpch[ichCurrent];
                if (ch == '_')
        {
                     return 0;
                }
                else return oldEditWordBreakProc(lpch, ichCurrent, cch, code);
            }
            else if (code == WB_CLASSIFY)
            {
                if (lpch.Length == 0 || lpch == null) return 0;
                char ch = lpch[ichCurrent];
                var vResult = Char.GetUnicodeCategory(ch);
                return (int)vResult;
            }
            else return oldEditWordBreakProc(lpch, ichCurrent, cch, code);
        }
    }
}