powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Глюк с Combobox если .ListCount = 0
4 сообщений из 4, страница 1 из 1
Глюк с Combobox если .ListCount = 0
    #38284157
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Воспроизвести элементарно.
Рисуем на форме пустой Combo1( в List ничего нет ).
Строго под ним внизу рисуем еще чего нибудь, например другой Combobox (для чистоты эксперимента поместите его вплотную к верхнему).
Рисуем еще чего-нибудь подальше , например кнопку.

Действия:
I.на верхнем Combobox нажать кнопку стрелка вниз (один раз).
попытаться "зайти" в нижний Combobox. (во всяком случае щелкая по его верхней части ничего не выйдет, пока не нажать кнопку в верхнем Combo1 еще раз).

II.на верхнем Combobox нажать кнопку стрелка вниз (один раз).
нажать на кнопку. Нажмется, но только со второго раза.
========
Дальше веселее.
Делаем форму WS_EX_LAYERED (у меня в проекте именно такая)
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Private Const WS_EX_LAYERED = &H80000
Private Const LWA_ALPHA = &H2

Private Declare Function SetLayeredWindowAttributes Lib "user32" _
 (ByVal hwnd As Long, ByVal crKey As Long, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long
  Dim aStyle As Long
  aStyle = GetWindowLong(Me.hwnd, GWL_EXSTYLE)
  aStyle = aStyle Or WS_EX_LAYERED
  Call SetWindowLong(Me.hwnd, GWL_EXSTYLE, aStyle)
  Call SetLayeredWindowAttributes(Me.hwnd, 0, 255, LWA_ALPHA)



Действия:
на верхнем Combobox нажать кнопку стрелка вниз (один раз).
Появится "пустой" список.
Но что интересно, его background всегда будет "прозрачным" - смотреть сквозь форму.
И никакие WM_CTLCOLORLISTBOX не могут сделать его хотя бы "белым".

==============================
Я выкрутился так:
У меня Combo1 все равно сабкласится, при выводе встроенного Listbox имеем WM_CTLCOLORLISTBOX , где lparam -hwnd этого Listbox.
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
    Case WM_CTLCOLORLISTBOX:
      'Debug.Print "WM_CTLCOLORLISTBOX"
      If Form1.Combo1.ListCount = 0 Then
        SetWindowPos lParam, 0, 0, 0, 0, 0, SWP_NOZORDER Or SWP_NOACTIVATE
      Else
        'какой-то код
        ...
        Exit Function
      End If


Т.е. грубо говоря, если список пустой, то его окно (невидимое? или глючное)
делаем нулевых размеров.
Тогда в любой другой контрол схотя бы со второго щелчка всегда попадаешь.
Ну, а если потом добавили Combo1.ListCount
то при след. нажатии на Combo1 список будет выводиться нормально
===================================
Но может это как-то по другому фиксится?
...
Рейтинг: 0 / 0
Глюк с Combobox если .ListCount = 0
    #38284510
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно как вариант при сабклассинге Combo1 игнорировать WM_COMMAND (при нажатии кнопки):
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
    Case WM_COMMAND:
      'Debug.Print "WM_COMMAND"
     ' LW_wParam = LOWORD(wParam)
     ' HW_wParam = HIWORD(wParam)
      'Debug.Print HW_wParam & "/" & LW_wParam
      If Form1.Combo1.ListCount = 0 Then
        Exit Function
      End If


Но тогда при пустом Combo1 кнопка вообще нажиматься не будет (даже визуально).
Красивше, когда она нажалась, но ничего не произошло (при этом все контролы доступны).
...
Рейтинг: 0 / 0
Глюк с Combobox если .ListCount = 0
    #38286003
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нормально делается так:

1. Сабклассим сам Combo1.
2. Ловим WM_CTLCOLORLISTBOX (при нажатии на кнопку Combobox).
И если List пустой, то сабклассим ListBox, а зоодно запоминаем его hwndCombo1ListBox=lparam:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
'для событий Combo1
Public Function NewCombo1WindowProc _
 (ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  
  Select Case Msg
    Case WM_CTLCOLORLISTBOX:
      Debug.Print "WM_CTLCOLORLISTBOX"
      If Form1.Combo1.ListCount = 0 Then
        hwndCombo1ListBox = lParam
        OldCombo1ListBoxWindowProc = SetWindowLong(lParam, GWL_WNDPROC, AddressOf NewCombo1ListBoxWindowProc)
      End If
    Case Else
  End Select 'Msg
  NewCombo1WindowProc = CallWindowProc _
   (OldCombo1WindowProc, hwnd, Msg, wParam, lParam)
End Function


3. Дальше надо отловить и отменить WM_PRINTCLIENT в Listbox и сразу сабклассинг Listbox-а снять.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Public Function NewCombo1ListBoxWindowProc _
 (ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  Select Case Msg
    Case WM_PRINTCLIENT
      Debug.Print "WM_PRINTCLIENT"
      SetWindowLong hwndCombo1ListBox, GWL_WNDPROC, OldCombo1ListBoxWindowProc
      Exit Function
    Case Else
      Debug.Print Msg
  End Select 'Msg
  NewCombo1ListBoxWindowProc = CallWindowProc _
   (OldCombo1ListBoxWindowProc, hwnd, Msg, wParam, lParam)
End Function
...
Рейтинг: 0 / 0
Глюк с Combobox если .ListCount = 0
    #38286005
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Собственно добивался того что на картинке.
Есть подозрение, что описанный глюк касается только Combo1 созданного в VB6. Через API создавать не пробовал.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Глюк с Combobox если .ListCount = 0
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]