|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Visual Basic Text API Routines SendMessage: Programmatically Scroll a Text Box Vertically |
||
Posted: | Friday July 10, 1998 | |
Updated: | Monday December 26, 2011 | |
Applies to: | VB4-32, VB5, VB6, and VB3, VB4-16 with appropriate declarations | |
Developed with: | VB5, Windows 95 | |
OS restrictions: | None | |
Author: | VBnet - Randy Birch | |
Prerequisites |
None. |
|
The
following code demonstrates two things. First, and the reason for this code, is how to use the SendMessage API to programmatically scroll a
textbox vertically by any number of lines. The second is to demonstrate rather vividly the overhead involved when a control's property is
referenced during a complex operation, over the recommend method of using temporary variables for this purpose. Microsoft, in talking about optimizing Visual Basic applications, emphasizes the fact that referencing a control's property is slow, and recommend using temporary variables. It was therefore surprising to discover in their Knowledge Base code for this example that they in fact used the text property when building the textbox string (as in InitializeTextBoxSlow code below). I rewrote it to utilize their elsewhere-recommended temporary variable, with a considerable corresponding increase in speed. Every time a control or a control's property is referenced, VB must check that the control is a valid control, that a control by that name exists, and that the property referenced in the operation is valid for that type of control. This adds significant overhead to a running application, with the result that to the user, the application appears slow. Add to that the screen redraw each time a control is updated, and the time required to clear and repopulate a textbox, and the application not only appears slow, but flickers as well. The status label in the project is provided to assure that the selected operation is in fact in progress (as opposed to locked up), and the code clearly demonstrates that in all but a simple assignment, either a control's value should be saved to a variable, or a variable used to compile any data, assigning it to the property only when completed. |
BAS Module Code |
None. |
|
Form Code |
To a form add a large text box (Text1), a small text box (Text2), 4 command buttons (Command1, Command2, Command3 & Command4), and a label (Label1) corresponding to the illustration layout. Add the following code to the form: |
|
Option Explicit '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved. ' Some pages may also contain other copyrights by the author. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Distribution: You can freely use this code in your own ' applications, but you may not reproduce ' or publish this code on any web site, ' online service, or distribute as source ' on any media without express permission. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Private Declare Function SendMessage Lib "user32" _ Alias "SendMessageA" _ (ByVal hwnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ lParam As Any) As Long Private Declare Function PutFocus Lib "user32" _ Alias "SetFocus" _ (ByVal hwnd As Long) As Long Private Const EM_LINESCROLL = &HB6 Sub Form_Load() Me.Move (Screen.Width - Me.Width) \ 2, (Screen.Height - Me.Height) \ 2 Label1.Caption = "Waiting for command" Command1.Caption = "Fast Load" Command2.Caption = "Slow Load" Command3.Caption = "Scroll" Command4.Caption = "End" End Sub Private Sub Command3_Click() 'Scroll text lines upward by the value specified in Text2 Dim numLines As Integer numLines = Val(Text2.Text) Call ScrollText(Text1, numLines) End Sub Private Sub Command1_Click() InitializeTextBoxFast Label1.Caption = "Waiting for command" End Sub Private Sub Command2_Click() InitializeTextBoxSlow Label1.Caption = "Waiting for command" End Sub Private Sub Command4_Click() Unload Me End Sub Private Sub InitializeTextBoxSlow() 'This routine assigns the string to the textbox text property 'as the string is being built. This is the method that 'the MS VBKB detailed. I named it InitializeTextBoxSlow. Dim i As Integer Dim j As Integer Text1.Text = "" Label1.Caption = "Performing slow load..." 'just a pause to let the textbox and label update DoEvents For i = 1 To 100 Text1.Text = Text1.Text + "This is line " + Str$(i) 'Add 10 words to a line of text. For j = 1 To 10 Text1.Text = Text1.Text + " ...Word " + Str$(j) Next j 'Force a carriage return and linefeed 'VB3 users need to use chr$(13) & chr$(10) Text1.Text = Text1.Text + vbCrLf Next i Text1.Text = Text1.Text End Sub Private Sub InitializeTextBoxFast() 'This routine assigns the string to temporary string variable 'as the string is being built. Dim tmp As String Dim i As Integer Dim j As Integer Text1.Text = "" Label1.Caption = "Performing fast load..." 'just a wee pause to let the textbox and label update DoEvents For i = 1 To 100 tmp = tmp + "This is line " + Str$(i) 'Add 10 words to a line of text For j = 1 To 10 tmp = tmp + " ...Word " + Str$(j) Next j 'Force a carriage return and linefeed 'VB3 users need to use chr$(13) & chr$(10) tmp = tmp + vbCrLf Next i 'Now assign it to the text property. Text1.Text = tmp End Sub Function ScrollText(TextBox As Control, vLines As Integer) As Long Dim Success As Long Dim SavedWnd As Long Dim moveLines As Long 'save the window handle of the control that currently has focus SavedWnd = Screen.ActiveControl.hwnd moveLines = vLines 'Set the focus to the passed control (text control) TextBox.SetFocus 'Scroll the lines. Success = SendMessage(TextBox.hwnd, EM_LINESCROLL, 0, ByVal moveLines) 'Restore the focus to the original control Call PutFocus(SavedWnd) 'Return the number of lines actually scrolled ScrollText = Success End Function |
Comments |
Save the app & run. Try the Fast Load button first, then the Slow Load, and note the considerable time difference (be patient .. on a P166 with 64 megs of memory, the Slow method takes about 13 seconds). Note too that the two Initialize routines are identical, differing only that the "Fast" method uses a temporary string variable. |
|
|
|
|||||
|
|||||
|
|||||
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |