<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <br>
    <div class="moz-cite-prefix">Le 25/10/2012 13:07, Bernd a écrit :<br>
      very nice indeed and readable even on pseudo-code, but ...<br>
    </div>
    <blockquote
cite="mid:CAAkg2-kaYYOQKFM8__xaKq2WR=wcutQYGMhn+=CJfF2Y4KRmkQ@mail.gmail.com"
      type="cite">
      <pre wrap="">
Here is an alternative way to implement it (this one can even reply
and have a conversation of multiple commands going forth an back
between the client and server):

pocedure OnEverythingGetsStarted;
begin
   if State = WAITING then exit;
   State := WAITING
   maybe also disable some buttons that might interfere
   open the connection
   send the request
   start the timeout timer
   // return from that event</pre>
    </blockquote>
    this is exactly what I have to avoid: user gains control on screen.
    A workaround is to disable the window itself. But then another timer
    is needed to ensure that whatever happens or NOTHING happens,
    control will return  back to the starting point.<br>
    Furthermore, all requests coded until now have to be moved outside
    of the procedures or events holding them: a lot of work<br>
    What if:<br>
    <pre wrap="">pocedure OnEverythingGetsStarted;
<big><big><b><small>var
  AHandles: PWOHandleArray;</small></b>
</big></big><b>  </b><b><big>Res: DWORD;</big></b>
begin
   if State = WAITING then exit;
   State := WAITING
   maybe also disable some buttons that might interfere
   open the connection
   Event.ResetEvent;  // not signaled
   send the request
   start the timeout timer
   
   AHandles[0] := Timer.Handle;
   AHandles[1] := Event.Handle; // posted by the OnReceive
 event
   Res:=WaitForMultipleObjects(2, @AHandles, False, Timeout);
   // wait for first reset, not interested for all
   case Res of
     ... continue processing depending of the answer or no answer
   end;
end;
</pre>
    <blockquote
cite="mid:CAAkg2-kaYYOQKFM8__xaKq2WR=wcutQYGMhn+=CJfF2Y4KRmkQ@mail.gmail.com"
      type="cite">
      <pre wrap="">
end;

procedure OnTimer;
begin
  if State = WAITING then begin
    Disconnect
    State := IDLE</pre>
    </blockquote>
                Timer.enabled := False;<br>
    <blockquote
cite="mid:CAAkg2-kaYYOQKFM8__xaKq2WR=wcutQYGMhn+=CJfF2Y4KRmkQ@mail.gmail.com"
      type="cite">
      <pre wrap="">
    enable the disabled buttons
  end;
end;

procedure OnReceive(S: TLSocket);
begin
  Answer := S.GetMessage()</pre>
    </blockquote>
    forget about the rest of the procedure and do instead:<br>
            DoWhatEverBeforeProcessData(Answer);<br>
            Event.SetEvent;    // event signaled<br>
    <blockquote
cite="mid:CAAkg2-kaYYOQKFM8__xaKq2WR=wcutQYGMhn+=CJfF2Y4KRmkQ@mail.gmail.com"
      type="cite">
      <pre wrap="">
  case Answer of
  'foo': begin
     DoThis();
     SendAnotherCommand();
  end
  'bar': begin
     DoThat();
     SendSomeThingDifferent();
  end</pre>
    </blockquote>
            .. I have dozens of messages to process in the internal
    protocol<br>
    <blockquote
cite="mid:CAAkg2-kaYYOQKFM8__xaKq2WR=wcutQYGMhn+=CJfF2Y4KRmkQ@mail.gmail.com"
      type="cite">
      <pre wrap="">
  else begin
     DoWhateverNeedsToBeDone();
     S.Disconnect;
     State := IDLE;
     enable the disabled buttons
  end;
end;

This will never block and never freeze and never eat any unneeded CPU
cycles and it is les code than messing around with the eventers and
CallAction directly and also less code than low level programming
against sockets and/or winsock2 directly.</pre>
    </blockquote>
    Anyway, I can agree with this above.<br>
    But the application has to be re-engineered.<br>
    <br>
    <blockquote
cite="mid:CAAkg2-kaYYOQKFM8__xaKq2WR=wcutQYGMhn+=CJfF2Y4KRmkQ@mail.gmail.com"
      type="cite">
      <pre wrap="">
</pre>
    </blockquote>
    <br>
  </body>
</html>