April 23, 2024, 12:51:41 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Why won't this code produce a delay in the manner intended?

Started by AdrianFox, January 03, 2009, 09:39:22 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

AdrianFox

Hi there, and 'bonne annÃÆ'Ã,©ÃÆ'Ã,©.

Can anyone tell me why this code will not work as intended?  I've declared a 'Sleep' constant using Kernel-32.  It works ok  as a simple delay of the defined number of milliseconds.

However, I'm simply trying to print text to the edit box in 'teleprinter' mode, with one character appearing in turn with a delay of say half a second between each one.  But in the following code, the delay occurs before anything changes and then the text is printed altogether.  I can't understand why this should be so when the 'sleep(300)' code is within my x, next x loop and as far as I can see each letter should appear on screen in sequence, with the delay occurring between each 'setcontroltext' command.

Can anyone see why this will not work with this code?

Alternatively, is there a simpler way of achieving want I want to do.  ( I must admit I have been having problems trying to achieve this with the Starttimer and Stoptimer  commands despite looking at the help files and various examples in the Forums.)

Forgive me if I'm doing something very stupid!

CONST EDIT_2 = 2
CONST DIK_F10 = 0x44
const button_3=3
'this declaration works to put in a 'sleep' command for delays
DECLARE "kernel32",Sleep(dwMilliseconds:INT)
def y$,t$ as STRING

DIALOG d1
CREATEDIALOG d1,0,0,300,202,0x80C80080,0,"Printing letters in sequence with delay",&d1_handler
CONTROL d1,@EDIT,"Initial message",21,22,220,47,0x50800000,EDIT_2
control d1,@button,"Press",200,150,100,20,0,button_3
domodal d1


SUB d1_handler
SELECT @MESSAGE
CASE @IDINITDIALOG
CENTERWINDOW d1
/* Initialize any controls here */
CASE @IDCLOSEWINDOW
CLOSEDIALOG d1,@IDOK
CASE @IDCONTROL
SELECT @CONTROLID
CASE EDIT_2
/* respond to edit notifications here */

Case button_3
if @notifycode=0
gosub newtext
endif

ENDSELECT
ENDSELECT
RETURN
ENDSUB
sub newtext
       
for x= 1 to 6
getdata myletters,y$
setcontroltext d1,2,t$+y$
t$=t$+y$
sleep(300)
next x
restore myletters
RETURN
endsub



databegin myletters
data "B","E","R","T","I","E",""
dataend


Adrian Fox

Ionic Wind Support Team

I'll answer the first half of your question first ;).

Windows is message based.  SetControlText sends a message to your control which it won't receive until after you've given up control back to windows, meaning the handler returns.

Think of it this way.  Messages exist in a queue, like a stack of dishes in a buffet line.  Your DoModal command activate a message processing loop like this:

do
  Get a message (dish) from the queue (bottom of stack)
  Send it to where it belongs
until done

So when you click button 3, Windows (the OS) Puts a message in the queue (puts a dish on top of the stack).  Eventually that DoModal loop gets to your message.


  Gets the button click message from the queue
  Gosub d1_handler


Now your d1_handler in processing the button click message is doing essentially this:

for x=1 to 6
   Put a message in the queue (set control text)
   sleep(300)
next x

After the for loop ends you are returning control back to the loop created by DoModal.

   Gets a message from the queue (set control text)
   Sends it to the edit control

And it would loop 6 times sending those setcontroltext messages at once to the edit control.

---------------------------------------------------------------------------------

Now as to the second part of your question.  There are a number of ways to do it, After the setcontroltext insert the command WAIT 1 WAIT 1 processes any pending messages, such as your SETCONTROLTEXT message and then returns .  It is the easiest way to make it work, but not the most reliable or correct.  There could be other messages in that queue besides your setcontroltext message, which can cause you headaches in a larger program.  In this little program it shouldn't cause any problems though.

Using a timer would be more correct.  It would be interesting to see how far you got with using a timer, but I would handle the response to @IDTIMER like so...

string display$
....
case @idcontrol
   if @controlid = button1
       if display$ = ""
           display$ = "BERTIE"
           SetControlText d1,2,""
           StartTimer win,300
      endif
  endif

case @idtimer
   string nextchar = display$[0]
   display$ = mid$(display$,2)
   SetControlText(d1,2,GetControlText(d1,2)+nextchar)
   if display$ = "" then stoptimer win

This is a more windows friendly way of doing it.  Sleep has its uses, but you need to understand exactly what it does before using it.  Sleep tells windows not to execute any code in your process for xxx millisecs.  So if you were using a timer somewhere else in your program, and the sleep time was longer than the timer duration, your handler would miss a timer message or more, and it would make your program non responsive for that amount of time.

Sleep can also affect other running processes.  It is common for programs to send "broadcast" messages, messages that are sent to every window on the system, if your process is sleeping the OS executive will wait indefinitely for it to wake up and process that broadcast message.

http://msdn.microsoft.com/en-us/library/ms686298.aspx

Later,
Paul.
Ionic Wind Support Team

AdrianFox

 :)  Thanks very much, Paul.

As usual you explain everything extremely clearly as well as providing code that will do what I need.  This is enormously helpful to novice programmers like myself.  (It's just as important to understand completely why something won't and can't work as to simply use code that will do the job.)

Really appreciate the advice and help.

(The snippet is just part of the code I wanted to use to completely re-do (and improve) a program about Chaucer's 'Wife of Bath' Tale. I originally programmed this in Liberty Basic while I was still teaching, but realise now how much better it could be in EB.  I will then put it as freeware on various English Literature sites.)

Thanks again for your help, and have a really good 2009.

Adrian
Adrian Fox