在RichTextBox中的某些位置抑制换行

问题描述

| 我需要抑制RichTextBox中的某些换行符。 例如,考虑“ 0”。
6
+
之间不得有换行符。基本上,我正在寻找HTML中的“ѭ3”之类的东西。 到目前为止,我已经弄乱了插入\\ u + FEFF等(在某些机器上可以使用,但是有些显示垂直线,虽然是Windows标准字体,但可能是字体问题)。我也尝试直接操作rtf,即在其中放一些
\\zwnbo
Box.rtf = ...
,但我似乎从来没有正确。 帮助非常感谢。     

解决方法

        是的,您可以将所有RichText API与RichTextBox控件一起使用。 您可能有兴趣看看以下站点: http://www.pinvoke.net/default.aspx/user32.sendmessage-如何使用p / invoke将消息发送到Windows。 您可以使用
RichTextBox
Handle
属性来获取该控件的窗口句柄,然后向其发送消息。 还要看看这些包含Microsoft SDK附带的文件,这些文件不会直接在C#中使用,但是这些文件包含您可能必须使用的所有常量,例如
WB_ISDELIMITER
WB_CLASSIFY
等。 winuser.h richedit.h 在以下示例中,我    演示如何使用API    提供。 编辑: 这个新示例的代码被标记为不安全,但是这样做更好,因为它不会遇到单个字符串的问题,因为我可以使用
char*
参数并对其进行操作。旧示例遵循此示例: 这是C#代码,而不是C ++ ...要进行编译,您将必须转到项目选项并标记复选框以允许运行不安全的代码。 右键单击项目->属性(Alt + Enter)->构建->常规->允许使用不安全的代码(必须选中)
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

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

        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            this.Text = \"abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz\";
            NewMethod();
        }

        unsafe private void NewMethod()
        {
            if (!this.DesignMode)
                SendMessage(this.Handle,EM_SETWORDBREAKPROC,IntPtr.Zero,Marshal.GetFunctionPointerForDelegate(new EditWordBreakProc(MyEditWordBreakProc)));
        }

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

        unsafe delegate int EditWordBreakProc(char* lpch,int ichCurrent,int cch,int code);

        unsafe int MyEditWordBreakProc(char* lpch,int code)
        {
            const int WB_ISDELIMITER = 2;
            const int WB_CLASSIFY = 3;
            if (code == WB_ISDELIMITER)
            {
                char ch = *lpch;
                return ch == \'-\' ? 0 : 1;
            }
            else if (code == WB_CLASSIFY)
            {
                char ch = *lpch;
                var vResult = Char.GetUnicodeCategory(ch);
                return (int)vResult;
            }
            else
            {
                var lpch2 = lpch;
                // in this case,we must find the begining of a word:
                for (int it = ichCurrent; it < cch; it++)
                {
                    char ch = *lpch2;
                    if (it + 1 < cch && lpch2[0] == \'-\' && lpch2[1] != \'-\')
                        return it;
                    if (lpch2[0] == \'\\0\')
                        return 0;
                    lpch2++;
                }
            }

            return 0;
        }
    }
}
旧样本代码 该示例包含一个继承自RichTextBox的类,并使用
EM_SETWORDBREAKPROC
放置了一个自定义处理程序。此类仅在\'-\'字符上方时才断行。不是之前,也不是之后。
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

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

        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            this.Text = \"abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz\";
            if (!this.DesignMode)
                SendMessage(this.Handle,IntPtr lParam);

        delegate int EditWordBreakProc(string lpch,int code);

        int MyEditWordBreakProc(string lpch,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];
                return ch == \'-\' ? 0 : 1;
            }
            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
            {
                if (lpch.Length == 0 || lpch == null) return 0;
                for (int it = ichCurrent; it < lpch.Length; it++)
                {
                    char ch = lpch[it];
                    if (ch != \'-\') return it;
                }
            }

            return 0;
        }
    }
}
这只是草稿,因此您可能需要进一步改进它,才能实现目标。 将控件放在Windows窗体中,然后运行。 调整窗口大小,看看这是否是您想要的! 您将不得不寻找单词边界...我还没有设法使它起作用。     ,        我不确定,但是如果ѭ7确实包裹了Windows丰富的编辑控件,那么阅读以下内容可能会有些运气: http://msdn.microsoft.com/zh-CN/library/hh270412%28v=vs.85%29.aspx 或更具体地说: http://msdn.microsoft.com/zh-cn/library/bb787877%28v=vs.85%29.aspx 我希望这有帮助。     ,        我已经快速尝试过,它似乎可以工作:
this.userControl.richTextBox1.LoadFile(\"C:\\\\test.rtf\");
this.userControl.richTextBox1.Rtf = this.userControl.richTextBox1.Rtf.Replace(@\"\\par\",String.Empty);

this.userControl.richTextBox1.SaveFile(\"C:\\\\test2.rtf\",RichTextBoxStreamType.RichText);
    ,        这是我的解决方案(基于@Miguel Angelo,但进行了一些修改和更正):
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace MyNameSpace
{
    public class SpaceBreakingRichTextBox : RichTextBox
    {
        const int EM_SETWORDBREAKPROC = 0x00D0;
        const int EM_GETWORDBREAKPROC = 0x00D1;

        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            AddDelegate();
        }

        [DllImport(\"User32.DLL\")]
        public static extern IntPtr SendMessage(IntPtr hWnd,int code);
        EditWordBreakProc myDelegate;

        unsafe private void AddDelegate()
        {
            if (!this.DesignMode)
            {
                myDelegate = new EditWordBreakProc(MyEditWordBreakProc);
                SendMessage(this.Handle,Marshal.GetFunctionPointerForDelegate(myDelegate));
            }
        }

        unsafe int MyEditWordBreakProc(char* lpch,int code)
        {
            const int WB_ISDELIMITER = 2;
            const int WB_CLASSIFY = 3;
            const int WB_MOVEWORDLEFT = 4;
            const int WB_MOVEWORDRIGHT = 5;

            const int WB_LEFTBREAK = 6;
            const int WB_RIGHTBREAK = 7;

            const int WB_LEFT = 0;
            const int WB_RIGHT = 1;

            if (code == WB_ISDELIMITER)
            {
                char ch = *lpch;
                return ch == \' \' ? 1 : 0;
            }
            else if (code == WB_CLASSIFY)
            {
                char ch = *lpch;
                var vResult = Char.GetUnicodeCategory(ch);
                return (int)vResult;
            }
            else if (code == WB_LEFTBREAK)
            {
                for (int it = ichCurrent; it >= 0; it--)
                {
                    if (lpch[it] == \' \'/* && lpch2[1] != \' \'*/)
                    {
                        if (it > 0 && lpch[it - 1] != \' \')
                            return it;
                    }
                }
            }
            else if (code == WB_RIGHT)
            {
                for (int it = ichCurrent; ; it++)
                {
                    if (lpch[it] != \' \')
                        return it;
                }
            }
            else
            {
                 // There might be more cases to handle (see constants)
            }
            return 0;
        }
    }
}
请注意,您需要保留委托方法,否则它会从垃圾收集器中收集时崩溃(调试起来很痛苦)。 基本上,此子类仅在空格处中断,这足以满足当前的需求。