Jump to content

Combobox with header/group


 Share

Recommended Posts

Hello, like title is possible to do in "pure" autoit?

I have see many images of this:

1wuOl4F.jpg

But not many information about how to do it, i have read something about WPF or similar but nothing of interest:

http://stackoverflow.com/questions/14866064/windows-form-how-add-header-not-selectable-in-combobox-item-in-c

Maybe something in _GUICtrlComboBoxEx? Dunno, nothing about "hearder" inside.

Thanks for the help

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

Yes, i did this in this small example:

#Include <GuiComboBox.au3>
#include <GUIConstantsEx.au3>
#include <array.au3>
#include <File.au3>

Const $sCSV = @AppDataDir & "\2cbo.CSV"
Const $sElect = "bitte auswählen"
Dim $a_sCSV, $aSplit, $scboChr = ""
_FileReadToArray($sCSV,$a_sCSV)
Dim $aCSV[$a_sCSV[0]][2]
for $i = 1 to UBound($a_sCSV) - 1
    ConsoleWrite($i & $a_sCSV[$i] & @CRLF)
    $aSplit = StringSplit($a_sCSV[$i],";")
    if not StringInStr($scboChr,$aSplit[1]) Then $scboChr &= $aSplit[1] & "|"
    $aCSV[$i-1][0] = $aSplit[1]
    $aCSV[$i-1][1] = $aSplit[2]
Next
ConsoleWrite($scboChr & @CRLF)

$hGui = GUICreate("2 Comboboxen aus 1er CSV ", 250, 120, 302, 218)
$hcboChr = GUICtrlCreateCombo($sElect, 8, 8, 200, 25)
GUICtrlSetData(-1,$scboChr)
$hcboChrNr  = GUICtrlCreateCombo("",8,35,200,25)
$hbtnExit = GUICtrlCreateButton("Be&enden", 8, 65)

GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE, $hbtnExit
            Exit
        Case $hcboChr
            $sVal = GUICtrlRead($hcboChr)
            if $sVal <> $sElect Then
                $aSplit = _ArrayFindAll($aCSV,$sVal,0,0,True,True,0)
                GUICtrlSetData($hcboChrNr,"")
                $scboChr = ""
                for $i = 0 to UBound($aSplit) - 1
                    $scboChr &= $aCSV[$aSplit[$i]][1] & "|"
                Next
                ConsoleWrite($scboChr & @CRLF)
                GUICtrlSetData($hcboChrNr,$scboChr)
                _GUICtrlComboBox_SetCurSel($hcboChrNr, 0)
            EndIf
    EndSwitch
WEnd

I used this file for testing: 2cbo.csv

Link to comment
Share on other sites

No, i think i wasn't clear. Take at look at image, the left side and forget about the right side. Did you see Friut, Meat and Vegetable? That are headers, something you can't select and divide other entry, like title or something similar. Another image is in the link on the first post, here:

j9QFB.png

In this case are "Header1" and "Hearder2". Is possible to reproduce this behavior in autoit? Add header to a combobox? Thanks

 

EDIT: Just a try:

#include <GUIConstantsEx.au3>
#include <ComboConstants.au3>
#include <GuiComboBox.au3>

; Create a GUI with various controls.
Local $hGUI = GUICreate("Example", 300, 200)

; Create a combobox control.
Local $idComboBox = GUICtrlCreateCombo("", 10, 10, 185, 20, $CBS_DROPDOWNLIST)
Local $idClose = GUICtrlCreateButton("Close", 210, 170, 85, 25)
GUICtrlSetData($idComboBox, "Header 1|   Item 1|   Item 2|Header 2|   Item 3|   Item 4")

; Display the GUI.
GUISetState(@SW_SHOW, $hGUI)

;~ _GUICtrlComboBox_ShowDropDown($idComboBox, True)
_GUICtrlComboBox_SetCurSel($idComboBox, 1)

; Loop until the user exits.
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE, $idClose
            ExitLoop
    EndSwitch
    Switch _GUICtrlComboBox_GetCurSel($idComboBox)
        Case 0
            _GUICtrlComboBox_SetCurSel($idComboBox, 1)
        Case 3
            _GUICtrlComboBox_SetCurSel($idComboBox, 4)
    EndSwitch
WEnd

; Delete the previous GUI and all controls.
GUIDelete($hGUI)

Sometime blink, bad!

It display on the "title" of the combobox a text without click, wrong!

When you click it show the item with space, wrong!

Opened to better-improved version :D

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

  • Moderators

Terenz,

I have been playing with various combo functions and styles all afternoon and I cannot get exactly what you want - the best I can manage is this:

#include <GUIConstantsEx.au3>
#include <GuiComboBox.au3>
#include <StringConstants.au3>

$sData = "Fruit|  Apples|  Pears|  Strawberries|Meat|  Bacon|  Chicken|Vegetables|  Cabbages"

$hGUI = GUICreate("Test", 500, 500)

$cCombo = GUICtrlCreateCombo("", 10, 10, 200, 20)
GUICtrlSetData($cCombo, $sData)

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $cCombo

            $sChoice = GUICtrlRead($cCombo)
            ; Look for the separator
            If StringLeft($sChoice, 2) = "  " Then
                $sChoice = StringTrimLeft($sChoice, 2)
            Else
                $sChoice = ""
            EndIf

            _GUICtrlComboBox_SetEditText($cCombo, $sChoice)
    EndSwitch

WEnd

Any use?

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Based on the code found in topic I posted earlier

#include <GUIComboBox.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <FontConstants.au3>
#include <BorderConstants.au3>
#include <WinAPI.au3>


Global Const $ODT_MENU = 1
Global Const $ODT_LISTBOX = 2
Global Const $ODT_COMBOBOX = 3
Global Const $ODT_BUTTON = 4
Global Const $ODT_STATIC = 5
Global Const $ODT_HEADER = 100
Global Const $ODT_TAB = 101
Global Const $ODT_LISTVIEW = 102
Global Const $ODA_DRAWENTIRE = 1
Global Const $ODA_SELECT = 2
Global Const $ODA_FOCUS = 4
Global Const $ODS_SELECTED = 1
Global Const $ODS_GRAYED = 2
Global Const $ODS_DISABLED = 4
Global Const $ODS_CHECKED = 8
Global Const $ODS_FOCUS = 16
Global Const $ODS_DEFAULT = 32
Global Const $ODS_HOTLIGHT = 64
Global Const $ODS_INACTIVE = 128
Global Const $ODS_NOACCEL = 256
Global Const $ODS_NOFOCUSRECT = 512
Global Const $ODS_COMBOBOXEDIT = 4096
Global Const $clrWindowText = _WinAPI_GetSysColor($COLOR_WINDOWTEXT)
Global Const $clrHighlightText = _WinAPI_GetSysColor($COLOR_HIGHLIGHTTEXT)
Global Const $clrHighlight = _WinAPI_GetSysColor($COLOR_HIGHLIGHT)
Global Const $clrWindow = _WinAPI_GetSysColor($COLOR_WINDOW)
Global Const $tagDRAWITEMSTRUCT = _
        'uint CtlType;' & _
        'uint CtlID;' & _
        'uint itemID;' & _
        'uint itemAction;' & _
        'uint itemState;' & _
        'hwnd hwndItem;' & _
        'hwnd hDC;' & _
        $tagRECT & _
        ';ulong_ptr itemData;'
Global Const $tagMEASUREITEMSTRUCT = _
        'uint CtlType;' & _
        'uint CtlID;' & _
        'uint itemID;' & _
        'uint itemWidth;' & _
        'uint itemHeight;' & _
        'ulong_ptr itemData;'

Global $iItemWidth, $iItemHeight
Global $hGUI
Global $ComboBox
Global $hBrushNorm = _WinAPI_CreateSolidBrush($clrWindow)
Global $hBrushSel = _WinAPI_CreateSolidBrush($clrHighlight)

Global $g_hFont = _WinAPI_CreateFont(20, 0, 0, 0, 800, False, False, False, $DEFAULT_CHARSET, _
        $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Arial') ;Font used for titles
Global $hFont2=_WinAPI_CreateFont(15, 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, _
        $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Arial')

Global $bFoundTitle=False, $sTextPrefix="    "
Global $aTitles[2]=["Title1", "Title2"] ; a n array that holds text of item which represent titles

GUIRegisterMsg($WM_MEASUREITEM, '_WM_MEASUREITEM')
GUIRegisterMsg($WM_DRAWITEM, '_WM_DRAWITEM')
;GUIRegisterMsg($WM_COMMAND, '_WM_COMMAND')

$hGUI = GUICreate('Test', 220, 300)
$ComboBox = GUICtrlCreateCombo('', 10, 10, 200, 300, BitOR($WS_CHILD, $CBS_OWNERDRAWVARIABLE, $CBS_HASSTRINGS, $CBS_DROPDOWNLIST))
GUICtrlSetData($ComboBox, "Medabi|V!c†o®|joelson0007|Title1|JScript|Belini|Jonatas|Title2|AutoIt v3|www.autoitbrasil.com|-|www.autoitscript.com", "Medabi")
GUISetState()

Do

Until GUIGetMsg() = $GUI_EVENT_CLOSE

_WinAPI_DeleteObject($hBrushSel)
_WinAPI_DeleteObject($hBrushNorm)
_WinAPI_DeleteObject($g_hFont)
_WinAPI_DeleteObject($hFont2)


GUIDelete()

Func _WM_MEASUREITEM($hWnd, $iMsg, $iwParam, $ilParam)

    Local $stMeasureItem = DllStructCreate($tagMEASUREITEMSTRUCT, $ilParam)

    If DllStructGetData($stMeasureItem, 1) = $ODT_COMBOBOX Then
        Local $iCtlType, $iCtlID, $iItemID
        Local $hComboBox
        Local $tSize
        Local $sText
        $iCtlType = DllStructGetData($stMeasureItem, 'CtlType')
        $iCtlID = DllStructGetData($stMeasureItem, 'CtlID')
        $iItemID = DllStructGetData($stMeasureItem, 'itemID')
        $iItemWidth = DllStructGetData($stMeasureItem, 'itemWidth')
        $hComboBox = GUICtrlGetHandle($iCtlID)

        ;_GUICtrlComboBox_GetLBText($hComboBox, $iItemID, $sText)
        ;If $sText = "-" Then
        ;   DllStructSetData($stMeasureItem, "itemHeight", 3)
        ;Else
        ;   DllStructSetData($stMeasureItem, "itemHeight", DllStructGetData($stMeasureItem, 'itemHeight') + 4)
        ;EndIf
        $iItemHeight = DllStructGetData($stMeasureItem, 'itemHeight')
    EndIf

    $stMeasureItem = 0

    Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_MEASUREITEM

Func _WM_DRAWITEM($hWnd, $iMsg, $iwParam, $ilParam)
    Local $tDIS = DllStructCreate($tagDRAWITEMSTRUCT, $ilParam)
    Local $iCtlType, $iCtlID, $iItemID, $iItemAction, $iItemState
    Local $clrForeground, $clrBackground
    Local $hWndItem, $hDC, $hOldPen, $hOldBrush
    Local $tRect
    Local $sText
    Local $iLeft, $iTop, $iRight, $iBottom
    $iCtlType = DllStructGetData($tDIS, 'CtlType')
    $iCtlID = DllStructGetData($tDIS, 'CtlID')
    $iItemID = DllStructGetData($tDIS, 'itemID')
    $iItemAction = DllStructGetData($tDIS, 'itemAction')
    $iItemState = DllStructGetData($tDIS, 'itemState')
    $hWndItem = DllStructGetData($tDIS, 'hwndItem')
    $hDC = DllStructGetData($tDIS, 'hDC')
    $tRect = DllStructCreate($tagRECT)

    If $iCtlType = $ODT_COMBOBOX And $iCtlID = $ComboBox Then
        Switch $iItemAction
            Case $ODA_DRAWENTIRE
                For $i = 1 To 4
                    DllStructSetData($tRect, $i, DllStructGetData($tDIS, $i + 7))
                Next

                _GUICtrlComboBox_GetLBText($hWndItem, $iItemID, $sText)

                Local $iTop = DllStructGetData($tRect, 2)
                ; search array of titles
                For $i=0 To UBound($aTitles)-1
                    If $sText=$aTitles[$i] Then
                        $bFoundTitle=True
                        If Not BitAND($iItemState, $ODS_COMBOBOXEDIT) Then
                        DllStructSetData($tRect, 2, $iTop + 1)
                         _WinAPI_SelectObject($hDC, $g_hFont)
                         _WinAPI_DrawText($hDC,$sText,$tRect,$DT_LEFT) ; if item's text it found then draw it with desired font
                         ExitLoop
                        EndIf
                    EndIf
                Next

                If $sText <> "" And Not $bFoundTitle  Then
                    If BitAND($iItemState, $ODS_SELECTED) Then
                        $clrForeground = _WinAPI_SetTextColor($hDC, $clrHighlightText)
                        $clrBackground = _WinAPI_SetBkColor($hDC, $clrHighlight)
                        _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), $hBrushSel)
                    Else
                        $clrForeground = _WinAPI_SetTextColor($hDC, $clrWindowText)
                        $clrBackground = _WinAPI_SetBkColor($hDC, $clrWindow)
                        _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), $hBrushNorm)
                    EndIf
                    DllStructSetData($tRect, 2, $iTop + 2);4)
                    _WinAPI_SelectObject($hDC,$hFont2)
                    _WinAPI_DrawText($hDC, $sTextPrefix & $sText, $tRect, $DT_LEFT)
                    _WinAPI_SetTextColor($hDC, $clrForeground)
                    _WinAPI_SetBkColor($hDC, $clrBackground)
                    _WinAPI_SetBkMode($hDC, $TRANSPARENT)
                EndIf
                $bFoundTitle=False
            Case $ODA_SELECT, $ODA_FOCUS
                For $i = 1 To 4
                    DllStructSetData($tRect, $i, DllStructGetData($tDIS, $i + 7))
                Next

                _GUICtrlComboBox_GetLBText($hWndItem, $iItemID, $sText)

                Local $iTop = DllStructGetData($tRect, 2)
                For $i=0 To UBound($aTitles)-1
                    If $sText=$aTitles[$i] Then
                        $bFoundTitle=True
                        If Not BitAND($iItemState, $ODS_COMBOBOXEDIT) Then
                        DllStructSetData($tRect, 2, $iTop + 1)
                         _WinAPI_SelectObject($hDC, $g_hFont)
                         _WinAPI_DrawText($hDC,$sText,$tRect,$DT_LEFT)
                         ExitLoop
                        EndIf
                    EndIf
                Next
                If $sText <> "" And Not $bFoundTitle Then
                    If BitAND($iItemState, $ODS_SELECTED) Then
                        $clrForeground = _WinAPI_SetTextColor($hDC, $clrHighlightText)
                        $clrBackground = _WinAPI_SetBkColor($hDC, $clrHighlight)
                        _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), $hBrushSel)
                    Else
                        $clrForeground = _WinAPI_SetTextColor($hDC, $clrWindowText)
                        $clrBackground = _WinAPI_SetBkColor($hDC, $clrWindow)
                        _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), $hBrushNorm)
                    EndIf
                    DllStructSetData($tRect, 2, $iTop + 2);4)
                    _WinAPI_DrawText($hDC, $sTextPrefix & $sText, $tRect, $DT_LEFT)
                    _WinAPI_SetTextColor($hDC, $clrForeground)
                    _WinAPI_SetBkColor($hDC, $clrBackground)
                    _WinAPI_SetBkMode($hDC, $TRANSPARENT)
                EndIf
                $bFoundTitle=False
        EndSwitch
    EndIf

    $tRect = 0

    Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_DRAWITEM

Func _WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg
    Local $hWndFrom, $iIDFrom, $iCode, $hWndCombo
    If Not IsHWnd($ComboBox) Then $hWndCombo = GUICtrlGetHandle($ComboBox)
    $hWndFrom = $ilParam
    $iIDFrom = BitAND($iwParam, 0xFFFF) ; Low Word
    $iCode = BitShift($iwParam, 16) ; Hi Word

    Switch $hWndFrom
        Case $ComboBox, $hWndCombo
            Switch $iCode
                Case $CBN_CLOSEUP ; Sent when the list box of a combo box has been closed
                    _DebugPrint("$CBN_CLOSEUP" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
                    ; no return value
                Case $CBN_DBLCLK ; Sent when the user double-clicks a string in the list box of a combo box
                    _DebugPrint("$CBN_DBLCLK" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
                    ; no return value
                Case $CBN_DROPDOWN ; Sent when the list box of a combo box is about to be made visible
                    _DebugPrint("$CBN_DROPDOWN" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
                    ; no return value
                Case $CBN_EDITUPDATE ; Sent when the edit control portion of a combo box is about to display altered text
                    _DebugPrint("$CBN_EDITUPDATE" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
                    ; no return value
                Case $CBN_ERRSPACE ; Sent when a combo box cannot allocate enough memory to meet a specific request
                    _DebugPrint("$CBN_ERRSPACE" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
                    ; no return value
                Case $CBN_KILLFOCUS ; Sent when a combo box loses the keyboard focus
                    _DebugPrint("$CBN_KILLFOCUS" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
                    ; no return value
                Case $CBN_SELCHANGE ; Sent when the user changes the current selection in the list box of a combo box
                    _DebugPrint("$CBN_SELCHANGE" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
                    ; Select Item
                    ;_GUICtrlComboBox_SetCurSel($ComboBox, _GUICtrlComboBox_GetCurSel($ComboBox))

                    ; no return value
                Case $CBN_SELENDCANCEL ; Sent when the user selects an item, but then selects another control or closes the dialog box
                    _DebugPrint("$CBN_SELENDCANCEL" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
                    ; no return value
                Case $CBN_SELENDOK ; Sent when the user selects a list item, or selects an item and then closes the list
                    _DebugPrint("$CBN_SELENDOK" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
                    ; no return value
                Case $CBN_SETFOCUS ; Sent when a combo box receives the keyboard focus
                    _DebugPrint("$CBN_SETFOCUS" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
                    ; no return value
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_COMMAND

Func _DebugPrint($s_text, $line = @ScriptLineNumber)
    ConsoleWrite( _
            "!===========================================================" & @LF & _
            "+======================================================" & @LF & _
            "-->Line(" & StringFormat("%04d", $line) & "):" & @TAB & $s_text & @LF & _
            "+======================================================" & @LF)
EndFunc   ;==>_DebugPrint

 

Link to comment
Share on other sites

  • Moderators

ahmet,

Very nice! That code is what I had been playing around with yesterday afternoon without success - good on you to have got it working. Now I just have t understand how you did it!

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Yeah i have see it and make it some "stripped" like this:

#include <GUIComboBox.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

;~ Global Const $ODT_MENU = 1
;~ Global Const $ODT_LISTBOX = 2
Global Const $ODT_COMBOBOX = 3
;~ Global Const $ODT_BUTTON = 4
;~ Global Const $ODT_STATIC = 5
;~ Global Const $ODT_HEADER = 100
;~ Global Const $ODT_TAB = 101
;~ Global Const $ODT_LISTVIEW = 102

Global Const $ODA_DRAWENTIRE = 1
Global Const $ODA_SELECT = 2
Global Const $ODA_FOCUS = 4
Global Const $ODS_SELECTED = 1
;~ Global Const $ODS_GRAYED = 2
;~ Global Const $ODS_DISABLED = 4
;~ Global Const $ODS_CHECKED = 8
;~ Global Const $ODS_FOCUS = 16
;~ Global Const $ODS_DEFAULT = 32
;~ Global Const $ODS_HOTLIGHT = 64
;~ Global Const $ODS_INACTIVE = 128
;~ Global Const $ODS_NOACCEL = 256
;~ Global Const $ODS_NOFOCUSRECT = 512
;~ Global Const $ODS_COMBOBOXEDIT = 4096

Global Const $clrWindowText = _WinAPI_GetSysColor($COLOR_WINDOWTEXT)
Global Const $clrHighlightText = _WinAPI_GetSysColor($COLOR_HIGHLIGHTTEXT)
Global Const $clrHightlight = _WinAPI_GetSysColor($COLOR_HIGHLIGHT)
Global Const $clrWindow = _WinAPI_GetSysColor($COLOR_WINDOW)

Global Const $tagDRAWITEMSTRUCT = _
        'uint CtlType;' & _
        'uint CtlID;' & _
        'uint itemID;' & _
        'uint itemAction;' & _
        'uint itemState;' & _
        'hwnd hwndItem;' & _
        'hwnd hDC;' & _
        $tagRECT & _
        ';ulong_ptr itemData;'

Global $hGUI, $ComboBox

$hGUI = GUICreate('Test', 200, 200)
$ComboBox = GUICtrlCreateCombo('', 0, 0, 200, 200, BitOR($WS_CHILD, $CBS_OWNERDRAWFIXED, $CBS_HASSTRINGS, $CBS_DROPDOWNLIST))
GUICtrlSetData($ComboBox, "Header 1|   Item 1|   Item 2|Header 2|   Item 3|   Item 4")

GUIRegisterMsg($WM_DRAWITEM, 'WM_DRAWITEM')
GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

GUIDelete()
Exit

Func WM_DRAWITEM($hWnd, $iMsg, $iwParam, $ilParam)
    Local $tDIS = DllStructCreate($tagDRAWITEMSTRUCT, $ilParam)
    Local $iCtlType, $iCtlID, $iItemID, $iItemAction, $iItemState
    Local $clrForeground, $clrBackground
    Local $hWndItem, $hDC
;~  Local $tRect
    Local $sText

    $iCtlType = DllStructGetData($tDIS, 'CtlType')
    $iCtlID = DllStructGetData($tDIS, 'CtlID')
    $iItemID = DllStructGetData($tDIS, 'itemID')
    $iItemAction = DllStructGetData($tDIS, 'itemAction')
    $iItemState = DllStructGetData($tDIS, 'itemState')
    $hWndItem = DllStructGetData($tDIS, 'hwndItem')
    $hDC = DllStructGetData($tDIS, 'hDC')
    $tRect = DllStructCreate($tagRECT)

    If $iCtlType = $ODT_COMBOBOX And $iCtlID = $ComboBox Then
        Switch $iItemAction
            Case $ODA_DRAWENTIRE, $ODA_SELECT, $ODA_FOCUS
                For $i = 1 To 4
                    DllStructSetData($tRect, $i, DllStructGetData($tDIS, $i + 7))
                Next

                _GUICtrlComboBox_GetLBText($hWndItem, $iItemID, $sText)

                If BitAND($iItemState, $ODS_SELECTED) Then
                    $clrBackground = _WinAPI_SetBkColor($hDC, $clrHightlight)
                    $clrForeground = _WinAPI_SetTextColor($hDC, $clrHighlightText)
                Else
                    $clrBackground = _WinAPI_SetBkColor($hDC, $clrWindow)
                EndIf

                If $sText <> "" And StringLeft($sText, 3) <> "   " Then
                    $clrForeground = _WinAPI_SetTextColor($hDC, 0x0000FF);red
                    _WinAPI_SetBkMode($hDC, $TRANSPARENT)
                EndIf
                _WinAPI_DrawText($hDC, $sText, $tRect, $DT_LEFT)
                _WinAPI_SetTextColor($hDC, $clrForeground)
                _WinAPI_SetBkColor($hDC, $clrBackground)
                _WinAPI_SetBkMode($hDC, $OPAQUE)
        EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM

But still having problems like header can be select, or "normal" items have space when you select it and other issue. All exaplained in this document:

http://www.codeproject.com/Articles/489189/Group-Combo-Box

 

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

Melba23,

I only changed part that draws separtaor with code for writing text :)

Terenz,

Following code does not draw spaces at editbox of combo when selected, but it has a side effect at dropdown list.

Switch $iItemAction
            Case $ODA_DRAWENTIRE
                For $i = 1 To 4
                    DllStructSetData($tRect, $i, DllStructGetData($tDIS, $i + 7))
                Next

                _GUICtrlComboBox_GetLBText($hWndItem, $iItemID, $sText)
                Local $iTop = DllStructGetData($tRect, 2)
                ; search array of titles
                For $i=0 To UBound($aTitles)-1
                    If $sText=$aTitles[$i] Then
                        $bFoundTitle=True
                        If Not BitAND($iItemState, $ODS_COMBOBOXEDIT) Then
                        DllStructSetData($tRect, 2, $iTop + 1)
                         _WinAPI_SelectObject($hDC, $g_hFont)
                         _WinAPI_DrawText($hDC,$sText,$tRect,$DT_LEFT) ; if item's text it found then draw it with desired font
                         ExitLoop
                        EndIf
                    EndIf
                Next

                If $sText <> "" And Not $bFoundTitle  Then
                    If BitAND($iItemState, $ODS_SELECTED) Then
                        $clrForeground = _WinAPI_SetTextColor($hDC, $clrHighlightText)
                        $clrBackground = _WinAPI_SetBkColor($hDC, $clrHighlight)
                        _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), $hBrushSel)
                        DllStructSetData($tRect, 2, $iTop + 2);4)
                        _WinAPI_SelectObject($hDC,$hFont2)
                        _WinAPI_DrawText($hDC, $sText, $tRect, $DT_LEFT)
                        _WinAPI_SetTextColor($hDC, $clrForeground)
                        _WinAPI_SetBkColor($hDC, $clrBackground)
                        _WinAPI_SetBkMode($hDC, $TRANSPARENT)
                    ElseIf BitAND($iItemState, $ODS_COMBOBOXEDIT) Then ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< New
                        ConsoleWrite("ODS_COMBOBOXEDIT" & @CRLF)
                        $clrForeground = _WinAPI_SetTextColor($hDC, $clrWindowText)
                        $clrBackground = _WinAPI_SetBkColor($hDC, $clrWindow)
                        _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), $hBrushNorm)
                        DllStructSetData($tRect, 2, $iTop + 2);4)
                        _WinAPI_DrawText($hDC,$sText, $tRect, $DT_LEFT)
                        _WinAPI_SetTextColor($hDC, $clrForeground)
                        _WinAPI_SetBkColor($hDC, $clrBackground)
                        _WinAPI_SetBkMode($hDC, $TRANSPARENT) ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                    Else
                        $clrForeground = _WinAPI_SetTextColor($hDC, $clrWindowText)
                        $clrBackground = _WinAPI_SetBkColor($hDC, $clrWindow)
                        _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), $hBrushNorm)
                        DllStructSetData($tRect, 2, $iTop + 2);4)
                        _WinAPI_SelectObject($hDC,$hFont2)
                        _WinAPI_DrawText($hDC, $sTextPrefix & $sText, $tRect, $DT_LEFT)
                        _WinAPI_SetTextColor($hDC, $clrForeground)
                        _WinAPI_SetBkColor($hDC, $clrBackground)
                        _WinAPI_SetBkMode($hDC, $TRANSPARENT)
                    EndIf
                EndIf
                $bFoundTitle=False

 

Edited by ahmet
Link to comment
Share on other sites

Another idea, using a TreeView control instead of a combo (sorry, not really clean) :

#include <GUIConstantsEx.au3>
#include <GuiTreeView.au3>
#include <MsgBoxConstants.au3>
#include <WindowsConstants.au3>
#include <ComboConstants.au3>
#include <EditConstants.au3>
#Include <ButtonConstants.au3>


Local $iStyle = BitOR($TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS)

Local $hMain = GUICreate("TreeView Set Bold", 500, 150)
Local $input = GUICtrlCreateInput("", 10, 10, 400, 20, $ES_READONLY)
Local $select = GUICtrlCreateButton(ChrW(0x25BC), 410, 10, 30, 20)
GUICtrlSetFont(-1, Default, Default, Default, "Arial")

Local $showTreeView = 0
Local $sLastSel

GUISetState(@SW_SHOW)


GUIRegisterMsg ($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg ($WM_COMMAND, "WM_COMMAND")


Local $listGUI = GUICreate("comboList", 400, 200, 10, 30, $WS_POPUP, $WS_EX_MDICHILD, $hMain)
Local $idTreeView = GUICtrlCreateTreeView(0, 0, 400, 200, $iStyle, $WS_EX_CLIENTEDGE)

Local $header = 0
Local $item = 0
_GUICtrlTreeView_BeginUpdate($idTreeView)
For $x = 0 To 3
    $header += 1
    $parent = _GUICtrlTreeView_Add($idTreeView, 0, "Header" &  $header)
    _GUICtrlTreeView_SetBold($idTreeView, $parent)
    
        
    For $y = 1 To 5
        $item += 1
        _GUICtrlTreeView_AddChild($idTreeView, $parent, "Item " & $item)
    Next
    _GUICtrlTreeView_Expand ( $idTreeView)
Next
_GUICtrlTreeView_EndUpdate($idTreeView)



While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $select
            If $showTreeView Then
                GUISetState(@SW_HIDE, $listGUI)
                $showTreeView = 0
            Else
                GUISetState(@SW_SHOW, $listGUI)
                $sLastSel = _GUICtrlTreeView_GetSelection($idTreeView)
                WinActivate($listGUI)
                $showTreeView = 1
            EndIf
    EndSwitch
    Sleep(10)
WEnd


Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg
    Local $hWndFrom, $iIDFrom, $iCode, $hWndListBox
    $hWndFrom = $lParam
    $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word
    $iCode = BitShift($wParam, 16) ; Hi Word
    
    Switch $iIDFrom
        Case $input
            Switch $iCode
                Case $EN_SETFOCUS
                    GUICtrlSendMsg($select, $BM_CLICK, 0, 0)
            EndSwitch
    EndSwitch
EndFunc



Func WM_NOTIFY($hWnd, $imsg, $iwParam, $ilParam)
    Local $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)

    Local $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    Local $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    Local $iCode = DllStructGetData($tNMHDR, "Code")
    
    Switch $iIDFrom
        Case $idTreeView
            Switch $iCode
                Case -8
                    $showTreeView = 0
                    GUISetState(@SW_HIDE, $listGUI)
                Case $TVN_SELCHANGEDW
                    If $showTreeView = 0 Then
                        $showTreeView = 1
                    Else
                        $sel = _GUICtrlTreeView_GetSelection($idTreeView)
                        If $sel <> 0 AND $sel <> $sLastSel Then
                            $sText = _GUICtrlTreeView_GetText($idTreeView, $sel)
                            GUICtrlSetData($input, "")
                            GUICtrlSetData($input, $sText, $sText)
                            $sLastSel = $sel
                            Sleep(50)
                            GUISetState(@SW_HIDE, $listGUI)
                            $showTreeView = 0
                        EndIf
                    EndIf
            EndSwitch
            
    EndSwitch
EndFunc

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...