Listboxes with Checkboxes

Started by Laura Clement, March 19, 2010, 09:16:16 AM

Previous topic - Next topic

Laura Clement

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.

Paul Squires

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

Paul Squires
PlanetSquires Software

Paul Squires

Oh, I forgot to add that you need to set the following two styles for your ListBox:

LBS_OWNERDRAWFIXED
LBS_HASSTRINGS

Paul Squires
PlanetSquires Software

Martin Francom

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:

David Kenny

Marty,

I only added code to the FORMDGMSG_COMMAND1_BN_CLICKED function.

David

Martin Francom

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.     

David Kenny

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.