VB3 Printing Multiline Text Box Using Windows API FunctionsID: Q80867
|
Printing the Text property of a multiline text box while maintaining the line structure requires attention to word wrapping, carriage returns, and line feeds. The programmer can either track the number of characters and lines in code or use Windows API functions to manipulate the Text property. This article demonstrates these techniques in a Visual Basic example.
The example below demonstrates how to use the API function SendMessage() to
track the number of lines in a multiline text box and to select and print
the lines the way they appear, with line breaks or word wrapping intact.
This code will work without modification even if the form and controls are
resized at run time. The actual position of word wrapping will change.
For more information about API functions relating to text boxes, query on
the following words in the Microsoft Knowledge Base:
("API") and ("text") and ("box") and ("manipulate")
Control Property Setting
--------------------------------------------------------
Text box TabIndex 0 (zero, or first in tab order)
Text box MultiLine True
Label AutoSize True
Label Name aGetLineCount
' Enter the following Declare statement on one, single line:
Declare Function SendMessage% Lib "user" (ByVal hWnd%, ByVal wMsg%,
ByVal wParam%, ByVal lParam As Any)
Dim Buffer As String
Dim resizing As Integer
Const EM_GETLINE = &H400 + 20
Const EM_GETLINECOUNT = &H400 + 10
Const MAX_CHAR_PER_LINE = 80 ' Scale this to size of text box.
Sub Form_Load ()
' Size form relative to screen dimensions.
' Could define all in move command but recursive definition causes
' extra paints.
form1.width = screen.width * .8
form1.height = screen.height * .6
' Enter the following form1.Move method on one, single line:
form1.Move screen.width\2-form1.width\2,
screen.height\2-form1.height\2
End Sub
Sub Form_Resize ()
resizing = -1 ' Global flag for fGetLineCount function call.
' Dynamically scale and position the controls in the form.
' This code also is executed on first show of form.
Text1.Move 0, 0, form1.width, form1.height \ 2
Text1.SelStart = Text1.SelStart
' Enter the following two lines as one, single line:
command1.Move form1.width\2-command1.width\2,
form1.height-form1.height\4
' Enter the following two lines as one, single line:
aGetLineCount.Move form1.width \ 2 - command1.width \ 2,
Text1.height
X% = fGetLineCount() ' Update to reflect change in text-box size.
resizing = 0
End Sub
Sub Command1_Click ()
'* Pop up an inputbox$ to allow user to specify which line
'* in the text box to print or print all lines.
'* Also check bounds so that a valid line number is printed.
OK = 0 ' Zero the Do Loop flag.
NL$ = Chr$(13) + Chr$(10)
prompt$ = "Which line would you like to print?"
prompt1$ = prompt$ + NL$ + "Enter -1 for all"
prompt2$ = "Too many lines" + NL$ + "Try again!" + NL$ + prompt1$
prompt$ = prompt1$
Do
response$ = InputBox$(prompt$, "Printing", "-1")
If response$ = "" Then Exit Sub ' If user hits cancel, then exit.
If Val(response$) > fGetLineCount&() Then
prompt$ = prompt2$
Else
OK = -1 ' Line chosen is in valid range, so exit DO.
End If
Loop Until OK
If Val(response$) = -1 Then ' Print all lines...
ndx& = fGetLineCount&()
For N& = 1 To ndx&
Buffer = fGetLine(N& - 1)
printer.Print Buffer ' ...or print to the screen.
Next N&
Else ' Print a line...
Buffer = fGetLine(Val(response$) - 1)
printer.Print Buffer ' ...or print to the screen.
End If
printer.enddoc
End Sub
Function fGetLine$ (LineNumber As Long)
' This function fills the buffer with a line of text
' specified by LineNumber from the text-box control.
' The first line starts at zero.
byteLo% = MAX_CHAR_PER_LINE And (255) '[changed 5/15/92]
byteHi% = Int(MAX_CHAR_PER_LINE / 256) '[changed 5/15/92]
Buffer$ = chr$(byteLo%) + chr$(byteHi%)+Space$(MAX_CHAR_PER_LINE-2)
' [Above line changed 5/15/92 to correct problem.]
x% = SendMessage(text1.hwnd, EM_GETLINE, LineNumber, Buffer$)
fGetLine$ = Left$(Buffer$,X%)
End Function
Function fGetLineCount& ()
' This function will return the number of lines
' currently in the text-box control.
' Setfocus method illegal while in resize event,
' so use global flag to see if called from there
' (or use setfocus before this function call in general case).
lcount% = SendMessage(text1.hwnd, EM_GETLINECOUNT, 0&, 0&)
aGetLineCount.caption = "GetLineCount = " + Str$(lcount%)
fGetLineCount& = lcount%
End Function
Sub Text1_Change ()
X% = fGetLineCount() '* Update label to reflect current line
End Sub
Please see the "Microsoft Windows Programmer's Reference Book and Online Resource" (Visual Basic Add-on Kit #1-55615-413-5).
Additional query words: textbox
Keywords : kbcode kbWndw PrgCtrlsStd
Version : 2.0 3.0
Platform : WINDOWS
Issue type : kbhowto
Last Reviewed: June 17, 1999