Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Tabs in Comboboxes

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Tabs in Comboboxes

    In answer to http://www.powerbasic.com/support/pb...ad.php?t=40451

    Code:
    ' draw a combobox with tabbed text items
    
    ' ----------------------------------------
    ' documentation
    ' ----------------------------------------
    
    ' Definition:    add %CBS_OWNERDRAWFIXED
    '
    ' SDK:
    '    hWndChild = CreateWindowEx( _
    '        %WS_EX_CLIENTEDGE, _                               
    '        "Combobox", _                                      
    '        "", _                                                  
    '        %WS_CHILD Or %WS_VISIBLE Or %WS_VSCROLL Or %WS_BORDER Or %WS_TABSTOP Or _
    '        %CBS_DROPDOWNLIST Or %CBS_OWNERDRAWFIXED Or %CBS_HASSTRINGS Or %CBS_SORT, _
    '        5, 5, _                       
    '        140, 120, _                      
    '        hWnd, _
    '        %IDC_COMBO1, _                       
    '        ghInstance, _
    '        ByVal %NULL)
    '
    '
    ' DDT: 
    '    Control Add ComboBox, hDlg, %IDC_COMBO1, , 5, 5, 140, 120, _
    '        %WS_CHILD Or %WS_VISIBLE Or %WS_TABSTOP Or %WS_VSCROLL Or %CBS_DROPDOWNLIST Or _
    '        %CBS_SORT Or %CBS_HASSTRINGS Or %CBS_OWNERDRAWFIXED, _
    '        %WS_EX_LEFT Or %WS_EX_LTRREADING Or %WS_EX_RIGHTSCROLLBAR
    
    
    ' Callback:
    '
    ' SDK: 
    '    Case %WM_DRAWITEM
    '        If wParam = %IDC_COMBO1 Then
    '            Function = tabcombo_DrawItem(GetDlgItem(hWnd, wParam), wParam, lParam)
    '        End If
    '
    '
    ' DDT: 
    '    Case %WM_DRAWITEM
    '        If Cb.wParam = %IDC_COMBO1 Then
    '            Function = tabcombo_DrawItem(GetDlgItem(Cb.Hndl, Cb.wParam), Cb.wParam, Cb.lParam)
    '        End If
    
    
    ' User-defined tabs:
    '    Local lngTabs As Long            ' 0-based count of number of tabs
    '    Local plngTabs As Long Ptr       ' pointer to array of tabs
    '
    '    lngTabs = 2
    '    ' allocate memory
    '    plngTabs = HeapAlloc(GetProcessHeap(), %HEAP_ZERO_MEMORY, (lngTabs + 1) * 4)
    '    ' assign values - in device units
    '    If IsTrue plngTabs Then
    '        @plngTabs[0] = 0
    '        @plngTabs[1] = 120
    '        @plngTabs[2] = 240
    '    End If
    '    ' ...
    '    ' define tabs either in %WM_DRAWITEM - local vars, 
    '    ' or in %WM_CREATE (SDK) or %WM_INITDIALOG (DDT) - global/static vars
    '    If IsTrue plngTabs Then
    '         Function = tabcombo_DrawItem(GetDlgItem(hWnd, wParam), wParam, lParam, plngTabs, lngTabs)
    '    End If
    '    ' ...
    '    ' free memory
    '    HeapFree GetProcessHeap(), 0, ByVal plngTabs
    
    
    ' ----------------------------------------
    
    Function tabcombo_DrawItem( _
        ByVal hWnd As Dword, _
        ByVal wParam As Dword, _
        ByVal lParam As Long, _
        Optional ByVal vplngTab As Long Ptr, _
        Optional ByVal vlngUBTab As Long _
    ) As Long
    ' Purpose:       WM_DRAWITEM procedure for ownerdrawn combobox to draw text separated by tabs
    ' Parameters:    hWnd - handle of combobox window
    '                wParam - control id of combobox
    '                lParam - pointer to draw item structure
    '                vplngTab - optional pointer to 0-based array of tab positions - in device units 
    '                vlngUBTab - optional upper bound of this array (required if vplngTab used)
    ' Called by:     %WM_DRAWITEM
    ' Original:      PB Forum, Borje Hagsten, 2004-01-03. Public domain.
    '                http://www.powerbasic.com/support/forums/Forum7/HTML/002194.html
    ' Note:          1. if no vplngTab, tabs are left-aligned using %DT_EXPANDTABS
    '                2. if vplngTab, use -ve numbers (e.g. -120, -180, -240) for right-align; +ve for left-align
    '                3. if vplngTab, tab stops must be sorted in increasing order
    ' Returns:       T: successful; F otherwise
        Local lngRtn As Long
        Local lngTabStd As Long                ' T: use left-aligned tabs; F: use array of tab positions
        Local lngXPos As Long
        Local lngYPos As Long
        Local szTxt As Asciiz * 300
        Local lpDis As DRAWITEMSTRUCT Ptr
        Local tm As TEXTMETRIC
    
        lpDis = lParam
        If @lpDis.itemID = &HFFFFFFFF& Then
            ' empty list
            GoTo tabcombo_DrawItem_Exit
        End If
        Select Case As Long @lpDis.itemAction
            Case %ODA_DRAWENTIRE, %ODA_SELECT
                ' clear background
                If (@lpDis.itemState And %ODS_SELECTED) = 0 Then
                    ' not selected
                    SetBkColor @lpDis.hDC, GetSysColor(%COLOR_WINDOW)
                    SetTextColor @lpDis.hDC, GetSysColor(%COLOR_WINDOWTEXT)
                    FillRect @lpDis.hDC, @lpDis.rcItem, GetSysColorBrush(%COLOR_WINDOW)
                Else
                    ' selected
                    SetBkColor @lpDis.hDC, GetSysColor(%COLOR_HIGHLIGHT)
                    SetTextColor @lpDis.hDC, GetSysColor(%COLOR_HIGHLIGHTTEXT)
                    FillRect @lpDis.hDC, @lpDis.rcItem, GetSysColorBrush(%COLOR_HIGHLIGHT)
                End If
                ' get text
                SendMessage hWnd, %CB_GETLBTEXT, @lpDis.itemID, VarPtr(szTxt)
                ' test if array of tab-positions is to be used
                lngTabStd = IIf&(vplngTab = 0, %TRUE, %FALSE)
                If IsFalse lngTabStd Then
                    lngTabStd = IIf&(vlngUBTab < 0, %TRUE, %FALSE)
                End If
                If lngTabStd Then
                    ' draw text with left-aligned tabs
                    DrawText @lpDis.hDC, szTxt, Len(szTxt), @lpDis.rcItem, %DT_SINGLELINE Or %DT_LEFT Or %DT_VCENTER Or %DT_EXPANDTABS
                    If (@lpDis.itemState And %ODS_SELECTED) Then
                        ' if selected, draw a focus rectangle around the item
                        Call DrawFocusRect(@lpDis.hDC, @lpDis.rcItem)
                    End If
                Else
                    ' draw text with tab positions taken from array
                    ' .. calculate X-pos  (edit part and listbox are different)
                    If (@lpDis.itemState And %ODS_COMBOBOXEDIT) Then
                        lngXPos = 6
                        ' if to draw in edit part (%ODS_COMBOBOXEDIT = &H1000)
                    Else
                        ' listbox part
                        lngXPos = 3
                    End If
                    ' .. calculate Y-pos  (vcenter in line)
                    GetTextMetrics @lpDis.hDC, tm        ' need character height
                    lngYPos = @lpDis.rcItem.nTop + ((@lpDis.rcItem.nBottom - @lpDis.rcItem.nTop) - tm.tmHeight) \ 2
                    ' .. set tab positions
                    TabbedTextOut @lpDis.hDC, lngXPos, lngYPos, szTxt, Len(szTxt), vlngUBTab + 1, @vplngTab[0], 0
                End If
                ' success
                lngRtn = %TRUE
        End Select
    tabcombo_DrawItem_Exit:
        Function = lngRtn
    End Function
Working...
X