How can I display text during file copying?

Just starting out? Need help? Post your questions and find answers here.
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: How can I display text during file copying?

Post by walbus »

The way I described it above is the only one that works perfectly
There are also other problems
If files are very large and/or the storage medium is very slow
On Windows there are quickly ugly effects with the window when no WindowEvent occurs
With such batch routines you must also consider that you can abort them again

With a While WIndowEvent() : Wend Call there is no possibility to cancel, because there are no more events available for check a button

After copying a small block, a WindowEvent() call
Before this call you update the progressbar and the text gadget
So you can also check simple Button events

Furthermore, a list must be created which records and can report errors
However, a copy error should only be displayed in a log after the end of the batch routine, otherwise the batch routine will get stuck and will not be finished and you will also have problems with localization and error correction.

It's also perfect when you consider that Fat32, which is often found on sticks, can't record files larger than 4GB (videos)
There must also be enough space on the stick for the files to be copied, otherwise there will be trouble

The corpses of files that could not be copied correctly must be automatically closed and removed from the target medium

Also you should use a custom progress bar, the Windows Progressbar is to slow and this look very bad, you seen not exactelly a fast progress
Is also annoying, the OS Progressbars look very different on the different OS, so a custom bar is recommended

So it's the details you should and must consider to make it perfect
Quickly, a simple thing becomes a rather complicated and complex one. :wink:
Last edited by walbus on Fri May 04, 2018 9:12 am, edited 3 times in total.
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: How can I display text during file copying?

Post by Dude »

Marc56us wrote:PB auto-refresh gadgets only when WindowEvent() occurs
Correct, because one of those events is #WM_PAINT, which redraws the window and all gadgets.

However, you can always send a manual redraw message to any gadget to make it update immediately, without using a WindowEvent() loop, like so:

Code: Select all

UpdateWindow_(GadgetID(gad))
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: How can I display text during file copying?

Post by walbus »

The WindowEvent Call does not cause any problems if it is used correctly and carefully :wink:
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: How can I display text during file copying?

Post by Dude »

I was just offering alternatives. :)
User avatar
mk-soft
Always Here
Always Here
Posts: 6554
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: How can I display text during file copying?

Post by mk-soft »

Small snipped for threads with cancel button...

Update v1.03

Code: Select all

;-TOP
;
; Comment : Thread Status Window
; Author  : mk-soft
; Version : v1.03
; Create  : 16.03.2018
; Update  : 04.05.2018
;
; -----------------------------------------------------------------------------

EnableExplicit

CompilerIf #PB_Compiler_Thread = 0
  CompilerError "Use Compiler Option Threadsafe"
CompilerEndIf

Enumeration EventCustomValue #PB_Event_FirstCustomValue
  ; Nothing
EndEnumeration
  
Enumeration EventCustomValue
  #MyEvent_ThreadStatusOpenWindow
  #MyEvent_ThreadStatusCloseWindow
  #MyEvent_ThreadStatusUpdateWindow
EndEnumeration

Structure udtThreadStatus
  Signal.i
  Window.i
  Info.i
  Progress.i
  Cancel.i
  x.i
  y.i
  dx.i
  dy.i
  Title.s
  Text.s
  Button.s
  Min.i
  Max.i
  Value.i
EndStructure


; -----------------------------------------------------------------------------

Declare DoEvent_TryCancelStatusWindow()

; -----------------------------------------------------------------------------

Procedure DoOpenStatusWindow(x, y, dx, dy, Title.s, Text.s, Button.s="Cancel", Min=0, Max=100)
  Protected *data.udtThreadStatus
  With *data
    *data = AllocateStructure(udtThreadStatus)
    If *data
      \x = x
      \y = y
      \dx = dx
      \dy = dy
      \Title = Title
      \Text = Text
      \Button = Button
      \Min = Min
      \Max = Max
      \Signal = CreateSemaphore()
      PostEvent(#MyEvent_ThreadStatusOpenWindow, 0, 0, 0, *data)
      WaitSemaphore(\Signal)
      If \Window
        ProcedureReturn *data
      Else
        FreeSemaphore(\Signal)
        FreeStructure(*data)
        ProcedureReturn 0 ; Error open windows
      EndIf
    Else
      ProcedureReturn 0 ; Out of Memory
    EndIf
  EndWith
EndProcedure

Procedure DoEvent_OpenStatusWindow()
  Protected *data.udtThreadStatus
  With *data
    *data = EventData()
    If *data
      \Window = OpenWindow(#PB_Any, \x, \y, \dx, \dy, \Title, #PB_Window_Tool)
      If \Window
        \Info = TextGadget(#PB_Any, 5, 5, \dx - 10, \dy - 65, \Text, #PB_Text_Center | #PB_Text_Border) 
        \Progress = ProgressBarGadget(#PB_Any, 5, \dy - 55, \dx - 10, 20, \Min, \Max)
        \Cancel = ButtonGadget(#PB_Any, \dx / 2 - 60, \dy - 30, 120, 25, \Button)
        SetGadgetData(\Cancel, *data)
        BindGadgetEvent(\Cancel, @DoEvent_TryCancelStatusWindow())
      EndIf
      SignalSemaphore(\Signal)
    EndIf
  EndWith
EndProcedure

; -----------------------------------------------------------------------------

Procedure DoCloseStatusWindow(*Data.udtThreadStatus)
  With *Data
    If *Data
      PostEvent(#MyEvent_ThreadStatusCloseWindow, 0, 0, 0, *Data)
    EndIf
  EndWith
EndProcedure

Procedure DoEvent_CloseStatusWindow()
  Protected *data.udtThreadStatus
  With *data
    *data = EventData()
    If *data
      If IsWindow(\Window)
        CloseWindow(\Window)
      EndIf
      FreeSemaphore(\Signal)
      FreeStructure(*Data)
    EndIf
  EndWith
EndProcedure

; -----------------------------------------------------------------------------

Procedure TryCancelStatusWindow(*Data.udtThreadStatus)
  If *Data
    ProcedureReturn TrySemaphore(*Data\Signal)
  Else
    ProcedureReturn 0 
  EndIf
EndProcedure

Procedure DoEvent_TryCancelStatusWindow()
  Protected *data.udtThreadStatus
  With *data
    *data = GetGadgetData(EventGadget())
    If *data
      SignalSemaphore(\Signal)
    EndIf
  EndWith
EndProcedure

; -----------------------------------------------------------------------------

Procedure DoUpdateStatusWindow(*Data.udtThreadStatus, Value.i)
  With *Data
    If *Data
      \Value = Value
      PostEvent(#MyEvent_ThreadStatusUpdateWindow, 0, 0, 0, *Data)
    EndIf
  EndWith
EndProcedure

Procedure DoEvent_UpdateStatusWindow()
  Protected *data.udtThreadStatus
  With *data
    *data = EventData()
    If *data
      If IsGadget(\Progress)
        SetGadgetState(\Progress, \Value)
      EndIf
    EndIf
  EndWith
EndProcedure

; -----------------------------------------------------------------------------

BindEvent(#MyEvent_ThreadStatusOpenWindow, @DoEvent_OpenStatusWindow())
BindEvent(#MyEvent_ThreadStatusCloseWindow, @DoEvent_CloseStatusWindow())
BindEvent(#MyEvent_ThreadStatusUpdateWindow, @DoEvent_UpdateStatusWindow())

; -----------------------------------------------------------------------------

; ***************************************************************************************

;-Test

CompilerIf #PB_Compiler_IsMainFile
  
  Procedure thProgress(Nummer)
    Protected *Data, Text.s, Value, time
    
    
    Debug "Start Thread " + Nummer
    time = Random(40000, 10000)
    text = #LF$ + "Thread Background State" + #LF$ + Str(time / 1000) + " Second" + #LF$ + "Press cancel for break"
    *Data = DoOpenStatusWindow(#PB_Ignore, #PB_Ignore, 300, 160, "Thread Number " + Nummer, Text); , "Abbrechen")
    
    Repeat
      ;TODO
      Delay(500)
      value + 500
      DoUpdateStatusWindow(*Data, (Value * 100 / time) % 100)
    Until TryCancelStatusWindow(*Data) Or Value >= time
    DoCloseStatusWindow(*Data)
    Debug "Ende Thread " + Nummer + " Value = " + Value
  EndProcedure
  
  If OpenWindow(0, #PB_Ignore, #PB_Ignore, 200, 80, "Thread Test")
    CreateThread(@thProgress(), 1)
    CreateThread(@thProgress(), 2)
    CreateThread(@thProgress(), 3)
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          If EventWindow() = 0
            Break
          EndIf
      EndSelect
    ForEver
  EndIf
  
CompilerEndIf
Another way is to use my Module ThreadToGUI
My Projects EventDesigner V3 / ThreadToGUI / OOP-BaseClass / Windows: Module ActiveScript
PB v3.30 / v5.75 - OS Mac Mini - VM Window Pro / Linux Ubuntu
Downloads on my OneDrive
User avatar
mk-soft
Always Here
Always Here
Posts: 6554
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: How can I display text during file copying?

Post by mk-soft »

There should always be only one 'WaitWindowEvent' in the program and this should always be called in the mainscope.
Windows and gadgets should only be created in the mainscope.

Changing the content of gadgets on windows also partly works with threads.
With Linus and mac this leads to massive problems.

PostEvent was added to make changes to the GUI from threads.

I also work a lot with threads and wrote a module "ThreadToGUI" to simplify programming in threads.

To open from a dialog window from a thread I use from PostEvent and with a semaphore that is also created with it in the mainscope.

Threads always receive a structure from me, where all necessary information is stored. Also termination conditions which are set in the mainscope and read cyclically from the thread. Either via a variable 'CMD' or via semaphores.

If you follow this rule for GUI and threads there are no problems and you don't need an API.

Link to ThreadToGUI: http://www.purebasic.fr/english/viewtop ... 12&t=66180

Translated with http://www.DeepL.com/Translator
My Projects EventDesigner V3 / ThreadToGUI / OOP-BaseClass / Windows: Module ActiveScript
PB v3.30 / v5.75 - OS Mac Mini - VM Window Pro / Linux Ubuntu
Downloads on my OneDrive
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: How can I display text during file copying?

Post by Dude »

mk-soft wrote:There should always be only one 'WaitWindowEvent' in the program
Depends on what your app does.
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: How can I display text during file copying?

Post by walbus »

My two cent
Using WindowEvent or WaitWindowEvent is primarily a matter of planning and consideration.
As long as the call and the evaluation are sequential, you can use as many as you want.
The use of threads unfortunately restricts the universal usability of a tool in a not insignificant way.
The activation of threadsave also has a significant negative effect on the execution speed.
Even I don't code tools for the community which don't run clean on all OS anymore.
Misconduct is not always immediately apparent and can lead to considerable problems if it is only detected at an advanced stage of development.

So I always try to be conservative and avoid everything that is unnecessarily complicated or could cause problems.
Post Reply