VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)
首页 - 经验之谈 - 改变ComboBox中ListBox的宽度
发表评论(0)作者:不详, 平台:VB6.0+Win98, 阅读:11007, 日期:2001-09-28
改变ComboBox中ListBox的宽度


作者: cww 

  我们知道ComboBox是由一个EditBox(TextBox)和ListBox所组成,当我们按ComBox右方的
向下键,便能出现ListBox,内有许多的选项给我们选,而该ListBox的宽度,是和ComboBox
的度相同,而这个程式使之可以放宽,以容更多的字。

  原本这看来似乎也没麽什麽困难,只要取得该ListBox的hWnd便可以使用MoveWindow来更
动大小,可是问题就是在ListBox中hwnd的取得。我有一篇文章提到取得ComboBox 中Edit
Box的hwnd,(详见如何拦截ComboBox的mouse右键),使用的是EnumChildWindows来做,
但是,取得ListBox的方式则不然,因为这ListBox是属於DeskTopWindow的,所以无法由
EnumChildWindows找子Window来做,而只好由ComboBox收到WM_CTLCOLORLISTBOX的讯息
时,lParam便是该ListBox的hWnd上面着手,因而有以下的作法。

注释:以下在.bas
Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
  (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
  (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
  (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, _
   ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long

Public Const WM_CTLCOLORLISTBOX = &H134
Public Const GWL_WNDPROC = (-4)


Public preWinProc As Long
Private hwndList As Long
Private EverChange As Boolean
Public AddOnWidth As Long
Public Function wndproc(ByVal hwnd As Long, ByVal Msg As Long, _
                         ByVal wParam As Long, ByVal lParam As Long) As Long
注释:以下程式会设定ListBox的大小,再将之送往原来的Window Procedure
If Msg = WM_CTLCOLORLISTBOX Then
    注释:请处理Mouse Move的动作
    If Not EverChange Then
       Dim rect5 As RECT
       hwndList = lParam 注释:当收到WM_CTLCOLORLISTBOX时,lParam是ListBox的hwmd
       EverChange = True
       Call GetWindowRect(hwndList, rect5)
       x = rect5.Left
       y = rect5.Top
       dx = rect5.Right - rect5.Left + AddonWidth
       dy = rect5.Bottom - rect5.Top
       Call MoveWindow(hwndList, x, y, dx, dy, 1)
    End If
End If
注释:将之送往原来的Window Procedure
wndproc = CallWindowProc(preWinProc, hwnd, Msg, wParam, lParam)
End Function


注释:以下程式在Form1, form1中有一Combo1
Sub Form_Load()
Dim ret As Long
AddonWidth = 50 注释:设定ComboBox中ListBox的宽度加50 Pixel
注释:记录原本的Window Procedure的位址
preWinProc = GetWindowLong(Combo1.hwnd, GWL_WNDPROC)
注释:设定Combo1的window Procedure到wndproc
ret = SetWindowLong(Combo1.hwnd, GWL_WNDPROC, AddressOf wndproc)
End Sub

Private Sub Form_Unload(Cancel As Integer)
Dim ret As Long
注释:取消Message的截取,而使之又只送往原来的Window Procedure
ret = SetWindowLong(Combo1.hwnd, GWL_WNDPROC, preWinProc)
End Sub