winform的RichTextBox设置行距

关于richtextbox设置指定行距的问题,在网上搜索了很多,大部分比较正确的答案是通过引用user32.dll,搜索到的内容比较多,我就放了其中一个参照的链接:https://www.cnblogs.com/liubiaocai/archive/2011/08/30/2159869.html

问题

这个链接上所给出的代码是没有问题的,但是,如果我们真的把代码照抄下来运行,肯定是达不到我们要的效果的,主要问题是两个参数PARAFORMAT2.bLineSpacingRulePARAFORMAT2.dyLineSpacing的值的问题。

解决

这两个参数是真正的用于设置行距的,具体的介绍,见链接:https://docs.microsoft.com/zh-cn/windows/win32/api/richedit/ns-richedit-_paraformat2

我们设置的行距大多是以像素为单位的,但是,dyLineSpacing是以 为单位的,它们的关系是:1像素=15缇
还有bLineSpacingRule ,表示行间距的类型
其中:
3:dylinespace成员以 缇。的形式指定从一行到下一行的间隔。但是,如果dylinespace指定的值小于单间距,则控件将显示单间距文本。
4:dylinespace成员以 缇。的形式指定从一行到下一行的间距。控件使用指定的精确间距,即使dylinespace指定的值小于单个间距。

修改后的代码如下

        public const int WM_USER = 0x0400;
        public const int EM_GETPARAFORMAT = WM_USER + 61;
        public const int EM_SETPARAFORMAT = WM_USER + 71;
        public const long MAX_TAB_STOPS = 32;
        public const uint PFM_LINESPACING = 0x00000100;
        [StructLayout(LayoutKind.Sequential)]
        private struct PARAFORMAT2
        {
            public int cbSize;
            public uint dwMask;
            public short wNumbering;
            public short wReserved;
            public int dxStartIndent;
            public int dxRightIndent;
            public int dxOffset;
            public short wAlignment;
            public short cTabCount;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
            public int[] rgxTabs;
            public int dySpaceBefore;
            public int dySpaceAfter;
            public int dyLineSpacing;
            public short sStyle;
            public byte bLineSpacingRule;
            public byte bOutlineLevel;
            public short wShadingWeight;
            public short wShadingStyle;
            public short wNumberingStart;
            public short wNumberingStyle;
            public short wNumberingTab;
            public short wBorderSpace;
            public short wBorderWidth;
            public short wBorders;
        }
        [DllImport("user32", CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, ref PARAFORMAT2 lParam);
       
        //height:要指定的行高像素
        private void SetLineSpace(Control ctl, int height)
        {
            //1像素=15缇。
            int dyLineSpacing = height * 15;            
            //4:dylinespace成员以  缇。的形式指定从一行到下一行的间距。控件使用指定的精确间距,即使dylinespace指定的值小于单个间距。
            //3:dylinespace成员以  缇。的形式指定从一行到下一行的间隔。但是,如果dylinespace指定的值小于单间距,则控件将显示单间距文本。
            byte bLineSpacingRule = (byte)3;
            PARAFORMAT2 fmt = new PARAFORMAT2();
            fmt.cbSize = Marshal.SizeOf(fmt);
            fmt.bLineSpacingRule = bLineSpacingRule;
            fmt.dyLineSpacing = dyLineSpacing;
            fmt.dwMask = PFM_LINESPACING;
            try
            {
                SendMessage(new HandleRef(ctl, ctl.Handle), EM_SETPARAFORMAT, bLineSpacingRule, ref fmt);
            }
            catch
            { }
        }

调用:设置richTextBox1的文本行间距为40px

SetLineSpace(richTextBox1, 40);

测试结果OK,符合预期效果

你可能感兴趣的:(WinForm,文本行高)