C#以编程方式通过富文本框移动而不会切割线条

时间:2018-01-18 22:34:56

标签: c# winforms fonts richtextbox measure

我正在使用图像/页面方案进行WinForms应用程序(用户通过单击图像的特定区域在图像之间导航)。在一个页面我创建了富文本框,我想在其中加载“规则”以供用户接受。不幸的是,规则比RTB长,所以我不得不应用某种滚动。我不想让用户使用滚动条 - 而是我制作了两个按钮(向上和向下),用户可以通过这些按钮滑过规则 - 用户无法以任何其他方式选择或移动文本。除了一件事之外,一切都很有效 - 单击按钮后,文本会滑动,但是第一行和最后一行的部分正在被剪切(只有部分高度的线在rtb中可见)。

下面我列出了用于制作此类RTB的代码(名为“规则”):

                rules.Clear(); 
                rules.Cursor = Cursors.Default;
                rules.ScrollBars = RichTextBoxScrollBars.Vertical;
                rules.ReadOnly = true;
                rules.KeyPress += rules_KeyPress;
                rules.SelectionChanged += rules_SelectionChanged;
                rules.Location = new System.Drawing.Point(450*this.Width/2000, 550*this.Height/1125);
                Console.WriteLine(rules.Font);
                float size = 16.5F;
                rules.Font = new Font("Microsoft Sans Serif", size);
                Console.WriteLine(rules.Font);
                using (Graphics g = rules.CreateGraphics())
                {
                    rules_line_height = Convert.ToInt32(g.MeasureString("A", rules.Font).Height); //getting the measure of the line
                    Console.WriteLine(rules_line_height);
                }
                int rules_h = 400 * this.Height / 1125; //height of the rtb
                int lines_n = rules_h / rules_line_height; //max number of lines that can be fit in the height
                rules.Size = new System.Drawing.Size(1000 * this.Width / 2000, lines_n*rules_line_height); //height of the rtb adjusted to fill full lines
                rules.ForeColor = Color.White;
                string fileName = "reg_pl.txt";
                string line = "";
                StreamReader file = new System.IO.StreamReader(Directory.GetCurrentDirectory() + "/reg/" + fileName, Encoding.GetEncoding("windows-1250"));
                while ((line = file.ReadLine()) != null)
                {
                    rules.AppendText(line + "\r\n");
                }
                file.Close();
                rules_max = rules.GetMaxRange(); //getting max range of the rtb
                rules_thumb = rules.GetThumb(); //getting size of visible part of the rtb
                rules_loc = 0; // current location visible part compared to the whole rtb
                rules.ScrollBars = RichTextBoxScrollBars.None;
                rules.BorderStyle = BorderStyle.None;
                rules.BackColor = Color.FromArgb(18, 25, 56);
                rules.BringToFront();

我还使用custom_RTB类来获取RTB的最大范围和拇指并滚动到RTB的选定点:

    public class CustomRTB : System.Windows.Forms.RichTextBox
{
    #region API Stuff

    public struct SCROLLINFO
    {
        public int cbSize;
        public int fMask;
        public int min;
        public int max;
        public int nPage;
        public int nPos;
        public int nTrackPos;
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int GetScrollPos(IntPtr hWnd, int nBar);

    [DllImport("user32.dll")]
    private static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw);

    [DllImport("User32.Dll", EntryPoint = "PostMessageA")]
    static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);

    [DllImport("user32")]
    private static extern int GetScrollInfo(IntPtr hwnd, int nBar,
                                       ref SCROLLINFO scrollInfo);
    private const int SB_HORZ = 0x0;
    private const int SB_VERT = 0x1;
    #endregion
    public int HorizontalPosition
    {
        get { return GetScrollPos((IntPtr)this.Handle, SB_HORZ); }
        set { SetScrollPos((IntPtr)this.Handle, SB_HORZ, value, true); }
    }

    public int VerticalPosition
    {
        get { return GetScrollPos((IntPtr)this.Handle, SB_VERT); }
        set { SetScrollPos((IntPtr)this.Handle, SB_VERT, value, true); }
    }

    public void ScrollTo(int Position)
    {
        SetScrollPos((IntPtr)this.Handle, 0x1, Position, true);
        PostMessage((IntPtr)this.Handle, 0x115, 4 + 0x10000 * Position, 0);
    }


    public int GetMaxRange()
    {
        SCROLLINFO scrollInfo = new SCROLLINFO();
        scrollInfo.cbSize = Marshal.SizeOf(scrollInfo);
        //SIF_RANGE = 0x1, SIF_TRACKPOS = 0x10,  SIF_PAGE= 0x2
        scrollInfo.fMask = 0x10 | 0x1 | 0x2;
        GetScrollInfo((IntPtr)this.Handle, 1, ref scrollInfo);//nBar = 1 -> VScrollbar
        return scrollInfo.max;
    }

    public int GetThumb()
    {
        SCROLLINFO scrollInfo = new SCROLLINFO();
        scrollInfo.cbSize = Marshal.SizeOf(scrollInfo);
        //SIF_RANGE = 0x1, SIF_TRACKPOS = 0x10,  SIF_PAGE= 0x2
        scrollInfo.fMask = 0x10 | 0x1 | 0x2;
        GetScrollInfo((IntPtr)this.Handle, 1, ref scrollInfo);//nBar = 1 -> VScrollbar
        return scrollInfo.nPage;
    }

    public int GetCurPos()
    {
        SCROLLINFO scrollInfo = new SCROLLINFO();
        scrollInfo.cbSize = Marshal.SizeOf(scrollInfo);
        //SIF_RANGE = 0x1, SIF_TRACKPOS = 0x10,  SIF_PAGE= 0x2
        scrollInfo.fMask = 0x10 | 0x1 | 0x2;
        GetScrollInfo((IntPtr)this.Handle, 1, ref scrollInfo);//nBar = 1 -> VScrollbar
        return scrollInfo.nTrackPos;
    }

    public bool ReachedBottom()
    {
        SCROLLINFO scrollInfo = new SCROLLINFO();
        scrollInfo.cbSize = Marshal.SizeOf(scrollInfo);
        //SIF_RANGE = 0x1, SIF_TRACKPOS = 0x10,  SIF_PAGE= 0x2
        scrollInfo.fMask = 0x10 | 0x1 | 0x2;
        GetScrollInfo((IntPtr)this.Handle, 1, ref scrollInfo);//nBar = 1 -> VScrollbar
        return scrollInfo.max == scrollInfo.nTrackPos + scrollInfo.nPage;
    }

}

以下是用于移动文本的“按钮”:

                int lines = rules_thumb / rules_line_height; //getting max number of lines that can be visible
                int new_thumb = lines * rules_line_height; //getting the move value so the lines won't be cut

                if (rules_loc - (new_thumb) >= 0) //if moving by the move value will be still over 0, then proceed normally
                {
                    rules_loc -= (new_thumb);
                    rules.ScrollTo(rules_loc);
                }
                else // if it will pass 0, the move to 0
                {
                    rules_loc = 0;
                    rules.ScrollTo(rules_loc);
                }

向下:

                int lines = rules_thumb / rules_line_height;
                int new_thumb = lines * rules_line_height;

                if (rules_loc + (new_thumb) < rules_max)
                {
                    rules_loc += (new_thumb);
                    rules.ScrollTo(rules_loc);
                }
                else
                {
                    rules.ScrollTo(rules_max);
                }

我认为我做错了的是测量给定字体的线条并设置RTB的良好尺寸。有没有人有类似的问题,能以某种方式协助我吗?

提前感谢您的回答。

祝你好运, Sarachiel

0 个答案:

没有答案