Tip 63: Preventing List Box from Redrawing (Refreshing)

Created: April 24, 1995

Abstract

In a Visual Basic® application you can update the contents of a List Box control by using the AddItem or RemoveItem methods. However, if you do not want the contents of the modified List Box to be updated until all items have been added or deleted, you can use the Windows® application programming interface (API) SendMessage function to set a flag (WM_SETREDRAW) telling Windows not to update the control until you specifically ask it to do so. This article explains how you can prevent a List Box control from being updated immediately.

Using the WM_SETREDRAW Message

In a Visual Basic® application, you can use a List Box control to hold items such as names of people. When a user clicks on an item in a List Box control, that item is highlighted and is said to be selected. If a List Box's MultiSelect property is set to True, multiple items can be selected at one time. New items can be added to a List Box control by using the AddItem method, and items can be deleted using the RemoveItem method. However, as soon as you use AddItem or RemoveItem, the List Box's Refresh event is triggered, which in turn updates the contents of the control. This behavior may not be appropriate in cases where you want to suppress the updating process while adding, deleting, or changing a large number of entries.

You can force your Visual Basic application to update the List Box control at a specific time by using the Windows® application programming interface (API) SendMessage and SendMessageByString functions. You must send the WM_SETREDRAW message to the control to prevent the List Box from being updated. In addition, you must also send the actual data to the List Box by using the SendMessage function—you cannot use the AddItem or RemoveItem methods, because these methods will override the WM_SETREDRAW message.

Setting the redraw flag to TRUE turns the redraw function on, and setting the redraw flag to FALSE turns the redraw function off. Therefore, in a Visual Basic application that is updating a List Box, you must send the WM_SETREDRAW message before you actually begin manipulating the contents of the control. After you have finished adding or removing items from the List Box control, you can send another WM_SETREDRAW message to turn the redraw function on again. This will cause Windows to display the modified List Box control immediately.

Example Program

The program shown below displays two List Box controls on the form. You can select items from the first List Box by clicking them. Each selected item will be added to the second List Box control when you click the "Show Results" command button.

  1. Create a new project in Visual Basic. Form1 is created by default.

  2. Add the following Constant and Declare statements to the General Declarations section of Form1 (note that each Declare statement should be typed as a single line of code):
    Const WM_SetRedraw = &HB
    Const LB_ADDSTRING = &H401
    
    Declare Function SendMessage Lib "User" (ByVal hWnd As Integer, ByVal wMsg As 
       Integer, ByVal wParam As Integer, lParam As Any) As Integer
    
    Declare Function SendMessageByString Lib "User" Alias "PostMessage" (ByVal hWnd 
       As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As 
       String) As Integer
    
  3. Add the following code to the Form_Load event for Form1:
    Sub Form_Load()
      Dim X As Integer
      Dim D As Integer
      Dim S As String
      'Add some dummy data to List1
      For X = 0 To 15
          List1.AddItem "Item #" + Str$(X)
      Next X
    End Sub
    
  4. Add a Command Button control to Form1. Command1 is created by default. Set its Caption property to "Show Results".

  5. Add the following code to the Click event for Command1:
    Sub Command1_Click()
      'Show updated list box now
      X = SendMessage(List2.hWnd, WM_SetRedraw, 1, 0)
    End Sub
    
  6. Add a List Box control to Form1. List1 is created by default. Set its MultiSelect property to True.

  7. Add the following code to the DblClick event for List1:
    Sub List1_DblClick()
        'Disable the Repaint event
        X = SendMessage(List2.hWnd, WM_SetRedraw, 0, 0)
        
        S = List1.List(List1.ListIndex)
      ' Must use SendMessageByString instead of
      ' List2.AddItem S to prevent redrawing
        D = SendMessageByString(List2.hWnd, LB_ADDSTRING, 0, S)
    End Sub
    
  8. Add a second List Box control to Form1. List2 is created by default.