C# RichTextBox行高自适应

12 篇文章 0 订阅

第一种:

richTextBox1.ScrollBars = RichTextBoxScrollBars.None;
richTextBox.ContentsResized += new ContentsResizedEventHandler(richTextBox_ContentsResized);

  private void richTextBox1_ContentsResized(object sender, ContentsResizedEventArgs e)
  {
  richTextBox1.Height = e.NewRectangle.Height+10;

  }

第二种:

1.先调用以下方法:

          [DllImport("user32.dll", EntryPoint = "SendMessageA")]
          private static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, string lParam);

2.设置RichTextBox:

            this.richTextBox1 = new RichTextBox();           
            this.richTextBox1.Text = “contentcontentcontentcontentcontentcontentcontentcontentcontent”;
            this.richTextBox1.Width = this.pPanel.Width-15;
            this.richTextBox1.ScrollBars = RichTextBoxScrollBars.None;
            this.richTextBox1.Location = new Point(0, 0 + this.lab1.Height+10);
           // this.richTextBox1.Anchor = (AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Top);这句代码有问题
            //得到RichTextBox高度
            int EM_GETLINECOUNT = 0x00BA;//获取总行数的消息号 
            int lc = SendMessage(this.richTextBox1.Handle, EM_GETLINECOUNT, IntPtr.Zero, "");
            int sf = this.richTextBox1.Font.Height * (lc + 1) + this.richTextBox1.Location.Y;
            this.richTextBox1.Height = sf;
            this.richTextBox1.Resize += new EventHandler(richTextBox1_Resize);
            this.Controls.Add(this.richTextBox1);
3.设置RichTextBox的Resize:

        void richTextBox1_Resize(object sender, EventArgs e)
        {
            int EM_GETLINECOUNT = 0x00BA;//获取总行数的消息号 
            int lc = SendMessage(this.richTextBox1.Handle, EM_GETLINECOUNT, IntPtr.Zero, "");
            int sf = this.richTextBox1.Font.Height * (lc + 1) + this.richTextBox1.Location.Y;
            this.richTextBox1.Height = sf;
        }


【转载请注明出处: http://blog.csdn.net/lzl124631x
我在用C#写一个窗体程序, 其中有RichTextBox读取RTF. 我期望RTB的宽度是固定的, 高度能够根据RTF的内容而动态改变. 搜了很多资料还不清楚怎么弄. 暂时找到了以下资料可能有用:
  1. C#调用API接收发送窗口消息  http://blog.csdn.net/haylhf/article/details/7842174
  2. C#中 WndProc(ref Message m) 方法怎么用 http://bbs.csdn.net/topics/290047154
  3. How To Resize RichTextbox Control with Endless Bottom http://support.microsoft.com/kb/257849
  4. Bottomless Rich Edit Controls http://msdn.microsoft.com/en-us/library/vstudio/dzh15c7k.aspx
  5. RichTextBox如何自适大小 http://social.msdn.microsoft.com/Forums/en-US/111a2875-dee8-4b42-aed5-d887a26b6926/richtextbox?forum=2212
在第3条中给出了VB的实现方法. MSDN上给出来的, 比较信赖, 所以决定先用VB试一下. 一开始用VS2010尝试建工程发现完全不是一回事儿, 发现应该用Visual Basic6.0来实现, 遂下载之. 在 http://xiazai.zol.com.cn/detail/3/29939.shtml下载了一个精简版, 只有5.86MB. 但是缺陷是没有RichTextBox控件, 需要自己下.  搜了下, 需要下载richtx32.ocx放到windows\system32下面, 在 http://www.xdowns.com/soft/184/dll/2008/Soft_40499.html下载了一个, 点bat直接帮你放到system32下面了.

打开VB, Ctrl+T(或者"工程">"部件"), 勾选Microsoft Windows Common Dialog Control和Microsoft Rich Textbox Control.


然后按照 http://support.microsoft.com/kb/257849/en-us中说的一步一步来:
  1. Start a new Visual Basic Standard EXE project. Form1 is created by default.
    创建一个新的Visual Basic Standard EXE工程.
  2. On the Project menu, select Components. Check the Rich Textbox and Common Dialog controls, and then click OK.
    "工程">"部件", 勾选Rich Textbox和Common Dialog控件
  3. Add a CommandButton, a CommonDialog, and a RichTextBox control to Form1.
    向Form1中添加CommandButton, CommonDialog和RichTextBox
  4. In the Properties window, set the ScrollBars property of RichTextBox1 to 2-rtfVertical.
    在RichTextBox1的属性窗口中将ScrollBars属性设置为2-rtfVertical.
  5. Add the following code to the General Declarations section of Form1:
    向Form1中添加如下代码:
    1. Option Explicit  
    2.   
    3. Private Sub Form_Load()  
    4. ' Create a Hook and populate a global variable with the Richtextbox hwnd.  
    5.    Call NewWindowProc(Me.hWnd)  
    6.    RichWnd = RichTextBox1.hWnd  
    7. End Sub  
    8.   
    9. Private Sub Command1_Click()  
    10. ' Load a file into the richtextbox control  
    11.    With CommonDialog1  
    12.       .Filter = "All Files|*.*|Text Files|*.txt|RTF Files|*.rtf"  
    13.       .ShowOpen  
    14.       RichTextBox1.FileName = .FileName  
    15.    End With  
    16. End Sub  
    17.   
    18. Private Sub Form_Resize()  
    19. ' 1.)Populate global variables with the Height and Width of the   
    20. '   Richtextbox control.  
    21. ' 2.)Set an event mask for the Richtextbox control.  
    22. ' 3.)Send an EM_REQUESTRESIZE Message to the Form.  
    23.   
    24.    gblWidth = RichTextBox1.Width / Screen.TwipsPerPixelX  
    25.    gblHeight = ((Form1.Height - RichTextBox1.Top) - 450) / _  
    26.                Screen.TwipsPerPixelY  
    27.    Call SetMask(RichWnd)  
    28.    Call SendMessage(RichWnd, EM_REQUESTRESIZE, 0, 0)  
    29. End Sub  
    30.   
    31. Private Sub Form_Unload(Cancel As Integer)  
    32.    Call ResetWindProc(Me.hWnd) ' Remove the Windows Hook  
    33. End Sub  
  6. On the Project menu, select Add Module to add a BAS module to the project. Module1 is created by default.
    "工程">"添加模块"
  7. Add the following code to General Declarations section of Module1:
    向Module1中添加如下代码:
    1. Option Explicit  
    2.   
    3. ' Private Variables  
    4.   
    5. Private rResize As REQSIZE ' <--- Pointer to REQSIZE Structure  
    6. Private MaskHdr As nmhdr   ' <--- Pointer to nmhdr Structure  
    7. Private OldWndProc As Long  
    8. Private Const GWL_WNDPROC = (-4)  
    9. Private Const WM_USER = &H400  
    10. Private Const WM_NOTIFY = &H4E  
    11. Private Const SWP_NOMOVE = &H2  
    12. Private Const SWP_SHOWWINDOW = &H40  
    13. Private Const EM_GETEVENTMASK = (WM_USER + 59)  
    14. Private Const EM_SETEVENTMASK = (WM_USER + 69)  
    15. Private Const ENM_REQUESTRESIZE As Long = &H40000  
    16. Private Const EN_REQUESTRESIZE = &H701  
    17.   
    18. ' Public Variables  
    19.   
    20. Public gblWidth As Long     ' <--- Var Holder for Richtext Width  
    21. Public gblHeight As Long    ' <--- Var Holder for Richtext Height  
    22. Public Const EM_REQUESTRESIZE = (WM_USER + 65)  
    23. Public Const VBNullPtr = 0&  
    24. Public RichWnd As Long      ' <--- Var Holder for Richtext Hwnd  
    25.   
    26. Private Type nmhdr  
    27.    hwndFrom As Long  
    28.    idfrom As Long  
    29.    code As Long  
    30. End Type  
    31.   
    32. Private Type rect  
    33.    Left As Long  
    34.    Top As Long  
    35.    Right As Long  
    36.    Bottom As Long  
    37. End Type  
    38.   
    39. Private Type REQSIZE  
    40.    nmhdr As nmhdr  
    41.    rect As rect  
    42. End Type  
    43.   
    44. Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _  
    45.    (ByVal hwnd As LongByVal wMsg As LongByVal wParam As Long, _  
    46.    ByVal lParam As LongAs Long  
    47.   
    48. Private Declare Function SetWindowLong Lib "user32" Alias _   
    49.    "SetWindowLongA" (ByVal hwnd As LongByVal nIndex As Long, _   
    50.    ByVal dwNewLong As LongAs Long  
    51.   
    52. Private Declare Function CallWindowProc Lib "user32" _  
    53.    Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, _  
    54.    ByVal hwnd As LongByVal Msg As LongByVal wParam As Long, _  
    55.    ByVal lParam As LongAs Long  
    56.   
    57. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _  
    58.    (Destination As Any, Source As Any, ByVal Length As Long)  
    59.   
    60. Public Declare Function SetWindowPos Lib "user32" _  
    61.    (ByVal hwnd As LongByVal hWndInsAfter As LongByVal x As Long, _  
    62.     ByVal y As LongByVal cx As LongByVal cy As Long, _  
    63.     ByVal wFlags As LongAs Long  
    64.   
    65. ' Call SetWindowLong to instantiate the Window Procedure by passing the  
    66. ' Address of MyWndProc.  
    67.   
    68. Public Sub NewWindowProc(fhWnd As Long)  
    69.    On Error Resume Next  
    70.    OldWndProc = SetWindowLong(fhWnd, GWL_WNDPROC, AddressOf MyWndProc)  
    71. End Sub  
    72.   
    73. ' Once the Hook is in place, All messages will be processed by this  
    74. ' function. Test for a WM_NOTIFY and parse the lParam to search for a  
    75. ' specific value. In this case we are looking for EN_REQUESTRESIZE in the  
    76. ' nmhdr structure. If an EN_REQUESTRESIZE is found then grab the next  
    77. ' structure(REQSIZE) from the lParam.  
    78.   
    79. Public Function MyWndProc(ByVal hwnd As Long, _  
    80.                           ByVal Msg As Long, _  
    81.                           ByVal wParam As Long, _  
    82.                           ByVal lParam As LongAs Long  
    83.    On Error Resume Next  
    84.   
    85.    Select Case Msg  
    86.       Case WM_NOTIFY  
    87.          Call CopyMemory(MaskHdr, ByVal lParam, Len(MaskHdr))  
    88.            
    89.          If MaskHdr.code = EN_REQUESTRESIZE Then  
    90.             Call CopyMemory(rResize, ByVal lParam, Len(rResize))  
    91.   
    92.   
    93.             If rResize.rect.Bottom < gblHeight Then  
    94.                Call SetWindowPos(RichWnd, VBNullPtr, _  
    95.                                  0, 0, gblWidth, _  
    96.                                  rResize.rect.Bottom, _  
    97.                                  SWP_SHOWWINDOW Or SWP_NOMOVE)  
    98.   
    99.             Else  
    100.                Call SetWindowPos(RichWnd, VBNullPtr, _  
    101.                                     0, 0, _  
    102.                                     gblWidth, gblHeight, _  
    103.                                     SWP_SHOWWINDOW Or SWP_NOMOVE)  
    104.             End If  
    105. ' By modifying 2 of the above parameters you can create an endless bottom  
    106. ' Richtext control. This may be desirable if you plan to wrap the control  
    107. ' and use it on a web page. To test this, comment the 'If' Statement above  
    108. ' and replace it with the SetWindowPos Function call below.  
    109. ' The control will now Resize itself to its actual contents.  
    110.   
    111. '               Call SetWindowPos(RichWnd, VBNullPtr, _  
    112. '                             0, 0, _  
    113. '                             gblWidth, rResize.rect.Bottom, _  
    114. '                             SWP_SHOWWINDOW Or SWP_NOMOVE)  
    115.          End If  
    116.               
    117.       Case Else ' Handle other messages here.  
    118.    End Select  
    119.       
    120. ' Reset windowproc  
    121.    MyWndProc = CallWindowProc(OldWndProc, hwnd, Msg, wParam, lParam)  
    122.   
    123. End Function  
    124.   
    125. Public Sub ResetWindProc(hwnd As Long)  
    126.   
    127.    On Error Resume Next  
    128.      
    129. ' Call SetWindowLong to remove the Windows Hook from app.  
    130.   
    131.    Call SetWindowLong(hwnd, GWL_WNDPROC, OldWndProc)  
    132.   
    133. End Sub  
    134.   
    135. Public Sub SetMask(fhWnd As Long)  
    136.    On Error Resume Next  
    137.    Dim CurrentMask As Long  
    138.    Dim NewMask As Long  
    139. ' Set the Event Mask to be called.  
    140.   
    141.    CurrentMask = SendMessage(fhWnd, EM_GETEVENTMASK, 0, 0)  
    142.    NewMask = (CurrentMask Or ENM_REQUESTRESIZE)  
    143.    Call SendMessage(fhWnd, EM_SETEVENTMASK, 0, ENM_REQUESTRESIZE)  
    144. End Sub  
  8. Save and run the project. Note that the control is now being displayed using the height of the contents or the height of the form.
    运行工程. 现在RTB的高度可以随着内容变化了!

    换一个RTF, 出现滚动条了, 不过轻轻把窗口拉大一下就好了, 代码里还有些问题, 不过我现在只是借鉴, 没关系.


    RTB此时取内容高度与窗口高度间的最小值, 如果窗口高度比内容高度小, 会出现滚动条!
  9. Comment out the If statement described in the comments in Module1 of the code sample, and uncomment the SetWindowPos function call following it.
    Module1中有几行注释, 上面是一段If代码, 下面是被注释掉的SetWindowPos函数. 注释掉那段If代码, 取消掉SetWindowPos函数的注释.

    VB6.0里面注释代码段:
    "视图">"工具栏">"编辑"

    其中就是注释和取消注释.
  10. Save the project and run it. The RichTextBox control now resizes itself to the height of its contents regardless of the size of the contents.
    运行程序, 现在RTB不管内容多大, 都保证是内容的高度, 不会添加滚动条了!


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值