Jump to content
Sign in to follow this  
dabus

Using _GUICtrlListView_BeginUpdate but window flickers when using a tab

Recommended Posts

dabus

Hi folks.

Haven't been around asking much in the past time since there were no issues or at least none that couldn't be fixed with the help of previous topics, but I didn't find any for this one:

Test 1: If I create a listview and use _GUICtrlListView_BeginUpdate, everything is ok.

Test 2: If I use a tab, the screen still flickers.

Test 3: If I prevent to repaint, the flickering goes away but progress gets lost I mean, sure it does. I just wanted to show that I know that one, but that's not working 100% ;) .

I just moved the progress-bar into a child-window in my real project that overlays the window, so there is a workaround and no need to rush anything. But I still thought I post it as something to chew on. (I also tested the beta)

So why does the tab cause this problem? :geek:

And is there a way to keep the window from flickering without moving into a child-window?

#include <GuiListView.au3>


Test(1)
Test(2)
Test(3)


Func Test($Run)

$g_UI=GUICreate('Sample:'&$Run, 200, 200)
$g_UI_Interact1=GUICtrlCreateProgress(0, 0, 200, 20)

If $Run <> 1 Then
GUICtrlCreateTab(10, 10, 180, 180)
$tab0 = GUICtrlCreateTabItem("tab0")
EndIf

$g_UI_Interact2=GUICtrlCreateListView('1|2|3|4', 10, 20, 180, 180)
$g_UI_Handle=GUICtrlGetHandle($g_UI_Interact2)
If $Run <> 1 Then GUICtrlCreateTabItem("")



GUISetState()
Sleep(2000)
_GUICtrlListView_BeginUpdate($g_UI_Handle)
If $Run=3 Then GUISetState(@SW_LOCK)
For $s=1 to 3000
GUICtrlSetData($g_UI_Interact1, $s*100/3000); set the progress
GUICtrlCreateListViewItem('1|2|3|4', $g_UI_Interact2)
Next
If $Run=3 Then GUISetState(@SW_UnLOCK)
_GUICtrlListView_EndUpdate($g_UI_Handle)
Sleep(2000)
GUIDelete($g_UI)
EndFunc

Share this post


Link to post
Share on other sites
kyo

Same problem here. ListView is in a tab control, and even though I use _GUICtrlListView_BeginUpdate($LV) and _GUICtrlListView_EndUpdate($LV), it stills flickers like crazy.

If I disable those two calls, it flickers *and* takes forever to update... So I'm keeping then in the code, but I'd prefer the flickering to go away...

If anyone has any idea, I'd be glad to try!

Edit: I just tried locking the gui with GuiSetState(@SW_LOCK, $Form1) before the updates, and unlocking it after - it works, but renders any progressbar useless, which is not a viable solution at this point.

Edited by kyo

Share this post


Link to post
Share on other sites
BrewManNH

Hide the window with the LV when updating it and you won't see the problem occurring.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites
Yashied
kyo

There is a very simple solution. Use _GUICtrlListView_AddItem() instead of GUICtrlCreateListViewItem().

Then the rest of my code doesn't work... :) Let's see if I can post it so it doesn't look too bad!

Func LoadFiles($EnLigne, ByRef $LV)

; Variables used by the progressbar

Local $GlobalSteps
Local $TotalSteps
Local $GlobalProgress

If $EnLigne Then
$Prefix = $Address
GUICtrlSetData($LV, "Nom du fichier sur " & $OnlineServerName)
Else
$Prefix = $OfflineAddress
GUICtrlSetData($LV, "Nom du fichier sur " & $OfflineServerName)
EndIf

$TheFiles = _RecFileListToArray($Prefix, "*.log", 1, 0, 1, 0, "", "")

_GUICtrlListView_BeginUpdate($LV)
_GUICtrlListView_DeleteAllItems($LV)

$TotalSteps = UBound($TheFiles)-1
GUICtrlSetData($Progress1, 0)
GUICtrlSetState($Progress1, $GUI_SHOW)

$GlobalSteps = 100 / $TotalSteps

for $x = 1 to UBound($TheFiles)-1
GUICtrlCreateListViewItem($TheFiles[$x], $LV)
$GlobalProgress += $GlobalSteps
GUICtrlSetData($Progress1, $GlobalProgress)
Next

_GuiCtrlListView_SetColumnWidth($LV, 0, $LVSCW_AUTOSIZE)
_GUICtrlListView_EndUpdate($LV)

GUICtrlSetState($Progress1, $GUI_HIDE)

EndFunc

If I replace this:

GUICtrlCreateListViewItem($TheFiles[$x], $LV)

by this:

_GUICtrlListView_AddItem($LV, $Patate[$x])

Then the call to

_GUICtrlListView_DeleteAllItems($LV)
does not work anymore when the function gets called again with the $EnLigne parameter changed from True to False. Then the files discovered by _RecFileListToArray in the "offline" folder are added to the "online" files already in the ListView, instead of their entries being replaced.

Currently the code works, but has that nasty "flickering" effect....

Share this post


Link to post
Share on other sites
water

You first have to close the Tab.

#include <GuiListView.au3>


Test(1)
Test(2)
Test(3)


Func Test($Run)

    $g_UI = GUICreate('Sample:' & $Run, 200, 200)
    $g_UI_Interact1 = GUICtrlCreateProgress(0, 0, 200, 20)
    Local $iTop = 20, $iWidth = 180
    If $Run <> 1 Then
        GUICtrlCreateTab(10, 20, 180, 180)
        $tab0 = GUICtrlCreateTabItem("tab0")
        GUICtrlCreateTabItem("")
        $iTop = 40
        $iWidth = 178
    EndIf

    $g_UI_Interact2 = GUICtrlCreateListView('1|2|3|4', 10, $iTop, $iWidth, 180)
    $g_UI_Handle = GUICtrlGetHandle($g_UI_Interact2)
    GUISetState()
    Sleep(2000)
    _GUICtrlListView_BeginUpdate($g_UI_Handle)
    If $Run = 3 Then GUISetState(@SW_LOCK)
    For $s = 1 To 3000
        GUICtrlSetData($g_UI_Interact1, $s * 100 / 3000); set the progress
        GUICtrlCreateListViewItem('1|2|3|4', $g_UI_Interact2)
    Next
    If $Run = 3 Then GUISetState(@SW_UNLOCK)
    _GUICtrlListView_EndUpdate($g_UI_Handle)
    Sleep(2000)
    GUIDelete($g_UI)
EndFunc   ;==>Test

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
kyo

This is a simple test I did:

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

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("LV Test", 607, 270, 192, 124)
$ListView1 = GUICtrlCreateListView("This is a perfectly acceptable header", 16, 8, 578, 230)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 250)
$Button1 = GUICtrlCreateButton("Empty LV", 16, 240)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

Global $StartPoint = 0

LoadFiles($ListView1, $StartPoint)

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

Case $Button1
EmptyLV($ListView1)
$Startpoint += 100
LoadFiles($ListView1, $StartPoint)

EndSwitch
WEnd


Func LoadFiles(ByRef $LV, $Starting)
for $x = $Starting to $Starting + 9
_GUICtrlListView_AddItem($LV, "Test item #" & $x)
;~ GUICtrlCreateListViewItem("Test item #" & $x, $LV)
Next

EndFunc

Func EmptyLV(ByRef $LV)
If Not _GUICtrlListView_DeleteAllItems($ListView1) Then
Beep(1000)
EndIf
EndFunc

If you try it, you'll get a beeping sound. If you swap the commented line for the uncommented line, no beep.

I just don't understand why....

Thanks!

Share this post


Link to post
Share on other sites
water

Did you try my example I posted above?

The tab doesn't flicker in my example where it does in your.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
kyo

Did you try my example I posted above?

The tab doesn't flicker in my example where it does in your.

I did try your example, and it does not flicker.

But when I modify my code to use what I understood from your code, like this:

$LVHandle = GUICtrlGetHandle($LV)

_GUICtrlListView_BeginUpdate($LVHandle)
_GUICtrlListView_DeleteAllItems($LVHandle)
GUISetState(@SW_LOCK)

; Allume le progressbar, calcule fin et steps, et on progresse!

$TotalSteps = UBound($TheFiles)-1
GUICtrlSetData($Progress1, 0)
GUICtrlSetState($Progress1, $GUI_SHOW)

; Puis on calcule le nombre de steps..

$GlobalSteps = 100 / $TotalSteps

for $x = 1 to UBound($TheFiles)-1
GUICtrlCreateListViewItem($TheFiles[$x], $LV)

; Et on fait avancer la progressbar d'un step

$GlobalProgress += $GlobalSteps
GUICtrlSetData($Progress1, $GlobalProgress)
Next

_GuiCtrlListView_SetColumnWidth($LVHandle, 0, $LVSCW_AUTOSIZE)
GUISetState(@SW_UNLOCK)
_GUICtrlListView_EndUpdate($LVHandle)

my entire GUI flickers twice while the ListView is updated and the progressbar is shown for very little time, and disappears very quicky too. Sorry if I'm not very clear, english is not my native language.

When I use the _GuiCtrlListView_AddItem() function, nothing flickers, but I'm unable to enpty the ListView control before adding new items.... I'd prefer that technique, but I can't get it to work...

Thanks for your help!

BTW, I'm using your AD UDF in a project at work, and it's been very very useful even though I'm only using a subset of it's functionalities! Thanks a million for this too!

Share this post


Link to post
Share on other sites
water

The code you posted look like something completely different. It's no reproducer script (a full script that can be tested by the forum users to find the bug).

Please post a small reproducer script that shows the problem you have now.

BTW: Glad you like the AD UDF!


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
kyo

The code you posted look like something completely different. It's no reproducer script (a full script that can be tested by the forum users to find the bug).

Please post a small reproducer script that shows the problem you have now.

BTW: Glad you like the AD UDF!

Ok, there it is:

#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <ProgressConstants.au3>
#include "recfilelisttoarray.au3"


#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("LV Test", 774, 466)
$tabGeneral = GUICtrlCreateTab(-1, -1, 770, 438)
GUICtrlCreateTabItem("First bank of servers")
GUICtrlSetState(-1, $GUI_SHOW); will be display first
$ListView1 = GUICtrlCreateListView("Nom du fichier", 5, 25, 502, 406, $LVS_REPORT, BitOR($WS_EX_CLIENTEDGE, $LVS_EX_CHECKBOXES))
_GuiCtrlListView_SetColumnWidth($ListView1, 0, $LVSCW_AUTOSIZE)
$Button1 = GUICtrlCreateButton("Reload LV", 512, 165, 250, 25)
$Progress1 = GUICtrlCreateProgress(512, 200, 250)
GUICtrlCreateTabItem("Second bank of servers")
GUICtrlCreateTabItem("About")

GUICtrlSetState($Progress1, $GUI_HIDE)

GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

$EnLigne = True

$OfflineAddress = @ScriptDir
$Address = @SystemDir

$OfflineServerName = "Offline Server"
$OnlineServerName = "Online Server"

LoadFiles($EnLigne, $ListView1)

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

Case $Button1
EmptyLV($ListView1)
$EnLigne = Not $EnLigne
LoadFiles($EnLigne, $ListView1)

EndSwitch
WEnd


Func LoadFiles($EnLigne, ByRef $LV)

; Variables utilisées pour la progressbar

Local $GlobalSteps
Local $TotalSteps
Local $GlobalProgress

If $EnLigne Then
$Prefix = $Address
GUICtrlSetData($LV, "Nom du fichier sur " & $OnlineServerName)
Else
$Prefix = $OfflineAddress
GUICtrlSetData($LV, "Nom du fichier sur " & $OfflineServerName)
EndIf

$TheFiles = _RecFileListToArray($Prefix, "*.*", 1, 0, 1, 0, "", "")

$LVHandle = GUICtrlGetHandle($LV)

GUISetState(@SW_LOCK)
_GUICtrlListView_BeginUpdate($LVHandle)
_GUICtrlListView_DeleteAllItems($LVHandle)

; Allume le progressbar, calcule fin et steps, et on progresse!

$TotalSteps = UBound($TheFiles)-1
GUICtrlSetData($Progress1, 0)
GUICtrlSetState($Progress1, $GUI_SHOW)

; Puis on calcule le nombre de steps..

$GlobalSteps = 100 / $TotalSteps

for $x = 1 to UBound($TheFiles)-1
GUICtrlCreateListViewItem($TheFiles[$x], $LV)

; Et on fait avancer la progressbar d'un step

$GlobalProgress += $GlobalSteps
GUICtrlSetData($Progress1, $GlobalProgress)
Next

_GuiCtrlListView_SetColumnWidth($LVHandle, 0, $LVSCW_AUTOSIZE)
_GUICtrlListView_EndUpdate($LVHandle)
GUISetState(@SW_UNLOCK)

; Puis on éteint le progressbar

GUICtrlSetState($Progress1, $GUI_HIDE)

EndFunc

Func EmptyLV(ByRef $LV)
If Not _GUICtrlListView_DeleteAllItems($ListView1) Then
Beep(1000)
EndIf
EndFunc

As it is now, it does not flicker, but the progressbar is not showing during the loading of files. Note that in my real-life application, the folders might contain around 9000 files, so it takes a while to load, hence the progressbar.

I might leave it like this, it loads a little quicker, and I guess I could live without the progressbar, but.... it's not what I would like it to be.

Still, I wonder why when I use the _GuiCtrlListView_AddItem() function, I can't use _GuiCtrlListView_DeleteAllItems() function to clear the ListView! It's a shame, because it seems to load faster, and it doesn't flicker, and my progressbar is behaving like i want it to. But can't clear that darn'd ListView!!

Thanks for the help, it's much appreciated.

Share this post


Link to post
Share on other sites
water

Remove line

GUISetState(@SW_LOCK)
to show the progress bar. According to the help file: "@SW_LOCK = Lock the window to avoid repainting."

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
kyo

Remove line

GUISetState(@SW_LOCK)
to show the progress bar. According to the help file: "@SW_LOCK = Lock the window to avoid repainting."

If I remove that line, then the ListView flickers when adding items. I added that line after reading your example earlier.. I thought that was your solution?

Share this post


Link to post
Share on other sites
kyo

Doggamit... now I understand that little phrase you wrote before:

You first have to close the tab

I hadn't. I thought I did, but I obviously did not.

Now the ListView does not flicker like crazy when i add items to it.

(sigh)

Thanks for the help, it pushed me in the right direction! Took a long time to get it, but I did! :-)

Share this post


Link to post
Share on other sites
water

Glad you got it working :D


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
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
Sign in to follow this  

×