I've been searching the board here for a while and it seems that Listboxes can sport checkboxes with some custom API code, but I don't know where to start in finding that.
Does anyone here have any idea about making listboxes use checkboxs?
Thanks in advance.
Hi,
I cobbled together a sample based on code from Borje Hagsten from 2001 from the PB Forums. It seems to work. Give it a try.
Paul
'--------------------------------------------------------------------------------
Function FORM1_WM_CREATE ( _
hWndForm As Dword, _ ' handle of Form
ByVal UserData As Long _ ' optional user defined Long value
) As Long
Local i As Long
For i = 1 To 100
FF_ListBox_AddString HWND_FORM1_LIST1, "Item " & Str$(i)
Next
End Function
'--------------------------------------------------------------------------------
Function FORM1_CUSTOM ( _
hWndForm As Dword, _ ' handle of Form
wMsg As Long, _ ' type of message
wParam As Dword, _ ' first message parameter
lParam As Long _ ' second message parameter
) As Long
Local hWndControl As Dword
Local rc As Rect
Local pt As PointApi
hWndControl = HWND_FORM1_LIST1
Select Case wMsg
Case %WM_CTLCOLORLISTBOX
If lParam = IDC_FORM1_LIST1 Then
Function = GetSysColorBrush(%COLOR_WINDOW)
End If
Case %WM_DRAWITEM
Local lpdis As DRAWITEMSTRUCT Ptr, zTxt As Asciiz * 64
lpdis = lParam
If @lpdis.itemID = &HFFFFFFFF& Then Exit Function
Select Case @lpdis.itemAction
Case %ODA_DRAWENTIRE, %ODA_SELECT
'DRAW BACKGROUND
FillRect @lpdis.hDC, @lpdis.rcItem, GetSysColorBrush(%COLOR_WINDOW)
'DRAW TEXT
SetBkColor @lpdis.hDC, GetSysColor(%COLOR_INFOBK) 'Set text Background
SetTextColor @lpdis.hDC, GetSysColor(%COLOR_INFOTEXT) 'Set text color
SendMessage hWndControl, %LB_GETTEXT, @lpdis.itemID, VarPtr(zTxt) 'Get text
TextOut @lpdis.hDC, 18, @lpdis.rcItem.ntop + 2, zTxt, Len(zTxt) 'Draw text
'DRAW INVERTED SELECTION
If (@lpdis.itemState And %ODS_SELECTED) Then 'if selected
rc.nLeft = 16 : rc.nRight = @lpdis.rcItem.nRight 'Set cordinates
rc.ntop = @lpdis.rcItem.ntop
rc.nbottom = @lpdis.rcItem.nbottom
InvertRect @lpdis.hDC, rc 'invert area around text only
End If
'DRAW CHECKBOX
rc.nLeft = 2 : rc.nRight = 15 'Set cordinates
rc.ntop = @lpdis.rcItem.ntop + 2
rc.nbottom = @lpdis.rcItem.nbottom - 1
If SendMessage(hWndControl, %LB_GETITEMDATA, @lpdis.itemID, 0) Then 'checked or not? itemdata knows
DrawFrameControl @lpdis.hDC, rc, %DFC_BUTTON, %DFCS_BUTTONCHECK Or %DFCS_CHECKED
Else
DrawFrameControl @lpdis.hDC, rc, %DFC_BUTTON, %DFCS_BUTTONCHECK
End If
Function = %TRUE : Exit Function
Case %ODA_FOCUS
DrawFocusRect @lpdis.hDC, @lpdis.rcItem 'draw focus rectangle
End Select
End Select
End Function
'--------------------------------------------------------------------------------
Function FORM1_LIST1_CUSTOM ( _
ControlIndex As Long, _ ' index in Control Array
hWndForm As Dword, _ ' handle of Form
hWndControl As Dword, _ ' handle of Control
wMsg As Long, _ ' type of message
wParam As Dword, _ ' first message parameter
lParam As Long _ ' second message parameter
) As Long
Local rc As Rect
Local t As Long
Local itd As Long
Local pt As PointApi
Select Case wMsg
Case %WM_KEYDOWN
If wParam = %VK_SPACE Then 'Respond to space bar
t = SendMessage(hWndControl, %LB_GETCURSEL, 0, 0) 'get selected
itd = Not SendMessage(hWndControl, %LB_GETITEMDATA, t, 0) 'get toggled item data
Call SendMessage(hWndControl, %LB_SETITEMDATA, t, itd) 'set toggleded item data
Call SendMessage(hWndControl, %LB_GETITEMRECT, t, VarPtr(rc)) 'get sel. item's rect
InvalidateRect hWndControl, rc, 0 : UpdateWindow hWndControl 'update sel. item only
Function = 0 : Exit Function 'return zero
End If
Case %WM_LBUTTONDOWN
If wParam = %MK_LBUTTON Then 'respond to mouse click
pt.x = LoWrd(lParam) : pt.y = HiWrd(lParam) 'get cursor pos
t = SendMessage(hWndControl, %LB_ITEMFROMPOINT, 0, MakLng(pt.x, pt.y)) 'get sel. item
SendMessage hWndControl, %LB_GETITEMRECT, t, VarPtr(rc) 'get sel. item's rect
rc.nLeft = 2 : rc.nRight = 15 'checkbox cordinates
If PtInRect(rc, pt.x, pt.y) Then 'if in checkbox
itd = Not SendMessage(hWndControl, %LB_GETITEMDATA, t, 0) 'get toggled item data
SendMessage hWndControl, %LB_SETITEMDATA, t, itd 'set toggled item data
InvalidateRect hWndControl, rc, 0 : UpdateWindow hWndControl 'update sel. item only
End If
End If
End Select
End Function
Oh, I forgot to add that you need to set the following two styles for your ListBox:
LBS_OWNERDRAWFIXED
LBS_HASSTRINGS
Paul,
I used your example code to created an example project. But I am confused about how to "get" the select list items.
What I want to be able to do is place the selected checked items from the ListBox in the popup listbox window and place them in a TextBox on the main form.
Can someone show me how to do this?
Here's the project:
Marty,
I only added code to the FORMDGMSG_COMMAND1_BN_CLICKED function.
David
David,
Thank you you have been most helpful. One question: You use syntax that I hadn't seen before:
Selected += FF_ListBox_GetText( HWND_FORMDGMSG_LIST1, i ) & $CrLf
I assume this is a short hand form of:
Selected = Selected & FF_ListBox_GetText( HWND_FORMDGMSG_LIST1, i ) & $CrLf
I like it, I'll have to remember that syntax. Clear, simple, concise.
Yea, isn't PowerBasic great? Take a look at the 'Let' statement in the PB docs. Go down to the 'compound assignments' section.
There are a few more permutations of that assignment operator. You can use them with numeric variables as well.