Results 1 to 5 of 5

Thread: [.NET 2.0+] ListRichTextBox - Exposes Ability To Have Different List Formats

  1. #1

    Thread Starter
    Master Of Orion ForumAccount's Avatar
    Join Date
    Jan 2009
    Location
    Canada
    Posts
    2,802

    [.NET 2.0+] ListRichTextBox - Exposes Ability To Have Different List Formats

    This is a control that was made for this thread.

    Description and explanation of control details are in the picture of the control attached.
    Attached Images Attached Images  
    Attached Files Attached Files

  2. #2
    Fanatic Member Arve K.'s Avatar
    Join Date
    Sep 2008
    Location
    Kyrksæterøra, Norway
    Posts
    518

    Re: [.NET 2.0+] ListRichTextBox - Exposes Ability To Have Different List Formats

    Looks great
    Arve K.

    Please mark your thread as resolved and add reputation to those who helped you solve your problem
    Disclaimer: I am not a professional programmer

  3. #3
    New Member
    Join Date
    May 2011
    Posts
    4

    Re: [.NET 2.0+] ListRichTextBox - Exposes Ability To Have Different List Formats

    Quote Originally Posted by ForumAccount View Post
    This is a control that was made for this thread.

    Description and explanation of control details are in the picture of the control attached.
    Hi
    I tried it but don't work!
    I tried for list Numered
    I inserted your code in an extended class text justified.
    This is the following code:
    please help me!
    Code:
    Imports System.Windows.Forms
    Imports System.Runtime.InteropServices
    Imports System.Drawing
    Imports System.Drawing.Printing
    Imports System.ComponentModel
    
    ''' <summary>
    ''' Represents a standard <see cref="RichTextBox"/> with some
    ''' minor added functionality.
    ''' </summary>
    ''' <remarks>
    ''' AdvRichTextBox provides methods to maintain performance
    ''' while it is being updated. Additional formatting features
    ''' have also been added.
    ''' </remarks>
    Public Class AdvRichTextBox
        Inherits RichTextBox
      
        Public Sub BeginUpdate()
            ' Deal with nested calls.
            updating += 1
    
            If updating > 1 Then
                Return
            End If
    
            ' Prevent the control from raising any events.
            oldEventMask = SendMessage(New HandleRef(Me, Handle), EM_SETEVENTMASK, 0, 0)
    
            ' Prevent the control from redrawing itself.
            SendMessage(New HandleRef(Me, Handle), WM_SETREDRAW, 0, 0)
        End Sub
    
        ''' <summary>
        ''' Resumes drawing and event handling.
        ''' </summary>
        ''' <remarks>
        ''' This method should be called every time a call is made
        ''' made to BeginUpdate. It resets the event mask to it's
        ''' original value and enables redrawing of the control.
        ''' </remarks>
        Public Sub EndUpdate()
            ' Deal with nested calls.
            updating -= 1
    
            If updating > 0 Then
                Return
            End If
    
            ' Allow the control to redraw itself.
            SendMessage(New HandleRef(Me, Handle), WM_SETREDRAW, 1, 0)
    
            ' Allow the control to raise event messages.
            SendMessage(New HandleRef(Me, Handle), EM_SETEVENTMASK, 0, oldEventMask)
        End Sub
    
        ''' <summary>
        ''' Gets or sets the alignment to apply to the current
        ''' selection or insertion point.
        ''' </summary>
        ''' <remarks>
        ''' Replaces the SelectionAlignment from
        ''' <see cref="RichTextBox"/>.
        ''' </remarks>
        Public Shadows Property SelectionAlignment() As TextAlign
            Get
                Dim fmt As New PARAFORMAT()
                fmt.cbSize = Marshal.SizeOf(fmt)
    
                ' Get the alignment.
                SendMessage(New HandleRef(Me, Handle), EM_GETPARAFORMAT, SCF_SELECTION, fmt)
    
                ' Default to Left align.
                If (fmt.dwMask And PFM_ALIGNMENT) = 0 Then
                    Return TextAlign.Left
                End If
    
                Return CType(fmt.wAlignment, TextAlign)
    
            End Get
    
            Set(ByVal value As TextAlign)
                Dim fmt As New PARAFORMAT()
                fmt.cbSize = Marshal.SizeOf(fmt)
                fmt.dwMask = PFM_ALIGNMENT
                fmt.wAlignment = CShort(value)
    
                ' Set the alignment.
                SendMessage(New HandleRef(Me, Handle), EM_SETPARAFORMAT, SCF_SELECTION, fmt)
            End Set
        End Property
    
        ''' <summary>
        ''' This member overrides
        ''' <see cref="Control"/>.OnHandleCreated.
        ''' </summary>
        Protected Overrides Sub OnHandleCreated(ByVal e As EventArgs)
            MyBase.OnHandleCreated(e)
    
            ' Enable support for justification.
            SendMessage(New HandleRef(Me, Handle), EM_SETTYPOGRAPHYOPTIONS, TO_ADVANCEDTYPOGRAPHY, TO_ADVANCEDTYPOGRAPHY)
        End Sub
    
        Private updating As Integer = 0
        Private oldEventMask As Integer = 0
    
        ' Constants from the Platform SDK.
        Private Const EM_SETEVENTMASK As Integer = 1073
        Private Const EM_GETPARAFORMAT As Integer = 1085
        Private Const EM_SETPARAFORMAT As Integer = 1095
        Private Const EM_SETTYPOGRAPHYOPTIONS As Integer = 1226
        Private Const WM_SETREDRAW As Integer = 11
        Private Const TO_ADVANCEDTYPOGRAPHY As Integer = 1
        Private Const PFM_ALIGNMENT As Integer = 8
        Private Const SCF_SELECTION As Integer = 1
    
        ' It makes no difference if we use PARAFORMAT or
        ' PARAFORMAT2 here, so I have opted for PARAFORMAT2.
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure PARAFORMAT
            Public cbSize As Integer
            Public dwMask As UInteger
            Public wNumbering As Short
            Public wReserved As Short
            Public dxStartIndent As Integer
            Public dxRightIndent As Integer
            Public dxOffset As Integer
            Public wAlignment As Short
            Public cTabCount As Short
            <MarshalAs(UnmanagedType.ByValArray, SizeConst:=32)> _
            Public rgxTabs As Integer()
    
            ' PARAFORMAT2 from here onwards.
            Public dySpaceBefore As Integer
            Public dySpaceAfter As Integer
            Public dyLineSpacing As Integer
            Public sStyle As Short
            Public bLineSpacingRule As Byte
            Public bOutlineLevel As Byte
            Public wShadingWeight As Short
            Public wShadingStyle As Short
            Public wNumberingStart As Short
            Public wNumberingStyle As Short
            Public wNumberingTab As Short
            Public wBorderSpace As Short
            Public wBorderWidth As Short
            Public wBorders As Short
        End Structure
    
        <DllImport("user32", CharSet:=CharSet.Auto)> _
        Private Shared Function SendMessage(ByVal hWnd As HandleRef, ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
        End Function
    
        <DllImport("user32", CharSet:=CharSet.Auto)> _
        Private Shared Function SendMessage(ByVal hWnd As HandleRef, ByVal msg As Integer, ByVal wParam As Integer, ByRef lp As PARAFORMAT) As Integer
        End Function
    
    
        ' Convert the unit that is used by the .NET framework (1/100 inch) 
        ' and the unit that is used by Win32 API calls (twips 1/1440 inch)
        Private Const AnInch As Double = 14.4
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure RECT
            Public Left As Integer
            Public Top As Integer
            Public Right As Integer
            Public Bottom As Integer
        End Structure
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure CHARRANGE
            Public cpMin As Integer          ' First character of range (0 for start of doc)
            Public cpMax As Integer          ' Last character of range (-1 for end of doc)
        End Structure
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure FORMATRANGE
            Public hdc As IntPtr             ' Actual DC to draw on
            Public hdcTarget As IntPtr       ' Target DC for determining text formatting
            Public rc As Rect                ' Region of the DC to draw to (in twips)
            Public rcPage As Rect            ' Region of the whole DC (page size) (in twips)
            Public chrg As CHARRANGE         ' Range of text to draw (see above declaration)
        End Structure
    
    
    #Region "Elenchi Numerati"
    
        '//APIs
        <DllImport("user32.dll")> _
        Private Shared Function SendMessage(ByVal hWnd As HandleRef, _
                                            ByVal msg As Integer, _
                                            ByVal wParam As Integer, _
                                            <[In]()> <Out()> _
                                            <MarshalAs(UnmanagedType.LPStruct)> _
                                            ByVal lParam As ListFormatInfo) As IntPtr
        End Function
    
        '//properties
        Private _selectionList As Boolean
        ''' <summary>
        ''' Gets or sets a value indicating whether the currently selected text uses a ListFormat.
        ''' </summary>
        ''' <remarks>Returns whether the currently selected text's ListFormat equals the currently chosen ListFormat.</remarks>
        <Browsable(False)> _
        <Description("Gets or sets a value indicating whether the currently selected text uses a ListFormat.")> _
        Public Property SelectionList() As Boolean
            Get
                Dim none As RichTextBoxSelectionAttribute = RichTextBoxSelectionAttribute.None
                If Me.IsHandleCreated Then
                    Dim format As New ListFormatInfo()
                    format.Tabs = New Integer(31) {}
                    AdvRichTextBox.SendMessage(New HandleRef(Me, MyBase.Handle), _
                                                1085, 0, format)
                    If ((32 And format.Mask) <> 0) Then
                        If (format.Numbering = Me._listFormat) Then
                            none = RichTextBoxSelectionAttribute.All
                        End If
                        Return (none = RichTextBoxSelectionAttribute.All)
                    End If
                End If
                Return False
            End Get
            Set(ByVal value As Boolean)
                If MyBase.IsHandleCreated Then
                    Dim format As New ListFormatInfo()
                    format.Mask = 36
                    If Not value Then
                        format.Numbering = Convert.ToInt16(ListFormats.None)
                        format.Offset = 0
                    Else
                        format.Numbering = Convert.ToInt16(Me._listFormat)
                        format.Offset = MyBase.BulletIndent
                    End If
                    AdvRichTextBox.SendMessage(New HandleRef(Me, MyBase.Handle), _
                                                1095, 0, format)
                End If
            End Set
        End Property
    
        Private _listFormat As ListFormats = ListFormats.Bullets
        ''' <summary>
        ''' Gets or sets a value indicating the format to use on lists.
        ''' </summary>
        <DefaultValue(GetType(ListFormats), "Bullets")> _
        <Description("Gets or sets a value indicating the format to use on lists.")> _
        Public Property ListFormat() As ListFormats
            Get
                Return Me._listFormat
            End Get
            Set(ByVal value As ListFormats)
                If [Enum].IsDefined(GetType(ListFormats), value) Then
                    Me._listFormat = value
                End If
            End Set
        End Property
    
        <Browsable(False)> _
        <EditorBrowsable(EditorBrowsableState.Never)> _
        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public Overloads Property SelectionBullet() As Boolean
            Get
                Return False
            End Get
            Set(ByVal value As Boolean)
                MyBase.SelectionBullet = False
            End Set
        End Property
    
        '//enumerations
        ''' <summary>
        ''' Represents an enumeration of valid formats for lists in the control.
        ''' </summary>
        ''' <remarks></remarks>
        Public Enum ListFormats
            None = 0
            Bullets = 1
            Numbered = 2
            LowercaseLetters = 3
            UppercaseLetters = 4
            LowercaseRomanNumeral = 5
            UppercaseRomanNumeral = 6
            SmallBullets = 8
        End Enum
    
        '//nested classes
        <StructLayout(LayoutKind.Sequential)> _
        Private Class ListFormatInfo
    
            '//properties
            Private _size As Integer
            Public Property Size() As Integer
                Get
                    Return Me._size
                End Get
                Set(ByVal value As Integer)
                    Me._size = value
                End Set
            End Property
    
            Private _mask As Integer
            Public Property Mask() As Integer
                Get
                    Return Me._mask
                End Get
                Set(ByVal value As Integer)
                    Me._mask = value
                End Set
            End Property
    
            Private _numbering As Short
            Public Property Numbering() As Short
                Get
                    Return Me._numbering
                End Get
                Set(ByVal value As Short)
                    Me._numbering = value
                End Set
            End Property
    
            Private _reserved As Short
            Public Property Reserved() As Short
                Get
                    Return Me._reserved
                End Get
                Set(ByVal value As Short)
                    Me._reserved = value
                End Set
            End Property
    
            Private _startIndent As Integer
            Public Property StartIndent() As Integer
                Get
                    Return Me._startIndent
                End Get
                Set(ByVal value As Integer)
                    Me._startIndent = value
                End Set
            End Property
    
            Private _rightIndent As Integer
            Public Property RightIndent() As Integer
                Get
                    Return Me._rightIndent
                End Get
                Set(ByVal value As Integer)
                    Me._rightIndent = value
                End Set
            End Property
    
            Private _offset As Integer
            Public Property Offset() As Integer
                Get
                    Return Me._offset
                End Get
                Set(ByVal value As Integer)
                    Me._offset = value
                End Set
            End Property
    
            Private _alignment As Short
            Public Property Alignment() As Short
                Get
                    Return Me._alignment
                End Get
                Set(ByVal value As Short)
                    Me._alignment = value
                End Set
            End Property
    
            Private _tabCount As Short
            Public Property TabCount() As Short
                Get
                    Return Me._tabCount
                End Get
                Set(ByVal value As Short)
                    Me._tabCount = value
                End Set
            End Property
    
            <MarshalAs(UnmanagedType.ByValArray, SizeConst:=32)> _
            Private _tabs As Integer()
            Public Property Tabs() As Integer()
                Get
                    Return Me._tabs
                End Get
                Set(ByVal value As Integer())
                    Me._tabs = value
                End Set
            End Property
            '//constructors
            Public Sub New()
                Me._size = Marshal.SizeOf(GetType(ListFormatInfo))
            End Sub
        End Class
    #End Region
    
       
    End Class
    ''' <summary>
    ''' Specifies how text in a <see cref="AdvRichTextBox"/> is
    ''' horizontally aligned.
    ''' </summary>
    Public Enum TextAlign
        ''' <summary>
        ''' The text is aligned to the left.
        ''' </summary>
        Left = 1
        ''' <summary>
        ''' The text is aligned to the right.
        ''' </summary>
        Right = 2
        ''' <summary>
        ''' The text is aligned in the center.
        ''' </summary>
        Center = 3
        ''' <summary>
        ''' The text is justified.
        ''' </summary>
        Justify = 4
    End Enum

  4. #4
    New Member
    Join Date
    Oct 2012
    Location
    Scandinavia
    Posts
    4

    Re: [.NET 2.0+] ListRichTextBox - Exposes Ability To Have Different List Formats

    This is a piece of really good work! Kudos!

    Good work always render a demand for even better functions. :-) And here it goes:
    1. The numbered lists are zero based, how do I change this? I'd like them to start with 1. Or whatever the user sets it to in my application.
    2. How about nested lists? Anyone having any good suggestions?

    Thanks for making this public! Much appreciated!

    /theLingorian

  5. #5
    New Member
    Join Date
    Oct 2012
    Location
    Scandinavia
    Posts
    4

    Re: [.NET 2.0+] ListRichTextBox - Exposes Ability To Have Different List Formats

    Additional question:
    3. Is it somehow possible to have the bullet list to use squares instead of round, filled circles?

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width