===>> Is there a function like DoEvents in Visual Basi

Just starting out? Need help? Post your questions and find answers here.
goomoo
User
User
Posts: 42
Joined: Sun Dec 05, 2004 9:25 am
Location: China
Contact:

===>> Is there a function like DoEvents in Visual Basi

Post by goomoo »

Hello,everyone.

I want to read a large number of strings to a treegadget from a text file in a WHILE loop,This operation will take a long time, during this, the gadgets and window cannot response user's operation, so I think there should be some funcion like DoEvents in VB or Application.ProcessMessages in Delphi , Is there anyone in PureBasic, or Can I have an alternate solution?

Thanks! :D
Hello, Everyone.
Thanks for your help.
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

Delay(#)
goomoo
User
User
Posts: 42
Joined: Sun Dec 05, 2004 9:25 am
Location: China
Contact:

Post by goomoo »

Shannara, thanks for your reply.

The Delay() subroutine sleeps current thread only, it cannot process window messages. For an example:

Code: Select all

OpenWindow(1,0,0,320,240,#PB_Window_ScreenCentered|#PB_Window_SystemMenu,"asdf")
CreateGadgetList(WindowID())
ButtonGadget(1,5,5,300,25,"After Click me, Move the window")

Repeat
  event.l=WaitWindowEvent()
  If event=#PB_Event_Gadget
    Delay(5000)
  EndIf
  
Until event=#PB_Event_CloseWindow
when you click the button, the window can't be moved in 5 seconds.[/code]
Hello, Everyone.
Thanks for your help.
Beach
Enthusiast
Enthusiast
Posts: 677
Joined: Mon Feb 02, 2004 3:16 am
Location: Beyond the sun...

Post by Beach »

I would also like to know a good way to do this. Currently, I use the 'CreateThread' function if I need something going on in the background.
goomoo
User
User
Posts: 42
Joined: Sun Dec 05, 2004 9:25 am
Location: China
Contact:

Post by goomoo »

CreateThread() works well at most situations, but using multi-threads to modify user interface can easily cause access conflict.
Hello, Everyone.
Thanks for your help.
LarsG
Enthusiast
Enthusiast
Posts: 713
Joined: Mon Jun 02, 2003 1:06 pm
Location: Norway
Contact:

Post by LarsG »

Perhaps putting a WindowEvent() in the while loop?

AMD Athlon XP2400, 512 MB RAM, Hercules 3D Prophet 9600 256MB RAM, WinXP
PIII 800MHz, 320 MB RAM, Nvidia Riva Tnt 2 Mach 64 (32MB), WinXP + Linux
17" iMac, 1.8 GHz G5, 512 MB DDR-RAM, 80 GB HD, 64 MB Geforce FX 5200, SuperDrive, OSX
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

i would put the reading file part in a thread.
User avatar
einander
Enthusiast
Enthusiast
Posts: 744
Joined: Thu Jun 26, 2003 2:09 am
Location: Spain (Galicia)

Post by einander »

Or you can try with a CallBack

Code: Select all

Procedure ReadTree()
  Static count
  count$="Reading Tree : "+Str(count)
  TextOut_(GetDC_(WindowID()),10,10,count$,Len(count$)) 
  count+1
EndProcedure


Procedure Callback(Win, Msg, wParam, lParam) 
   result = #PB_ProcessPureBasicEvents 
   Select Msg 
   Case #PB_Event_CloseWindow:End
    ; here you can process other messages
    EndSelect 
  ProcedureReturn result 
EndProcedure 

hWnd = OpenWindow(0,0,0,800,80,#PB_Window_SystemMenu|#PB_Window_ScreenCentered, "Test") 
    CreateGadgetList(hWnd) 
   TextGadget(0, 200, 6, 200, 20, "")
      
SetWindowCallback(@Callback()) 
Repeat 
      If WindowEvent() = 0 
        Readtree()
        SetGadgetText(0, "Window mouse position: "+Str(WindowMouseX())+","+Str(WindowMouseY()))
        Delay(20)
      EndIf
  ForEver   
 
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> Perhaps putting a WindowEvent() in the while loop?

Yes, this is the PureBasic equivalent of VB's "DoEvents" command. Try it! :)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

This one also works :

Code: Select all

Procedure DoEvents() 
    msg.MSG 
    If PeekMessage_(msg,0,0,0,1) 
      TranslateMessage_(msg) 
      DispatchMessage_(msg) 
    Else 
      Delay(1) 
    EndIf 
EndProcedure
Call DoEvents() in your loop to update your gagdets.
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
Beach
Enthusiast
Enthusiast
Posts: 677
Joined: Mon Feb 02, 2004 3:16 am
Location: Beyond the sun...

Post by Beach »

Doooode, thanks Gonzal! 8)
-Beach
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

The code by gnozal does the exact same thing that WindowEvent() does.
(except for the delay, and WindowEvent() handles shortcuts too)

It is recommended to call WindowEvent() in a loop until it returns 0.
This way you make sure all redraw events get processed as quickly as possible.
the code by gnozal does process only one event per DoEvents() call, which, depending
on what you do between those calls can still lead to an unresponsive gui.

Also the Delay(1) is not a good choise. As long as your program is still working on something
in a loop, it makes no sense to slow that down with a delay.
The Delay makes only sense where your app has actually nothing to do at the moment
and you want to avoid using 100% cpu.)

Short Version:

Code: Select all

Procedure DoEvents()
  While WindowEvent(): Wend
EndProcedure
This makes sure any waiting events are processed, so the gui is redrawn correctly.
However, you must notice that this discards any user events like button clicks and such
too. So i suggest before entering the loop you are in to use DisableGadget() to disable
any buttons, so tha user knows that clicking them has no effect, and enable them again
when entering the main loop again.
Otherwise the user might wonder why your program is not reacting to his input.

If you have lets say an "Abort" button that can stop what you are currently doing,
or any other event you need to check, i recommend this:

Code: Select all

Procedure DoEvents()
  Repeat
    event = WindowEvent()
    ; check for the abort condition here, for example a #PB_Event_Gadget on a button
    ; and set a global variable that will abort the loop
  Until event = 0 ; stop processing when all waiting events are done
EndProcedure
these 2 ways are both 100% crossplatform compatible btw.

It is also recommended to tell the user in some way that your app is busy, especially
if what you are doing takes a little time. This can be done by opening a small "busy"
window, or putting a "processing, please wait..." in the statusbar.
Also a progressbar is always a good choise.

If you don't do that, the user will think that the app hangs if he doesn't know why it is
not responding for some time and believe your app is not well coded.
.. and you don't want that, do you? :wink:

hope that helps a bit...
quidquid Latine dictum sit altum videtur
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

your recommendations are welcome Freak :wink:
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
goomoo
User
User
Posts: 42
Joined: Sun Dec 05, 2004 9:25 am
Location: China
Contact:

Post by goomoo »

I got it.

Thank you , freak.

Thank you all. :)
Hello, Everyone.
Thanks for your help.
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

Thanks freak :)
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
Post Reply