2

I'm programing one network application in delphi 6 using TTCPServer. At OnAccept event of this component I call showmodal for another form. This cause to hang the main form. I think that it is because of threads but I do not know how to showmodal the form at this event. I really have to call that. I appreciate any answer. thanks.

var
  s: array[0..10000] of byte;
  i, j: integer;
  Str : String;
  Request, UN, Pass: WideString;
  StartItemNode : IXMLNode;
  st: TStringStream;
begin
  CoInitialize(nil);

  i := ClientSocket.ReceiveBuf(s, 10000, 0);

  Str := '';
  for j := 0 to i - 1 do
    Str := Str + AnsiChar(s[j]);

  XMLDoc.XML.Text := Str;
  XMLDoc.Active := true;
  StartItemNode := XMLDoc.ChildNodes.FindNode('r');
  Request := StartItemNode.ChildNodes['request'].Text;

  if(Request = 'Order')then
  begin
    Memo1.Lines.Text := Str;
    ClientSocket.Sendln('<?xml version="1.0" encoding="utf-8"?><r><answer result="OK"></answer></r>');

    **Form2.ShowModal;**
  end;
Ken White
  • 123,280
  • 14
  • 225
  • 444
hamid
  • 852
  • 11
  • 27
  • 4
    You need to run the GUI on the GUI thread. If this code runs in a background thread then it will fail. Use `TThread.Synchronize` to force the `ShowModal` onto the GUI thread. That gives synchronous operation. If you need the UI to be asynchronous, use `PostMessage` with a private windows message code to show the UI. – David Heffernan Mar 27 '12 at 10:03
  • I've never tried TThread.Synchronize, (ugh!), with a modal form, (well, TBH, I haven't tried it with anything since D3). I wonder if it returns before the user clicks to set modalResult? Perhaps I will try it later, just to see... – Martin James Mar 27 '12 at 15:11
  • Yup, sure enough, Synchronize does not return until the modal form is closed, so preventing the OnAccept handler from exiting. I'm guessing that the server will not accept any more connections until that handler exits. – Martin James Mar 27 '12 at 15:30
  • 1
    @MartinJames Synchronize is, well, synchronous. It returns when the method returns. Not before. – David Heffernan Mar 27 '12 at 17:15
  • 2
    @MartinJames: when the `OnAccept` event fires, a connection has already been accepted, and will be closed when the event handler exits. If the server's `BlockMode` property is set to `bmThreadBlocking`, the `OnAccept` events occur in their own individual threads, so the server can process multiple connections even if one of them is blocked. – Remy Lebeau Mar 27 '12 at 21:30
  • OK, thanks Remy. I guess it's called just before the OnExecute loop. – Martin James Mar 30 '12 at 17:23

1 Answers1

0

Finally find the answer. with Indy component we can use TidSync or TidNotify. Create it and the call the Synchronize method of then with parameter of a method. this method with run at main thread(UI) and it is thread safe. I can not find any solution for TTCPServer but we can use Timer. Set its Interval to for example 100 and do your showmodal at tick of that. but do not forgot about more than one running at same time. for example at OnTimer you have to disable recieving new connections or save them in array to process next OnTimer event.

hamid
  • 852
  • 11
  • 27