Jump to content

Slow Listview items create


Recommended Posts

Hi,

I've got a problem with the item loading in a listview that is very slow.

Here is a example (which works faster than my main script even if you can see the same problem) :

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <WindowsConstants.au3>
#include <GUIListView.au3>

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

$gui = GUICreate("listview items", 500, 500, -1, -1)

$idListview_clic = GUICtrlCreateListView("col", 10, 10, 200, 450, BitOR($LVS_NOSORTHEADER, $LVS_SHOWSELALWAYS, $LVS_SINGLESEL, $LVS_REPORT))
_GUICtrlListView_SetExtendedListViewStyle(GUICtrlGetHandle($idListview_clic), BitOR($LVS_EX_FULLROWSELECT, $WS_EX_CLIENTEDGE))
For $i = 0 To 10
    GUICtrlCreateListViewItem("item", $idListview_clic)
Next

$idListview_flicker = GUICtrlCreateListView("col1|col2|col3  ", 270, 10, 200, 450, BitOR($LVS_NOSORTHEADER, $LVS_SHOWSELALWAYS, $LVS_REPORT))
_GUICtrlListView_SetExtendedListViewStyle(GUICtrlGetHandle($idListview_flicker), BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES, $LVS_EX_GRIDLINES))

$idButton = GUICtrlCreateButton("test", 230, 470, 70, 20)

GUISetState(@SW_SHOW)


While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop

        Case $idButton
            _generate($idListview_flicker)

    EndSwitch
WEnd



Func _generate($idLV)
    $depart = TimerInit()
    _GUICtrlListView_DeleteAllItems($idLV)
    For $i = 0 To 30
        $idItem1 = GUICtrlCreateListViewItem("item"&$i&"|col22|col23", $idLV)
    Next
    ConsoleWrite("temps = "&TimerDiff($depart)&@CRLF)
EndFunc


Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    ; $iwParam : The identifier of the common control sending the message. This identifier is not guaranteed to be unique. An application should use the hwndFrom or idFrom member of the NMHDR structure (passed as the lParam parameter) to identify the control.
    ; $ilParam : A pointer to an NMHDR structure that contains the notification code and additional information.
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) ; handle du control qui envoie le message
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")          ; identifier du control
    $iCode = DllStructGetData($tNMHDR, "Code")              ; code de notification du message

    $h_Listview = GUICtrlGetHandle($idListview_clic)

    ; selon le control sur lequel il y a un événement...
    Switch $hWndFrom
        Case $h_Listview
            Switch $iCode
                Case $NM_CLICK
                    _generate($idListview_flicker)

            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

So, when the items of the Listview on the right side are generated, the total duration is different if it's launched from WM_NOTIFY() or by the button click in the main loop.

GUICtrlCreateListViewItem() is 2 times slower. In my main script, it is even worse (6ms -> 402ms) and of course I've got flickering !

I tried with _beginupdate()/_endupdate(), it's better but another bug appears with the  listview header not refreshing correctly sometimes (in my main script)...

Any idea how I can fix this ?

Edited by tatane
Link to comment
Share on other sites

Can't you do it this way:

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <WindowsConstants.au3>
#include <GUIListView.au3>

$gui = GUICreate("listview items", 500, 500, -1, -1)

$idListview_clic = GUICtrlCreateListView("col", 10, 10, 200, 450, BitOR($LVS_NOSORTHEADER, $LVS_SHOWSELALWAYS, $LVS_SINGLESEL, $LVS_REPORT))
_GUICtrlListView_SetExtendedListViewStyle(GUICtrlGetHandle($idListview_clic), BitOR($LVS_EX_FULLROWSELECT, $WS_EX_CLIENTEDGE))
$item0 = GUICtrlCreateListViewItem("item", $idListview_clic)
For $i = 0 To 9
    GUICtrlCreateListViewItem("item", $idListview_clic)
Next

$idListview_flicker = GUICtrlCreateListView("col1|col2|col3  ", 270, 10, 200, 450, BitOR($LVS_NOSORTHEADER, $LVS_SHOWSELALWAYS, $LVS_REPORT))
_GUICtrlListView_SetExtendedListViewStyle(GUICtrlGetHandle($idListview_flicker), BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES, $LVS_EX_GRIDLINES))

$idButton = GUICtrlCreateButton("test", 230, 470, 70, 20)

GUISetState(@SW_SHOW)


While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop

        Case $idButton, $item0 To $item0 + 10
            _generate($idListview_flicker)

    EndSwitch
WEnd


Func _generate($idLV)
    Local Static $idItem1
    $depart = TimerInit()
    _GUICtrlListView_BeginUpdate($idLV)
    If $idItem1 Then
      For $i = 0 To 30
        GUICtrlDelete($idItem1+$i)
      Next
    EndIf
    $idItem1 = GUICtrlCreateListViewItem("item0"&"|col22|col23", $idLV)
    For $i = 1 To 30
      GUICtrlCreateListViewItem("item"&$i&"|col22|col23", $idLV)
    Next
    _GUICtrlListView_EndUpdate($idLV)
    ConsoleWrite("temps = "&TimerDiff($depart)&@CRLF)
EndFunc

 

Link to comment
Share on other sites

Unfortunatly no. I need WM_NOTIFY to change partial subitem colors, right click & context menu, ... and the most important is when I click an item in the left listview, it loads different items in the right one.

It seems repainting the listview while in the WM_NOTIFY function is faster (handled differently ?) than main loop.

Edited by tatane
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...