Jump to content

[SOLVED]Two or more listviews with double click


Recommended Posts

I've created a gui with two (or more) listviews based on a function (so that I can easiely expand the number of listviews).

Now I would like to be able to achieve two things:

1. Perform some action based on a double click in the listview (lets say, get the information from the double clicked item in the listview)

2. Be able to select more items in both listviews and be able to retreive this information.

I am stuck in both thins and would appreciate help on both.

Here is the (simplified) version of the script I have created so far.

It might look a bit over done to use a function for the creation of the listview controls / items, but as stated before the real script will have a variable number of listviews, which will be based on a SQL query.

#include <array.au3>
#include <Constants.au3>
#include <EditConstants.au3>
#include <GuiButton.au3>
#Include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include <GuiEdit.au3>
#include <WindowsConstants.au3>
#Include <WinAPI.au3>


Global $lView,$iRows,$iColumns,$iLvWidth,$iLvLeft,$iLvTop,$iLvWidth,$iLvHeight
Global $iExListViewStyle = BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES), $adata[100][120]


        $hGUI = GUICreate("Test", 400, 376)
        $bTest1 = GUICtrlCreateButton("test",1,348,100,20)

        $iLvLeft = 2
        $iLvTop = 2
        $iLvWidth = 393
        $iLvHeight = 150

        _ListviewCreate($lView,$iLvLeft,$iLvTop,$iLvWidth,$iLvHeight)
        $lvTest = $lView

        $iLvLeft = 2
        $iLvTop = 152
        $iLvWidth = 393
        $iLvHeight = 150

        _ListviewCreate($lView,$iLvLeft,$iLvTop,$iLvWidth,$iLvHeight)
        $lvTest1 = $lView

        $iDblClk = 0

        GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

        GUISetState(@SW_SHOW)

            While 1
                $nMsg = GUIGetMsg()

                If $iDblClk = 1 then
                     msgbox(0,"","Perform action based on double click in listview")
                    $iDblClk = 0
                EndIf

                Switch $nMsg

                    Case $GUI_EVENT_CLOSE ;CLOSE

                        GUIDelete($hGUI)

                        Exitloop

                    Case $bTest1

                        MsgBox(0,"","Get the values from the selected item(s) from one or more listviews...")

                EndSwitch

            WEnd






;=========================================================Functions========================================================

Func _ListviewCreate($lView,$iLvLeft,$iLvTop,$iLvWidth,$iLvHeight) ;Functie om listview te maken

    $iRows = 10
    $iCols = 4

    For $r = 0 to 11

        For $col = 0 to 4

            $aData[$r][$col] = "Row " & $r & " Col " & $col

        Next

    Next

    $iLvCol = ubound($adata,2) ;Get the number of columns in query
    $sLvCol = ""
    $sLine = ""
    dim $aitem[$iRows]
    For $c = 1 to $iLvCol ;Determine the headers of the query

        if  $c < $iLvCol Then
            $sLvCol = $sLvCol & $aData[0][$c-1] & "|"
        Else
            $sLvCol = $sLvCol  & $aData[0][$c-1]
        EndIf

    Next

    ;Create listview
    $lView = GUICtrlCreateListView($sLvCol, $iLvLeft, $iLvTop, $iLvWidth, $iLvHeight,$LVS_ICON,BitOR($LVS_SORTDESCENDING,$LVS_EX_GRIDLINES))
    GUICtrlSetBkColor($lView, $GUI_BKCOLOR_LV_ALTERNATE)
    _GUICtrlListView_SetExtendedListViewStyle($lView, $iExListViewStyle)

    ;Populate listview

        _GUICtrlListView_BeginUpdate($lView)
        _GUICtrlListView_DeleteAllItems($lView)

        _GUICtrlListView_RegisterSortCallBack($lView)


            For $r = 1 to $iRows ;Every line
                For $k = 1 to $iLvCol ;Every Column
                    if  $k < $iLvCol Then
                        $sLine = $sLine & $aData[$r][$k-1] & "|"
                    Else
                        $sLine = $sLine  & $aData[$r][$k-1]
                    EndIf
                Next
                $aItem[$r - 1]= GUICtrlCreateListViewItem($sLine, $lView ) ;Add Item to listview
                GUICtrlSetBkColor(-1, 0xD0DEC7)
                $sLine = ""
            Next
        _GUICtrlListView_endUpdate($lView)

        ;Change column width of last column
        $iKolW = 0

        For $k = 0 to $iLvCol -1
            $iKolW = _GUICtrlListView_GetColumnWidth($lView, $k) +  $iKolW
        Next

        _GUICtrlListView_SetColumnWidth($lView, $iLvCol , $iLvWidth - $iKolW  )



EndFunc ;_ListviewCreate



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

    Local $hWndFrom, $iCode, $tNMHDR, $hWndListView

    $hWndListView = $lView
    If Not IsHWnd($hWndListView) Then $hWndListView = GUICtrlGetHandle($hWndListView)

        $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hWndListView
            msgbox(0,"",$hWndListView)

            Switch $iCode

                Case $NM_DBLCLK  ; Sent by a list-view control when the user double-clicks an item with the left mouse button

                    $iDblClk = 1


            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Thanks in advance for the help!

Edited by Montfrooij
Link to comment
Share on other sites

  • Moderators

Montfrooij,

This should do what you want. :graduated:

Note that the items are indexed from 0 - you have Item 0 as the headers, so you might have to make suitable adjustments to the returns: :D

#include <array.au3>
#include <Constants.au3>
#include <EditConstants.au3>
#include <GuiButton.au3>
#include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include <GuiEdit.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

#include <Array.au3> ; For the _ArrayDisplay to show the selected items

Global $lView, $iRows, $iColumns, $iLvWidth, $iLvLeft, $iLvTop, $iLvWidth, $iLvHeight
Global $iExListViewStyle = BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES), $adata[100][120]

; Create array to hold listview handles - will be resized within the creation function
Global $ahListView[1] = [0]

$hGUI = GUICreate("Test", 400, 376)
$bTest1 = GUICtrlCreateButton("test", 1, 348, 100, 20)

$iLvLeft = 2
$iLvTop = 2
$iLvWidth = 393
$iLvHeight = 150

; Removed first parameter from function - added storage code to function
_ListviewCreate($iLvLeft, $iLvTop, $iLvWidth, $iLvHeight)

$iLvLeft = 2
$iLvTop = 152
$iLvWidth = 393
$iLvHeight = 150

_ListviewCreate($iLvLeft, $iLvTop, $iLvWidth, $iLvHeight)

$iDblClk = 0

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()

    Switch $nMsg

        Case $GUI_EVENT_CLOSE ;CLOSE
            GUIDelete($hGUI)
            ExitLoop

        Case $bTest1
            ; Create array to hold data - ony needed for demo
            Global $aIndices[3][2]
            ; Loop through the listviews
            For $i = 1 To $ahListView[0]
                ; Store listview index and selected elements
                $aIndices[$i][0] = $i
                $aIndices[$i][1] = _GUICtrlListView_GetSelectedIndices($ahListView[$i])

            Next
            ; Disply for demo only
            _ArrayDisplay($aIndices, "Selected items per ListView")

    EndSwitch

    If $iDblClk Then
        ; $iDblClick now holds the index of the Listview so you can interrogate it at will
        MsgBox(0, "", "Perform action based on double click in listview " & $iDblClk)
        $iDblClk = 0
    EndIf

WEnd

;=========================================================Functions========================================================

Func _ListviewCreate($iLvLeft, $iLvTop, $iLvWidth, $iLvHeight) ;Functie om listview te maken

    $iRows = 10
    $iCols = 4

    For $r = 0 To 11

        For $col = 0 To 4

            $adata[$r][$col] = "Row " & $r & " Col " & $col

        Next

    Next

    $iLvCol = UBound($adata, 2) ;Get the number of columns in query
    $sLvCol = ""
    $sLine = ""
    Dim $aitem[$iRows]
    For $c = 1 To $iLvCol ;Determine the headers of the query

        If $c < $iLvCol Then
            $sLvCol = $sLvCol & $adata[0][$c - 1] & "|"
        Else
            $sLvCol = $sLvCol & $adata[0][$c - 1]
        EndIf

    Next

    ;Create listview
    $lView = GUICtrlCreateListView($sLvCol, $iLvLeft, $iLvTop, $iLvWidth, $iLvHeight, $LVS_ICON, BitOR($LVS_SORTDESCENDING, $LVS_EX_GRIDLINES))
    GUICtrlSetBkColor($lView, $GUI_BKCOLOR_LV_ALTERNATE)
    _GUICtrlListView_SetExtendedListViewStyle($lView, $iExListViewStyle)

    ;Populate listview

    _GUICtrlListView_BeginUpdate($lView)
    _GUICtrlListView_DeleteAllItems($lView)

    _GUICtrlListView_RegisterSortCallBack($lView)

    For $r = 1 To $iRows ;Every line
        For $k = 1 To $iLvCol ;Every Column
            If $k < $iLvCol Then
                $sLine = $sLine & $adata[$r][$k - 1] & "|"
            Else
                $sLine = $sLine & $adata[$r][$k - 1]
            EndIf
        Next
        $aitem[$r - 1] = GUICtrlCreateListViewItem($sLine, $lView) ;Add Item to listview
        GUICtrlSetBkColor(-1, 0xD0DEC7)
        $sLine = ""
    Next
    _GUICtrlListView_EndUpdate($lView)

    ;Change column width of last column
    $iKolW = 0

    For $k = 0 To $iLvCol - 1
        $iKolW = _GUICtrlListView_GetColumnWidth($lView, $k) + $iKolW
    Next

    _GUICtrlListView_SetColumnWidth($lView, $iLvCol, $iLvWidth - $iKolW)

    ; Increase count of ListViews
    $ahListView[0] += 1
    ;Increase size of array
    ReDim $ahListView[$ahListView[0] + 1]
    ; Store the handle in the array
    $ahListView[$ahListView[0]] = GUICtrlGetHandle($lView)

EndFunc   ;==>_ListviewCreate

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

    Local $hWndFrom, $iCode, $tNMHDR, $hWndListView

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")
    For $i = 1 To $ahListView[0]
        If $hWndFrom = $ahListView[$i] Then
            Switch $iCode

                Case $NM_DBLCLK ; Sent by a list-view control when the user double-clicks an item with the left mouse button
                    ; Set the index of the ListView in the storage array
                    $iDblClk = $i
                    ; No point in looking any further!
                    ExitLoop

            EndSwitch
        EndIf
    Next
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Please ask if the comments are not clear enough to explain what is going on. :(

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

M23, thanks for the quick reply.

The first quest seems solved :(

I'll have to take some time to understand it and to implement this in my script, but it seems to work just fine!

The second one seems to need a bit more work.

On my PC it is not possible to select one or more items from both listviews.

It seems like the click in the second listview (WITH CTRL pressed) makes the selection from listview 1 jump to the second listview. :graduated:

The _ArrayDisplay($aIndices, "Selected items per ListView") that you've added seems to give the right selection though, so it seems to be just a 'visual' problem.

Nevertheless, this might confuse the users, since the selection is not visible in the listviews.

The users might be selecting a lot of items from many listviews, so this is probably unwanted...

Could you have a look at this?

PS, I'm running on Windows Server Datacenter 2008

Edited by Montfrooij
Link to comment
Share on other sites

  • Moderators

Montfrooij,

The second one seems to need a bit more work

And you obviously expect me to do it! :D

Actually it is really easy. You need the $LVS_SHOWSELALWAYS style for the ListView. So just change the listview creation lines to read: :graduated:

$lView = GUICtrlCreateListView($sLvCol, $iLvLeft, $iLvTop, $iLvWidth, $iLvHeight, BitOr($LVS_ICON, $LVS_SHOWSELALWAYS), BitOR($LVS_SORTDESCENDING, $LVS_EX_GRIDLINES))
GUICtrlSetBkColor($lView, 0xFF0000)
GUICtrlSetBkColor($lView, $GUI_BKCOLOR_LV_ALTERNATE)

You need to adjust the backcolour of the ListView to make sure that the selected items have sufficient contrast when the ListView no longer has focus - on my machine it is very close to the default listView colour. I have exaggerated the backcolour for effect in this snippet - you can change it to a colour you can live with that has sufficient contrast. :D

Happy now? :(

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

And you obviously expect me to do it! :D

Eehm :graduated: .... I assumed you would know, so it was too tempting to ask you specifically.

Happy now? :(

The last remaining question is how to change the colour of the selection from the listview that no longer has focus.

This selection stays gray.

Your suggestion seems to affect the default colour of the 'even' lines, which works, if contrasting enough, but I would like to know if there is a way to alter the colour of the 'non focussed listview selection' (....) .

I could not find a solution for this on the forum (except for putting an icon in front of the selected items)

So if anybody knows how :D

Thanks in advance.

Link to comment
Share on other sites

  • Moderators

Montfrooij,

I would like to know if there is a way to alter the colour of the 'non focussed listview selection'

So would I! :D

I imagine it is set as part of the system colour scheme - but I have yet to find out exactly which bit need to change. Anf if I ever do, it will no doubt affect some other vital part of the GUI. :(

But we live in hope! :graduated:

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