Page 1 of 1

Trying to show that I'm working (my program, that is)

Posted: Fri Jun 27, 2025 7:02 am
by Steving
I am pulling my hair out (and I don't have much) trying to get some lame indication that my program is running in the form of a status bar. I've threaded my program but for some reason the status bar display shows "Not responding" and doesn't do anything. I know that my program is running but nothing shows on the small status window. Can you help me figure out what I'm doing wrong?

Side note: I know my status bar is lame and will just continuously paint the bar over and over but it should also display the number of files processed so it would give the user something to look at

Code: Select all

;
;
; Program GetFileInfo
;
; Program to get information on files from a specific folder
; Written 5/10/2025
; Written by Me
;
;

EnableExplicit

Structure FileInfoStructure
  NameOfFile.s
  PathOfFile.s
  CreateDateOfFile.i
  AccessDateOfFile.i
  ModifiedDateOfFile.i
  SizeOfFile.i
  AttributesOfFile.i
EndStructure

Structure DirectoryStructure
  NameOfFolder.s
  FolderID.i
  Processed.b
  Comment.s
EndStructure

Global LogFileName.s, Log, CountDone, CountProgressBarGadget

Global eWaitWindow.i, eType.i, gActiveGadget.i, ProgressBarWindow.i = 0, gProgressBarGadget.i = 0, gProgressBarGadgetLevel.i = 50
Global gDoneYes.i = 0, Status_Max = 1000, FileCount, GlobalDir.s
Global DirectoryNumber, StartPath.s, FileFilter.s, path.s, Pattern.s

Global NewList FileInfo.FileInfoStructure()
Global NewList Directories.DirectoryStructure()

Enumeration
  #MAIN_FORM
  #STATUS_BAR
  #TEXT
EndEnumeration

Procedure THR_increment(*para)
  Repeat
    Protected n
    n = n + 1
    LogSomething("In THR_increment: n=" + Str(n) + " FileCount = " + Str(FileCount) + " gDoneYes = " + Str(gDoneYes) + ".")
    SetGadgetText(#TEXT,"Processed "+Str(FileCount)+" files.")
    StatusBarProgress(#STATUS_BAR,0,n,#PB_StatusBar_BorderLess,0,Status_Max)
    If n>Status_Max
      n = 0
    EndIf
    Delay(100)
  Until gDoneYes = #True
EndProcedure

Define.s FullPathName, NewFolder, CurrentFolderName, FileToSave
Define FoundAnotherOne, AllFoldersProcessed.b, CurrentFolder, *ActiveElement, *TrainTrackElement, UserResponse, MissionComplete.b, MainThread, StatusThread

Procedure.s WalkRecursive(dir,path.s,Pattern.s="\.txt$")
  While NextDirectoryEntry(dir)
    If DirectoryEntryType(dir)=#PB_DirectoryEntry_Directory
      If DirectoryEntryName(dir)<>"." And DirectoryEntryName(dir)<>".."
        If ExamineDirectory(dir+1,path+DirectoryEntryName(dir),"")
          AddElement(Directories())
          Directories()\NameOfFolder = path + "\" + DirectoryEntryName(dir)
          Directories()\Processed = #False
          WalkRecursive(dir+1,path+DirectoryEntryName(dir)+"\",Pattern)
          FinishDirectory(dir+1)
        Else
          LogSomething("Error in "+path+DirectoryEntryName(dir))
        EndIf
      EndIf
    Else ; e.g. #PB_DirectoryEntry_File 
      FileCount + 1
      LogSomething("Got file number " + Str(FileCount) + ": " + DirectoryEntryName(dir) + ".")
      AddElement(FileInfo())
      FileInfo()\NameOfFile = DirectoryEntryName(dir)
      FileInfo()\PathOfFile = path
      FileInfo()\CreateDateOfFile = DirectoryEntryDate(dir, #PB_Date_Created)
      FileInfo()\ModifiedDateOfFile = DirectoryEntryDate(dir, #PB_Date_Modified)
      FileInfo()\AccessDateOfFile = DirectoryEntryDate(dir, #PB_Date_Accessed)
      fileinfo()\SizeOfFile = DirectoryEntrySize(dir)
      Fileinfo()\AttributesOfFile = DirectoryEntryAttributes(dir)
    EndIf
  Wend
EndProcedure

Procedure DoTheWalk(*ThreadNum)
  LogSomething("I'm in the thread, 5x5, reticulating splines: " + GlobalDir)
  FileCount = 0
  ExamineDirectory(1, GlobalDir, "*.*")
  WalkRecursive(1, GlobalDir, "*.*")
  LogSomething("OK, we're done now... exiting I think...")
  gDoneYes = #True
EndProcedure

gDoneYes = #False
GetLogFile()
LogSomething("Program starting...")

StartPath = InputRequester("Path to search", "Please enter the path to start the file search","C:\")

LogSomething("User input the path " + #DQUOTE$ + StartPath + #DQUOTE$)

If Right(StartPath, 1) <> "\"
  StartPath + "\"
EndIf

GlobalDir = StartPath

OpenWindow(#MAIN_FORM, 0, 0, 300, 100, "Getting File Info", #PB_Window_ScreenCentered)
TextGadget(#TEXT, 10, 10, 280, 30, "")
CreateStatusBar(#STATUS_BAR, WindowID(#MAIN_FORM))
AddStatusBarField(#PB_Ignore)
StatusThread = CreateThread(@THR_increment(),0)

MainThread = CreateThread(@DoTheWalk(), 1)

LogSomething("Now waiting on the thread to complete.")
WaitThread(MainThread)
gDoneYes = #True
LogSomething("Thread complete. Moving on to saving the file.")
KillThread(StatusThread)

CloseWindow(#MAIN_FORM)
Any help or pointers would be greatly appreciated. I'm just starting to write interactive programs with PureBasic.

Thank you!

Re: Trying to show that I'm working (my program, that is)

Posted: Fri Jun 27, 2025 7:45 am
by IceSoft

Code: Select all

[08:44:20] [COMPILER] Line 49: LogSomething() is not a function, array, list, map or macro.

Re: Trying to show that I'm working (my program, that is)

Posted: Fri Jun 27, 2025 7:46 am
by pjay
Gadgets are updated / redrawn when you process the event queue, which you're not doing here.

Try replacing:

Code: Select all

WaitThread(MainThread)
With:

Code: Select all

Define Event
Repeat
  Delay(1)
  Repeat : event = WindowEvent() : Until event = 0
Until IsThread(MainThread) = 0

Re: Trying to show that I'm working (my program, that is)

Posted: Fri Jun 27, 2025 9:48 am
by Axolotl
Hi Steving,

I recommend the following Thread stuff from mk-soft.
Module ThreadToGUI / Update windows,gadgets,... from threads
Try it out. And you will learn a lot about threads.

Some small hints to your code.
You are using so called "blocking" functions like WaitThread().
1. Add a new Event and Send the status info to this event.
2. work on this event in the main loop (see abstract and not running code below)

Code: Select all

Enumeration #PB_Event_FirstCustomValue
  #My_Event_For_Something 
EndEnumeration

; .... Main Loop for MAIN_FORM 
Repeat
  event = WaitWindowEvent()
  Select event
    Case #PB_Event_CloseWindow
      ; wait for threads to finish or kill them 
      If IsThread(thread1) : KillThread(thread1) : EndIf
      Break ; leave the loop 

    Case #My_Event_For_Something 
      ; MyEvent = EventData() 
      Debug "event from thread" 

    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          ; start a thread .... 
          If Not IsThread(thread1)
            thread = CreateThread(@DoTheWalk, @thread)  ; not perfect but give some ideas 
          EndIf
      EndSelect
  EndSelect
ForEver

Re: Trying to show that I'm working (my program, that is)

Posted: Fri Jun 27, 2025 6:34 pm
by Steving
Thanks everyone. @pjay, your code worked flawlessly. Thank you so much! @Axolotl, thank you, I will look at that link from mk-soft. I appreciate all of you and the help that I have received. Thank you.

Re: Trying to show that I'm working (my program, that is)

Posted: Fri Jun 27, 2025 7:29 pm
by mk-soft
Terminating a programme with threads and killing the threads is not a good method (you don't do that)
In this case, you use a structure variable to report that the thread should terminate and then wait with a timeout until the thread has been exited.
Threads should only be killed if they no longer respond.

For more information on how to start, stop, resume and terminate threads, see
as you know my example Mini Thread Control

Re: Trying to show that I'm working (my program, that is)

Posted: Fri Jun 27, 2025 8:35 pm
by Piero
I still did not clean any kind of pool, anyway I want to dedicate my new avatar chip to mk-soft, again :mrgreen: