Jump to content
Sign in to follow this  
gfunk999

GUI Parent Window Loses Face

Recommended Posts

gfunk999

Hello all,

I'm not sure how to search for this on the forums, basically I made a GUI filecopy program. The scripts works great; however, while the program is running, if I open another window and slide it over my program the window turns white (loses it's face). It takes a while before it repaints itself, it seems to be a memory issue, so the question is...can I somehow allocate more memory to my program, or is there a routine I can use to prevent this?

thanks,

Gary

Share this post


Link to post
Share on other sites
martin

Hello all,

I'm not sure how to search for this on the forums, basically I made a GUI filecopy program. The scripts works great; however, while the program is running, if I open another window and slide it over my program the window turns white (loses it's face). It takes a while before it repaints itself, it seems to be a memory issue, so the question is...can I somehow allocate more memory to my program, or is there a routine I can use to prevent this?

thanks,

Gary

You need to show us some code, or explain in some detail what it is you create in your script and which is slow to repaint.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites
gfunk999

You need to show us some code, or explain in some detail what it is you create in your script and which is slow to repaint.

Basically it fails to repaint when a huge file (i.e. .pst file) is being copied. I'll post an example shortly, but you will need a 1+GB .pst file to test...

post-24538-1233348485_thumb.jpg

Share this post


Link to post
Share on other sites
gfunk999

Heres a quick test GUI, however, you need files that are at least 1GB or bigger to reproduce. As you can see i'm using c:\1\ as my source and c:\mail\ as my destination folder. I attached two pictures of before and after copy shots. Basically when the process starts and you hover any window on top of your program it does not refresh. See pics below.

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <array.au3>
#include <file.au3>

$Form1 = GUICreate("test", 447, 270, 193, 125)
$Button1 = GUICtrlCreateButton("Copy", 248, 224, 75, 25, 0)
$Button2 = GUICtrlCreateButton("Cancel", 344, 224, 75, 25, 0)
$Label1 = GUICtrlCreateLabel("Copy: ", 8, 50, 50, 25)
$Label2 = GUICtrlCreateLabel("", 50, 50, 200, 25)

$files = _FileListToArray("c:\1", "*")

GUISetState(@SW_SHOW)

While 1
$nMsg = GUIGetMsg()
    If $nMsg = $GUI_EVENT_CLOSE Or $nMsg = $Button2 Then Exit
    Switch $nMsg
        Case $Button1
                copy()
    EndSwitch
WEnd

Func copy()
    For $f = 1 To $files[0]
        $err = FileCopy("c:\1\" & $files[$f], "C:\mail\" & $files[$f], 1)
            GUICtrlSetData($Label2, "Processing " & " " & $files[$f])
                If $err = 0 Then 
                    FileWrite("C:\mail\err.log", $files[$f] & "  " & "failed to copy" & @CRLF)
                EndIf
    Next
        MsgBox(0, "", "finished")
    Exit
EndFunc

post-24538-1233353190_thumb.jpg

Share this post


Link to post
Share on other sites
martin

Heres a quick test GUI, however, you need files that are at least 1GB or bigger to reproduce. As you can see i'm using c:\1\ as my source and c:\mail\ as my destination folder. I attached two pictures of before and after copy shots. Basically when the process starts and you hover any window on top of your program it does not refresh. See pics below.

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <array.au3>
#include <file.au3>

$Form1 = GUICreate("test", 447, 270, 193, 125)
$Button1 = GUICtrlCreateButton("Copy", 248, 224, 75, 25, 0)
$Button2 = GUICtrlCreateButton("Cancel", 344, 224, 75, 25, 0)
$Label1 = GUICtrlCreateLabel("Copy: ", 8, 50, 50, 25)
$Label2 = GUICtrlCreateLabel("", 50, 50, 200, 25)

$files = _FileListToArray("c:\1", "*")

GUISetState(@SW_SHOW)

While 1
$nMsg = GUIGetMsg()
    If $nMsg = $GUI_EVENT_CLOSE Or $nMsg = $Button2 Then Exit
    Switch $nMsg
        Case $Button1
                copy()
    EndSwitch
WEnd

Func copy()
    For $f = 1 To $files[0]
        $err = FileCopy("c:\1\" & $files[$f], "C:\mail\" & $files[$f], 1)
            GUICtrlSetData($Label2, "Processing " & " " & $files[$f])
                If $err = 0 Then 
                    FileWrite("C:\mail\err.log", $files[$f] & "  " & "failed to copy" & @CRLF)
                EndIf
    Next
        MsgBox(0, "", "finished")
    Exit
EndFunc
I think that the FileCopy function is probably blocking execution of other functions in the script. Maybe this approach would work thought I haven't tried it with large files.

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <array.au3>
#include <file.au3>

$Form1 = GUICreate("test", 447, 270, 193, 125)
$Button1 = GUICtrlCreateButton("Copy", 248, 224, 75, 25, 0)
$Button2 = GUICtrlCreateButton("Cancel", 344, 224, 75, 25, 0)
$Label1 = GUICtrlCreateLabel("Copy: ", 8, 50, 50, 25)
$Label2 = GUICtrlCreateLabel("", 50, 50, 200, 25)

$files = _FileListToArray("c:\1", "*")

GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    If $nMsg = $GUI_EVENT_CLOSE Or $nMsg = $Button2 Then Exit
    Switch $nMsg
        Case $Button1
            copy()
        case -3
            Exit
    EndSwitch
WEnd

Func copy()
    For $f = 1 To $files[0]
        $instr = "copy c:\1\" & $files[$f] & " C:\mail\" & $files[$f]
        GUICtrlSetData($Label2, "Processing " & " " & $files[$f])
        
        $data = ''

        If $instr = '' Then Return

        Local $foo = Run("cmd.exe", @SystemDir, @SW_HIDE, 9);$STDIN_CHILD + $STDOUT_CHILD)
        StdinWrite($foo, $instr & @CRLF)
       ; Calling with no 2nd arg closes stream
        StdinWrite($foo)

       ; Read from child's STDOUT and show
        Local $data
        While True
            $data &= StdoutRead($foo)
            If @error Then ExitLoop
            Sleep(25)
        WEnd
        if not StringInStr($data,"1 file(s) copied") then
            FileWrite("C:\mail\err.log", $files[$f] & "  " & "failed to copy" & @CRLF)
        EndIf
    Next
    MsgBox(0, "", "finished")
    Exit
EndFunc  ;==>copy

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites
gfunk999

Your code worked (very well I might add); however, I commited to filecopy, and I really don't want to depend on copy. Copy does not handle problems well, for instance, if it comes accros a file it cannot copy it just crashes instead of moving on like filecopy does.

I think that the FileCopy function is probably blocking execution of other functions in the script. Maybe this approach would work thought I haven't tried it with large files.

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <array.au3>
#include <file.au3>

$Form1 = GUICreate("test", 447, 270, 193, 125)
$Button1 = GUICtrlCreateButton("Copy", 248, 224, 75, 25, 0)
$Button2 = GUICtrlCreateButton("Cancel", 344, 224, 75, 25, 0)
$Label1 = GUICtrlCreateLabel("Copy: ", 8, 50, 50, 25)
$Label2 = GUICtrlCreateLabel("", 50, 50, 200, 25)

$files = _FileListToArray("c:\1", "*")

GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    If $nMsg = $GUI_EVENT_CLOSE Or $nMsg = $Button2 Then Exit
    Switch $nMsg
        Case $Button1
            copy()
        case -3
            Exit
    EndSwitch
WEnd

Func copy()
    For $f = 1 To $files[0]
        $instr = "copy c:\1\" & $files[$f] & " C:\mail\" & $files[$f]
        GUICtrlSetData($Label2, "Processing " & " " & $files[$f])
        
        $data = ''

        If $instr = '' Then Return

        Local $foo = Run("cmd.exe", @SystemDir, @SW_HIDE, 9);$STDIN_CHILD + $STDOUT_CHILD)
        StdinWrite($foo, $instr & @CRLF)
      ; Calling with no 2nd arg closes stream
        StdinWrite($foo)

      ; Read from child's STDOUT and show
        Local $data
        While True
            $data &= StdoutRead($foo)
            If @error Then ExitLoop
            Sleep(25)
        WEnd
        if not StringInStr($data,"1 file(s) copied") then
            FileWrite("C:\mail\err.log", $files[$f] & "  " & "failed to copy" & @CRLF)
        EndIf
    Next
    MsgBox(0, "", "finished")
    Exit
EndFunc ;==>copy

Share this post


Link to post
Share on other sites
martin

Your code worked (very well I might add); however, I commited to filecopy, and I really don't want to depend on copy. Copy does not handle problems well, for instance, if it comes accros a file it cannot copy it just crashes instead of moving on like filecopy does.

I don't understand what happens if Copy fails. Even if it crashes I would not have expected that to be a problem. What hapeens to your script in that event? Does it hang?

Anyway, the point is that you can get over the painting problem by using another process to do the copying. It needn't be Run the way I did it, you could have your own little compile script which uses FileCopy which you call with run or ShellExecute and pass it the parameters of the file to copy and the destination. It could send you a message about the result maybe or write to a file. You could embed the code for the script in your main script, write the file as an au3 file and run it instead of having a separate compiled script. Or maybe just use Run and have the output sent to a file. Then all the time that the run PID exists it is copying and when it no longer exists you can check the result file.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites
gfunk999

I have compared both xcopy and copy vs Filecopy. The copy speed from xcopy, or copy does not compare to filecopy; Filecopy rule! However, if I had to use an alternative I would go with copy, but it does not have a switch for hidden files. Xcopy does, but it's too darn slow when processing folders with multiple subfolders/files.

What hapeens to your script in that event? Does it hang?

Nothing with filecopy, it just returns an error and I write it to an error log. Copy crashes, and I get the standard windows error your cmd.exe has encounter an error blah blah blah and it must close. xcopy includes switch /c that should "Continue copying even if errors occur", but I have yet to see this work, and then I get that infamous crash error.

could have your own little compile script which uses FileCopy which you call with run or ShellExecute and pass it the parameters of the file to copy and the destination.

I love this idea! I'll try after I get some zzzz's I don't know why I didn't think of this... thanks again Martin.

Gary

I don't understand what happens if Copy fails. Even if it crashes I would not have expected that to be a problem. What hapeens to your script in that event? Does it hang?

Anyway, the point is that you can get over the painting problem by using another process to do the copying. It needn't be Run the way I did it, you could have your own little compile script which uses FileCopy which you call with run or ShellExecute and pass it the parameters of the file to copy and the destination. It could send you a message about the result maybe or write to a file. You could embed the code for the script in your main script, write the file as an au3 file and run it instead of having a separate compiled script. Or maybe just use Run and have the output sent to a file. Then all the time that the run PID exists it is copying and when it no longer exists you can check the result file.

Share this post


Link to post
Share on other sites
gfunk999

I guess those zzz's did not work, I'm stuck :) , I built that small filecopy.exe, and I can't seem to pass my parameters from the main program, to the filecopy.exe using the Run command.

;Main program:
$Source = "C:\Mail\personal.pst"
$Destination = "Z:\Backup\personal.pst"

Run("filecopy.exe", "C:\autoit" , @SW_HIDE)oÝ÷ Ù«­¢+ØíQ¡¥±½Áä¹áÁɽɴ)½Áä ÀÌØíM½ÕÉ°ÀÌØíÍÑ¥¹Ñ¥½¸¤()Õ¹½Áä ÀÌØí¥±Ä°ÀÌØí¥±È¤(ÀÌØíÉÍÕ±Ðô¥±
½Áä ÀÌØí¥±Ä°ÀÌØí¥±È°Ä¤)5Í ½à À°ÅÕ½ÐìÅÕ½Ðì°ÀÌØíÉÍձФ()¹Õ¹
Edited by gfunk999

Share this post


Link to post
Share on other sites
martin

I guess those zzz's did not work, I'm stuck :) , I built that small filecopy.exe, and I can't seem to pass my parameters from the main program, to the filecopy.exe using the Run command.

;Main program:
$Source = "C:\Mail\personal.pst"
$Destination = "Z:\Backup\personal.pst"

Run("filecopy.exe", "C:\autoit" , @SW_HIDE)oÝ÷ Ù«­¢+ØíQ¡¥±½Áä¹áÁɽɴ)½Áä ÀÌØíM½ÕÉ°ÀÌØíÍÑ¥¹Ñ¥½¸¤()Õ¹½Áä ÀÌØí¥±Ä°ÀÌØí¥±È¤(ÀÌØíÉÍÕ±Ðô¥±
½Áä ÀÌØí¥±Ä°ÀÌØí¥±È°Ä¤)5Í ½à À°ÅÕ½ÐìÅÕ½Ðì°ÀÌØíÉÍձФ()¹Õ¹
I hope this helps

;Main program:
$Source = "C:\Mail\personal.pst"
$Destination = "Z:\Backup\personal.pst"
$test = "filecopy.exe" & ' "' & $Source & '"' & ' "' & $Destination & '"'
ConsoleWrite($test & @CRLF)
Run($test, "C:\autoit", @SW_HIDE)
;add quotation marks in case the source or dest has a space in the path.


;;;;;;;;;;;;;;;;;  the exe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;The filecopy.exe program
If $CmdLine[0] < 2 Then
    MsgBox(262144, "ERROR", "I need 2 parameters to work from!")
    Exit
EndIf

fcopy($CmdLine[1], $CmdLine[2])

Func fcopy($File1, $File2)
    $result = FileCopy($File1, $File2, 1)
    MsgBox(0, "", $result)

EndFunc  ;==>fcopy

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites
gfunk999

Hi Martin,

I've been meaning to thank you, your code worked perfect! :)

GF.

I hope this helps

;Main program:
$Source = "C:\Mail\personal.pst"
$Destination = "Z:\Backup\personal.pst"
$test = "filecopy.exe" & ' "' & $Source & '"' & ' "' & $Destination & '"'
ConsoleWrite($test & @CRLF)
Run($test, "C:\autoit", @SW_HIDE)
;add quotation marks in case the source or dest has a space in the path.


;;;;;;;;;;;;;;;;;  the exe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;The filecopy.exe program
If $CmdLine[0] < 2 Then
    MsgBox(262144, "ERROR", "I need 2 parameters to work from!")
    Exit
EndIf

fcopy($CmdLine[1], $CmdLine[2])

Func fcopy($File1, $File2)
    $result = FileCopy($File1, $File2, 1)
    MsgBox(0, "", $result)

EndFunc ;==>fcopy

Share this post


Link to post
Share on other sites
martin

Hi Martin,

I've been meaning to thank you,

That's ok.

your code worked perfect! :)

GF.

That's good :)

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

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  

×