Visual Basic Combo API
SendMessage: Make a Style-0 Combo Edit Read-Only
     
Posted:   Saturday May 5, 1999
Updated:   Monday December 26, 2011
     
Applies to:   VB4-32, VB5, VB6
Developed with:   VB5, Windows 95
OS restrictions:   None
Author:   VBnet - Randy Birch
     

Related:  

 

WM_CONTEXTMENU: Kill the Default Text Box Context Menu
SendMessage: Make a Style-0 Combo Edit Read-Only
FindWindowEx: Obtain Combo Box Edit Window Handle
GetComboBoxInfo: Obtain Combo Box Edit and List Handles on Win98/NT5
     
 Prerequisites
None; this functionality built-in to VB6 (Locked property).

With VB5 and earlier there is no built-in mechanism to prevent the user from typing or pasting text into the edit portion of a combo box set to Style-0. In VB6 this functionality is provided by setting the combo's locked property.

This demo shows how to use FindWindowEx and SendMessage with EM_SETREADONLY to disable the edit portion while maintaining the ability to set or change its contents through code. Depending on the operating system versions you support, you may be able to use GetComboBoxInfo instead of FindWindowEx; see the demo above for that code.

 BAS Module Code
None.

 Form Code
Toss a Combo (style 0) and a command button onto a form, using the default names, and add following code:

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 Const EM_SETREADONLY = &HCF

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 SetWindowText Lib "user32" _
   Alias "SetWindowTextA" _
  (ByVal hwnd As Long, _
   ByVal lpString As String) As Long

Private Declare Function FindWindowEx Lib "user32" _
   Alias "FindWindowExA" _
  (ByVal hWnd1 As Long, _
   ByVal hWnd2 As Long, _
   ByVal lpsz1 As String, _
   ByVal lpsz2 As String) As Long
   
   
Private Sub Form_Load()

  'fill a combo with 10 of the 
  'system's screen fonts.
   Dim i As Integer

   For i = 1 To 10
      Combo1.AddItem Screen.Fonts(i)
   Next

End Sub


Private Sub Command1_Click()

   Dim hwndEdit As Long
   
  'get the handle to the edit portion
  'of the combo control
   hwndEdit = FindWindowEx(Combo1.hwnd, 0&, vbNullString, vbNullString)
   
   If hwndEdit <> 0 Then
     
     'prove you got it by changing its text (style 0 only)
      Call SetWindowText(hwndEdit, "You can copy but not change this text")
      
     'and disable the edit control's editing ability
      Call SendMessage(hwndEdit, EM_SETREADONLY, 1&, ByVal 0&)

   End If
   
End Sub
 Comments
Run the project, and click the button. You can not edit the text in the control, yet you can select anything in the list, and copy the selected item using the keyboard or context menu.

To enable editing, call the method again, but pass 0& as wParam in the SendMessage call. This demonstrates toggling between the two states:

Private Sub Command1_Click()

   Dim hwndEdit As Long
   Static state As Boolean
   
  'get the handle to the edit portion
  'of the combo control
   hwndEdit = FindWindowEx(Combo1.hwnd, 0&, vbNullString, vbNullString)
   
   If hwndEdit <> 0 Then
     
     'reflect the state (style 0 only)
      state = Not state
      Call SendMessage(hwndEdit, EM_SETREADONLY, CLng(Abs(state)), ByVal 0&)
      Call SetWindowText(hwndEdit, "You can copy but not change this text")

   End If
   
End Sub

Note: Due to the implementation of FindWindowEx in this demo, the command click routine will (usually) always find the same combo giving the appearance it works only on one combo box on the form. If you can obtain the hwnd to a specific combo of interest the code can be applied to two or more combos as required. However, a better solution - assuming your code will not be run on Windows 95 (or you really don't care if the combo is editable on 95), would be to integrate the code from GetComboBoxInfo: Obtain Combo Box Edit and List Handles on Win98/NT5 on Win98/Win2000/WinXP (see related pages above). That code uses a COMBOBOXINFO structure to retrieve the constituent portions of the combo box including the edit portion's hwnd. With this code you could replace the FindWindowEx call in this demo with a call to GetComboEditHandle(), as that function accepts specific controls as input parameters returning the hwnd of the edit portion of the passed combo.


 
 

PayPal Link
Make payments with PayPal - it's fast, free and secure!

 
 
 
 

Copyright 1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy

 

 

Hit Counter