Page 1 of 1

Using Gadgets from inside a Procedure [Closed]

Posted: Thu Mar 15, 2007 11:53 am
by orb_505
Hi all,

I'm an occasional PB user so don't know all the ins and outs and this is my first outing using the Windows and Gadgets rather than just the console.

I'm writing a program to copy certain files from a specific directory to a user chosen drive.

I've coded the actual copying process (it also checks to see if the required files are where the user has pointed it too) in a procedure. I want to access a progress bar and a list gadget from inside this procedure as the checking and copying is taking place.

As the gadgets where not part of the procedure than I'm having problems using them (Gadget Object Not Initialized). How can I use the gadgets from inside the procedure? I don't want to use a return as that will only come back after the check/copying has taken place, I want to keep the user informed of the current progress.

Cheers

Posted: Thu Mar 15, 2007 11:55 am
by Derek
Can you post some code, this always helps.

I'm guessing perhaps that you have named the gadgets but haven't used shared inside the procedure or global before defining the procedure.

Posted: Thu Mar 15, 2007 12:11 pm
by netmaestro
If your gadget numbers were assigned statically using constants ( MyGadget(#Gadget,... ) ) the gadget numbers will be available globally if you enumerated your constants at the top of the program. However, if you used #PB_Any, assigning the gadget numbers to variables, those variables would need to be declared Global at the top of the code in order for them to be recognized inside a procedure. PureBasic compiles in one pass, top-down, so constants and globals need to be declared at the top of the code to be available everywhere.

Posted: Thu Mar 15, 2007 12:11 pm
by orb_505
The code is quite long so can't post it all. THe general gist is:

Code: Select all

frmMain = OpenWindow(1,100,100,400,265,"PMR Data Retriver " + version,#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)  And CreateGadgetList(WindowID(1))

editList = EditorGadget(#PB_Any, 10, 100, 380, 150, #PB_Editor_ReadOnly)

Procedure CopyFiles()

  AddGadgetItem(editList, 0, "Copying")

  various lines of checking and copying code

EndProcedure

CopyFiles()

I've also tried

Code: Select all

Global editList = EditorGadget(#PB_Any, 10, 100, 380, 150, #PB_Editor_ReadOnly)
and althought this stopped the 'Gadget Not Intialized' error it still didn't add text to the edit gadget

Posted: Thu Mar 15, 2007 12:17 pm
by netmaestro
I'm not sure where your event loop is, but this is working here:

Code: Select all

frmMain = OpenWindow(1,100,100,400,265,"PMR Data Retriver " ,#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)  And CreateGadgetList(WindowID(1)) 

Global editList = EditorGadget(#PB_Any, 10, 100, 380, 150, #PB_Editor_ReadOnly) 

Procedure CopyFiles() 

  AddGadgetItem(editList, 0, "Copying") 

  ;various lines of checking And copying code 

EndProcedure 

CopyFiles() 

Repeat:Until WaitWindowEvent()=#WM_CLOSE


Posted: Thu Mar 15, 2007 12:17 pm
by orb_505
Actually, after I specific the Gadget as Global is DOES work but only at the end of the procedure, I'm guessing the form isn't refreshed until the end of the procedure?

If I set the form as Global and call a refresh in the procedure than I'm guessing that'll work?

Posted: Thu Mar 15, 2007 12:19 pm
by gnozal
Works here :

Code: Select all

frmMain = OpenWindow(1,100,100,400,265,"PMR Data Retriver " + Version$,#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered) And CreateGadgetList(WindowID(1)) 

editList = EditorGadget(#PB_Any, 10, 100, 380, 150, #PB_Editor_ReadOnly) 

Procedure CopyFiles() 
  
  Shared editList
  
  AddGadgetItem(editList, 0, "Copying") 
  
  ;various lines of checking And copying code 
  
EndProcedure 

CopyFiles()

Repeat
  Event = WaitWindowEvent()
  If Event = #PB_Event_CloseWindow
    Break
  EndIf
ForEver
Maybe you have to add

Code: Select all

While WindowEvent() : Wend
after AddGadgetItem(), so your listicon is updated in your real code.

Posted: Thu Mar 15, 2007 12:31 pm
by Derek
gnozal wrote:Maybe you have to add

Code: Select all

While WindowEvent() : Wend
after AddGadgetItem(), so your listicon is updated in your real code.

Code: Select all

frmMain = OpenWindow(1,100,100,400,265,"PMR Data Retriver " + Version$,#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered) And CreateGadgetList(WindowID(1))

editList = EditorGadget(#PB_Any, 10, 100, 380, 150, #PB_Editor_ReadOnly)

Procedure CopyFiles()

  Shared editList

  For n=1 To 10
    AddGadgetItem(editList, 0, "Copying")
    While WindowEvent() : Wend
      Delay(1000)
    Next

    ;various lines of checking And copying code

  EndProcedure

  CopyFiles()

  Repeat
    Event = WaitWindowEvent()
    If Event = #PB_Event_CloseWindow
      Break
    EndIf
  ForEver
Yep, updates here whenever you add to the gadget.

Posted: Thu Mar 15, 2007 12:34 pm
by orb_505
I've tried the Globel and Shared route (thanks for that guys) and they do work but only after the procedure has finished. As the files being copied are large than there is about 60-120sec's while the files are copying and nothing is on the screen, the user thinks "wtf?? Is it doing anything?"

I have got an Event loop, sorry I didn't post it in the general jist.

Code: Select all

frmMain = OpenWindow(1,100,100,400,265,"PMR Data Retriver " + version,#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)  And CreateGadgetList(WindowID(1))

cmdStart = ButtonGadget(#PB_Any, 10, 70, 40, 20, "Start")

Global editList = EditorGadget(#PB_Any, 10, 100, 380, 150, #PB_Editor_ReadOnly)

Procedure CopyFiles()

  AddGadgetItem(editList, 0, "Copying")

  various copying code

EndProcedure

Repeat
  Event = WaitWindowEvent()
  Select Event
    Case #PB_Event_Gadget
    Select EventGadget()
      Case cmdStart
        CopyFiles()

Various other Case looking for other Gadgets

   EndSelect
  EndSelect
Until Event = #PB_Event_CloseWindow

Probably not the most elequant way to approch it but like I say it's my first GUI outting :oops:

Posted: Thu Mar 15, 2007 12:40 pm
by netmaestro
If you want a progress bar to be updated while the copy operation is happening, there are a couple of ways to accomplish it. The best is using CopyFileEx_ with a progress callback, you can read on MSDN how to implement that. But either that or a thread that monitors the amount of data copied is what you need as the progress must be monitored asynchronously.

Posted: Thu Mar 15, 2007 1:59 pm
by orb_505
Still trying on this, I looked at the thread route but I've now discovered I'll have to send at least 2 paramenters to the CopyFile() procedure plus get a return. Looking in the help threads don't support this.

The AddGadgetItem() is now working now the gadget is Global but it's only showing on the gadget after the procedure has completed and returns to the main Event loop.

Not sure how to use this CopyFileEx you mentioned.

Posted: Thu Mar 15, 2007 2:26 pm
by Derek
Have you tried the last post of mine above, as gnozal said, adding a windowevent seems to update the gadget straight away. Works in the code posted above.

Posted: Thu Mar 15, 2007 2:58 pm
by orb_505
Sorry Derek, I missed you post in the cross fire, yes just tried that and worked a treat!

Cheers all!