Word Wrap Text
The code listed below can be compiled as a class or can be added to a project. This code wraps text to a specified number of characters per line. It does this by using several api calls and a fixed width font. This method for wrapping text is much faster than any other code I have found on the internet. These are the necessary objects: one form called frmMain with txtbox on it called txtHidden, a module called modMainCode, and a class module called WordWrap
'modMainCode
Option Explicit
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal msg As Long, ByVal wp As Long, lp As Any) As Long
Public Const EM_LINEINDEX = &HBB
Public Const EM_LINELENGTH = &HC1
Public Const EM_GETLINE = &HC4
Public Const EM_GETLINECOUNT = &HBA
Public Const EM_FMTLINES = &HC8
'frmMain
Option Explicit
Public intMaxLineLen As Integer
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal msg As Long, ByVal wp As Long, lp As Any) As Long
Private Const EM_LINEINDEX = &HBB
Private Const EM_LINELENGTH = &HC1
Private Const EM_GETLINE = &HC4
Private Const EM_GETLINECOUNT = &HBA
Private Const EM_FMTLINES = &HC8
'************************************************************************
'This sets up the textbox so it will wrap to the correct amount of
'characters
'************************************************************************
Private Sub SetUpRTB()
Dim lngIndex As Long
Dim intLength As Integer
intLength = 0
txtHidden.MultiLine = True
txtHidden.Font.Name = "Fixedsys"
txtHidden.Text = String(500, "W")
Do Until intLength = intMaxLineLen
txtHidden.Width = txtHidden.Width + 5
lngIndex = SendMessage(txtHidden.hWnd, _
EM_LINEINDEX, 1, 0)
intLength = SendMessage(txtHidden.hWnd , _
EM_LINELENGTH, lngIndex, 0)
Loop
txtHidden = ""
txtHidden.Visible = False
End Sub
Private Sub Form_Load()
SetUpRTB
End Sub
'WordWrap Class
Option Explicit
Public Function WordWrap(strText As String, intLineLen As Integer) As String
frmMain.intMaxLineLen = intLineLen
Load frmMain
WordWrap = GetText(strText)
End Function
'*************************************************************************************
'This function wraps a string by using apis and a textbox control(txtHidden)
'located on frmmain
'*************************************************************************************
Private Function GetText(strSource As String) As String
Dim lngCounter As Long
Dim lngLinecount As Long
Dim strHolder As String
Dim strLine As String
Dim lngCurrPos As Long, lngCurrPos2 As Long
Dim lngNextLen As Long
Dim lngtxtSize As Long
Dim intLength As Integer, intPrevLength As Integer
Dim lngCount As Long
Dim lngIndex As Long
Dim strBuf As String, strBufReplace As String
lngtxtSize = 65535 / ((2 / ((frmMain.intMaxLineLen + 1) / 2)) + 1)
strHolder = Space$(10000000)
lngNextLen = lngtxtSize
lngCurrPos = 1
lngCurrPos2 = 1
Do Until lngCurrPos >= Len(strSource)
If Len(strSource) - lngCurrPos < lngtxtSize Then
lngNextLen = Len(strSource) - lngCurrPos + 1
End If
frmMain.txtHidden = Mid(strSource, lngCurrPos, lngNextLen)
SendMessage frmMain.txtHidden.hWnd, EM_FMTLINES, True, 0
lngIndex = SendMessage(frmMain.txtHidden.hWnd, _
EM_LINEINDEX, 0, 0)
intLength = SendMessage(frmMain.txtHidden.hWnd, _
EM_LINELENGTH, lngIndex, 0)
If intLength + intPrevLength > frmMain.intMaxLineLen Then
strBuf = Space$(intLength + 1)
SendMessage frmMain.txtHidden.hWnd, EM_GETLINE, 0, ByVal strBuf
strBuf = Left$(strBuf, intLength)
strBufReplace = FixBuf(strBuf, intPrevLength)
frmMain.txtHidden = Replace$(frmMain.txtHidden, strBuf, strBufReplace, , 1)
SendMessage frmMain.txtHidden.hWnd, EM_FMTLINES, True, 0
End If
lngCount = SendMessage(frmMain.txtHidden.hWnd, _
EM_GETLINECOUNT, 0, 0)
lngIndex = SendMessage(frmMain.txtHidden.hWnd, _
EM_LINEINDEX, lngCount - 1, 0)
intPrevLength = SendMessage(frmMain.txtHidden.hWnd, _
EM_LINELENGTH, lngIndex, 0)
Mid$(strHolder, lngCurrPos2, Len(frmMain.txtHidden)) = frmMain.txtHidden
lngCurrPos2 = lngCurrPos2 + Len( frmMain.txtHidden)
lngCurrPos = lngCurrPos + lngNextLen
Loop
GetText = Replace$(Trim$(strHolder), vbCr & vbCr & vbLf, vbCrLf)
End Function
'****************************************************************************
'This function ensures that the first line of the text to be conconcatonated
'does not exceed the maximum line length when concatonated to the last line
'in the main string variable
'****************************************************************************
Private Function FixBuf(ByVal strText As String, intLen As Integer) As String
Dim intMaxLen As Integer
Dim i As Integer
Dim intlstSpace As Integer
intMaxLen = frmMain.intMaxLineLen - intLen
For i = 1 To intMaxLen
If Mid$(strText, i, 1) = Space$(1) Then
intlstSpace = i
End If
Next
If intlstSpace <> 0 Then
strText = Left$(strText, intlstSpace - 1) & vbCrLf & Right$(strText, Len(strText) - intlstSpace)
Else
strText = Left$(strText, intMaxLen) & vbCrLf & Right$(strText, Len(strText) - intMaxLen)
End If
FixBuf = strText
End Function
( orignal source: http://www.mredkj.com/vbquicktakes/WordWrap.html )
No comments:
Post a Comment