I want to create a ListBox in VBA with WinAPI. I managed to create it, but ListBox doesn't respond to actions - no scrolling, no selecting. None of this works. It looks like it's disabled. How to make it respond to actions?
The following code was used to create and fill ListBox
.
WinAPI functions
Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Declare Function CreateWindow Lib "user32.dll" Alias "CreateWindowExA" ( _
ByVal dwExStyle As WindowStylesEx, _
ByVal lpClassName As String, _
ByVal lpWindowName As String, _
ByVal dwStyle As Long, _
ByVal x As Long, _
ByVal y As Long, _
ByVal nWidth As Long, _
ByVal nHeight As Long, _
ByVal hWndParent As Long, _
ByVal hMenu As Long, _
ByVal hInstance As Long, _
ByVal lpParam As Long) As Long
Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" ( _
ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Any) As Long
Creating ListBox:
Private hlist As Long
hlist = WinAPI.CreateWindow( _
dwExStyle:=WS_EX_CLIENTEDGE, _
lpClassName:="LISTBOX", _
lpWindowName:="MYLISTBOX", _
dwStyle:=WS_CHILD Or WS_VISIBLE Or WS_VSCROLL Or WS_SIZEBOX Or LBS_NOTIFY Or LBS_HASSTRINGS, _
x:=10, _
y:=10, _
nWidth:=100, _
nHeight:=100, _
hWndParent:=WinAPI.FindWindow("ThunderDFrame", Me.Caption), _
hMenu:=0, _
hInstance:=Application.hInstance, _
lpParam:=0 _
)
Filling ListBox:
Dim x As Integer
For x = 10 To 1 Step -1
Call WinAPI.SendMessage(hlist, LB_INSERTSTRING, 0, CStr(x))
Next
Result:
The answer is to call
SetParent
thanks to David Hefferman for pointing that out.So no need to subclass at all.
The Userform class
Your listbox is not interactable because it doesn't receive the messages sent to the window. It seems that all the messages are handled by a child container:
To make it work, call
CreateWindow
withhWndParent
set to handle of this container :and for the declarations: