Jump to content

ComboBox inside ListView Item


rajeshwaran
 Share

Recommended Posts

Hi all,

I have added a ComboBox inside a listview item, when you do single click on subitem, the combobox appears, but I can not able to operate anything on that combobox with mouse (with keyboard navigation is possible)

Here is the code

#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#Include <GuiComboBox.au3>


;--- Global Variables --

;-- Window properties --
Global  $ID_Window
Global  $Window_Title = "Generator"
Global  $Window_Width = 1200
Global  $Window_Height = 800

;-- ListView 1 properties --
Global  $ID_InputDevice_Gen_Config_ListView
Global  $Handle_InputDevice_Gen_Config_ListView

;-- ComboBox on ListView properties --
Global  $ID_ComboBox_On_ListView

;--- Global Variables --
Global  $Array_InDev_Genrl_Config_XYWH [4] = _
                    [                   _ 
                        10,             _ ;-- Left --
                        10,             _ ;-- Top --
                        700,            _ ;-- Width --
                        400             _ ;-- Height --
                    ]

Global  $Array_InDev_Genrl_Config_Columns [6] = _
                    [                           _ 
                        "In. Device Name",      _
                        "Input Fs",             _
                        "Master Clck",          _
                        "Decoder Type",         _
                        "Dual Mono Mode",       _
                        "Down Mix Mode"         _
                    ]

Global  $Array_InDev_Genrl_Config_Items [18][6] =                                           _
                    [                                                                       _
                        [   "std0_01",      "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "std1_01",      "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "std2_23",      "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "std3_23",      "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "capa_01",      "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "capb_01",      "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "capc_01",      "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "capa_23",      "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "capb_23",      "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "capc_23",      "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "hdmi_01",      "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "hdmi_23",      "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "esf_01",       "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "esf_23",       "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "pcmf_01",      "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "pcmf_23",      "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "pcm_mem_01",   "48k",  "amclki0",  "ac3",  "and",  "mode0" ],  _
                        [   "pcm_mem_23",   "48k",  "amclki0",  "ac3",  "and",  "mode0" ]   _
                    ]
                

;-- Start Main Function --
Main()

Func Main()
    
    ;-- Create a window --
    $ID_Window = GUICreate($Window_Title, $Window_Width, $Window_Height) 
    
    ;-- Create ListView for input device general configuration --
    Create_ListView(    $ID_Window,                                 _
                        $ID_InputDevice_Gen_Config_ListView,        _
                        $Handle_InputDevice_Gen_Config_ListView,    _
                        $Array_InDev_Genrl_Config_XYWH,             _
                        $Array_InDev_Genrl_Config_Columns,          _
                        $Array_InDev_Genrl_Config_Items)

    ;-- Create Combobox to display on ListView --
    $ID_ComboBox_On_ListView = _GUICtrlComboBox_Create($ID_Window, "A|B|C|D", 0, 0, $CBS_DROPDOWNLIST)
        
    ;-- Hide the combobox --
    _WinAPI_ShowWindow($ID_ComboBox_On_ListView, @SW_HIDE)
    

    ;-- Register message for ListView notifications --
    GUIRegisterMsg($WM_NOTIFY, "ListView_EventHandler")

    GUISetState()

    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE
                Exit
        EndSwitch
    WEnd
    
EndFunc

;-- Function to create a listview and assign items specified in the input array --
Func Create_ListView( ByRef $H_Window, ByRef $ID_ListView, ByRef $Handle_ListView, ByRef $Array_XYWH, ByRef $Array_Columns, ByRef $Array_Items)
    
    Local   $Array_Element
    Local   $ListView_Width = 0
    Local   $Loop = 0

    ;-- Create ListView --
    $ID_ListView = GUICtrlCreateListView(   "",                 _
                                            $Array_XYWH[0],     _
                                            $Array_XYWH[1],     _
                                            $Array_XYWH[2],     _
                                            $Array_XYWH[3],     _
                                            $LVS_SINGLESEL,         _
                                            BitOR($LVS_EX_DOUBLEBUFFER, $LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES) ) 
                                            
    $Handle_ListView = GUICtrlGetHandle($ID_ListView)
    
    ;-- Set ListView Font Height --
    GUICtrlSetFont($ID_ListView, 12)
    
    ;-- Add columns for ListView --
    For $Array_Element In $Array_Columns
        _GUICtrlListView_AddColumn($Handle_ListView, $Array_Element)
    Next
    
    ;-- Add items for ListView --
    _GUICtrlListView_AddArray($Handle_ListView, $Array_Items)

    ;-- Determine the column width --
    For $Loop = 0 To UBound($Array_Columns) Step 1
        Determine_ColumnWidth($Handle_ListView, $Loop)
    Next
    
    ;-- Center justify all columns --
    For $Loop = 0 To UBound($Array_Columns) Step 1
        _GUICtrlListView_JustifyColumn($Handle_ListView, $Loop + 1, 2)
    Next

EndFunc


Func Determine_ColumnWidth($Handle_ListView, $Column_Index = 0)
    
    Local $TotalNumberOfColumns = 0
    Local $AutoWidth_Of_DataItems = 0
    Local $AutoWidth_Of_Columns = 0
    
    ;-- Get column count
    Local $TotalNumberOfColumns = _GUICtrlListView_GetColumnCount($Handle_ListView)
    
    ;-- If column index passed by user is greater than total number of columns then do needful--
    If $Column_Index > $TotalNumberOfColumns Then $Column_Index = $TotalNumberOfColumns

    ;-- Set auto width for data items --
    _GUICtrlListView_SetColumnWidth($Handle_ListView, $Column_Index, $LVSCW_AUTOSIZE)

    ;-- Get auto width assigned by AutoIt (for later comparision) --
    $AutoWidth_Of_DataItems = _GUICtrlListView_GetColumn($Handle_ListView, $Column_Index)
    
    ;-- Set auto width for Columns Headers --
    _GUICtrlListView_SetColumnWidth($Handle_ListView, $Column_Index, $LVSCW_AUTOSIZE_USEHEADER)
    
    ;-- Get auto width assigned by AutoIt (for later comparision) --
    $AutoWidth_Of_Columns = _GUICtrlListView_GetColumn($Handle_ListView, $Column_Index)

    ;-- Compare and apply the suitable auto width to that column --
    If $AutoWidth_Of_DataItems[4] < $AutoWidth_Of_Columns[4] Then _GUICtrlListView_SetColumnWidth($Handle_ListView, $Column_Index, $LVSCW_AUTOSIZE_USEHEADER)
    If $AutoWidth_Of_DataItems[4] > $AutoWidth_Of_Columns[4] Then _GUICtrlListView_SetColumnWidth($Handle_ListView, $Column_Index, $LVSCW_AUTOSIZE)
        
EndFunc


Func ListView_EventHandler($hWnd, $Msg, $wParam, $lParam)
    
    Local   $tNotificationMessage 
    Local   $Handle_Control 
    Local   $Event_Occured
    
    ;-- From $lParam form the system structure $tagNMHDR --
    $tNotification_Message = DllStructCreate($tagNMHDR, $lParam)
    
    ;-- From the above structure formed, retrive the handle of the control and event occured --
    $Handle_Control = DllStructGetData($tNotification_Message, "hWndFrom")
    $Event_Occured = DllStructGetData($tNotification_Message, "Code")
    
    ;-- Classification of controls --
    Switch $Handle_Control
        
        ;-- Check notification for ListView control (General config for input device) --
        Case $Handle_InputDevice_Gen_Config_ListView
        
            ;-- Classification of events --
            Switch $Event_Occured
                
                ;-- Check for mouse single click event --
                Case $NM_CLICK
                
                    Local   $tLV_NotificationMessage
                    Local   $Hit_Item_Index = 0
                    Local   $Hit_SubItem_Index = 0  
                    Local   $Rect_SubItem
                    
                    ;-- From $lParam form the system structure $tagNMITEMACTIVATE --
                    $tLV_NotificationMessage = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                    
                    ;-- From the above structure formed, retrive the item & subitem index  --
                    $Hit_Item_Index = DllStructGetData($tLV_NotificationMessage, "Index")
                    $Hit_SubItem_Index = DllStructGetData($tLV_NotificationMessage, "SubItem")
                    
                    $Rect_SubItem = _GUICtrlListView_GetSubItemRect($Handle_InputDevice_Gen_Config_ListView, $Hit_Item_Index, $Hit_SubItem_Index)
                    
                    _WinAPI_MoveWindow($ID_ComboBox_On_ListView, $Array_InDev_Genrl_Config_XYWH[0] + $Rect_SubItem[0], $Array_InDev_Genrl_Config_XYWH[1] + $Rect_SubItem[1], $Rect_SubItem[2] - $Rect_SubItem[0], $Rect_SubItem[3] - $Rect_SubItem[1])      
                    _WinAPI_ShowWindow($ID_ComboBox_On_ListView, @SW_SHOW)
                    _WinAPI_SetFocus($ID_ComboBox_On_ListView)
                    
                    ConsoleWrite("X Pos = " & $Rect_SubItem[0] & " Y Pos = " & $Rect_SubItem[1] & " Width = " & $Rect_SubItem[2] - $Rect_SubItem[0] & " Height = " &  $Rect_SubItem[3] - $Rect_SubItem[1] & @LF)
                        
            EndSwitch ;-- End switch for Classification of events --
    
    EndSwitch ;-- End switch for Classification of controls --
    
    Return $GUI_RUNDEFMSG
EndFunc

Please help me to solve this problem.

Link to comment
Share on other sites

  • Moderators

rajeshwaran,

Based on some code I posted yesterday, this shows how I would go about putting a combo into a ListView: ;)

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <Misc.au3>

Opt("TrayIconDebug", 1)

; We use ESC to exit the temporary Combo
Opt("GUICloseOnESC", 0)

; Set flag to indicate double click in ListView
Global $fDblClk = False
; Declare global variables
Global $aLV_Click_Info, $hTmp_Combo = 0

; Open DLL for _IsPressed
$dll = DllOpen("user32.dll")

; Create GUI
$hGUI = GUICreate("Test", 400, 250)

$hListView = _GUICtrlListView_Create($hGUI, "Col 0|Col 1|Col 2", 10, 10, 242, 200)
_GUICtrlListView_AddItem($hListView, "Item 00",0)
_GUICtrlListView_AddSubItem($hListView, 0, "Item 01", 1)
_GUICtrlListView_AddSubItem($hListView, 0, "Item 02", 2)
_GUICtrlListView_AddItem($hListView, "Item 10",1)
_GUICtrlListView_AddItem($hListView, "Item 20",2)
_GUICtrlListView_AddItem($hListView, "Item 30",3)

GUISetState()

; Look for double clicks
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            DllClose($dll)
            Exit
    EndSwitch

    ; If a temporary combo exists
    If $hTmp_Combo <> 0 Then
        ; If ENTER pressed
        If _IsPressed("0D", $dll) Then
            ; Set label to edit content
            $sText = GUICtrlRead($hTmp_Combo)
            _GUICtrlListView_SetItemText($hListView, $aLV_Click_Info[0], $sText, $aLV_Click_Info[1])
            ; Delete temporary combo
            GUICtrlDelete($hTmp_combo)
            $hTmp_Combo = 0
            GUICtrlSetState($hListView, $GUI_ENABLE)
        EndIf
        ; If ESC pressed
        If _IsPressed("1B", $dll) Then
            ; Delete temporary combo
            GUICtrlDelete($hTmp_Combo)
            $hTmp_Combo = 0
            GUICtrlSetState($hListView, $GUI_ENABLE)
        EndIf
    EndIf

    ; If an item was double clicked
    If $fDblClk Then
        $fDblClk = False
        ; Delete an existing temporary combo
        GUICtrlDelete($hTmp_Combo)
        ; Get label position
        Switch $aLV_Click_Info[1]
            Case 0 ; On Item
                $aLV_Rect_Info = _GUICtrlListView_GetItemRect($hListView, $aLV_Click_Info[0], 2)
            Case Else ; On SubItem
                $aLV_Rect_Info = _GUICtrlListView_GetSubItemRect($hListView, $aLV_Click_Info[0], $aLV_Click_Info[1])
        EndSwitch
        ; Create temporary combo
        $hTmp_Combo = GUICtrlCreateCombo("", $aLV_Rect_Info[0] + 10, $aLV_Rect_Info[1] + 10, 100, $aLV_Rect_Info[3] - $aLV_Rect_Info[1])
        GUICtrlSetData($hTmp_Combo, "Tom|Dick|Harry")
        GUICtrlSetState($hListView, $GUI_DISABLE)
        GUICtrlSetState($hTmp_Combo, BitOR($GUI_FOCUS, $GUI_ONTOP))

    EndIf

WEnd

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

    ; If a combo exists, return immediately
    If $hTmp_Combo <> 0 Then Return $GUI_RUNDEFMSG

    Local $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    If HWnd(DllStructGetData($tNMHDR, "hWndFrom")) = $hListView And DllStructGetData($tNMHDR, "Code") = $NM_DBLCLK Then
        $aLV_Click_Info = _GUICtrlListView_SubItemHitTest($hListView)
        ; As long as the click was on an item or subitem
        If $aLV_Click_Info[0] <> -1 Then $fDblClk = True
    EndIf
    Return $GUI_RUNDEFMSG

EndFunc

Losts of iimprovements could be made - like autoinsertion of the selected value using _GUICtrlComboBox_GetDroppedState for example - but I hope it will be of use. Please ask if you have any questions. :)

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

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...