Indy 10 TCP Server, Creating a form in OnExecute.

I'm using Indy 10 with Delphi 2007.  I have a program with a TIdTCPClient which connects and sends a string to another program that has a TIdTCPServer, and then immediately disconnects.  The OnExecute event of the server parses the string and, depending on the contents of the string, may call a method which creates a new form.  This server also has a UDPServer which can listen for a UDP broadcast of this same string, and if it's found, will call that same method. However, the end result of the calls is di
fferent.  

If called by the UDPServer method, the child form is created, and I can move it to the side and continue working on my main form.  Both are interactive, and this is the desired behavior.  More calls can add more child forms, and they're all interactive, as well as the main form.  

If called by the TCPServer method, I'll see the child form for a brief instant before it disappears.  When I go to close my program, I get an exception when it attempts to free the child form (I keep a TList of any created child forms), EOSError 1400 - Invalid window handle.  I don't see where it could be trying to minimize or hide, and it's not being destroyed (doesn't go through the destructor).  

Just for kicks, I put the same child-form-creation method call into a timer that I enabled when I otherwise would call that function in the TCPServer execute (I commented out the method call within the execute).  With that, the child forms are created, stay on the desktop, and I can interact with them.  However, the main application form stops being interactive (any mouseclicks just get the Windows 'You can't do that' sound).  

Unfortunately, there's quite a bit of code that would need to be copied to show exactly what I'm doing, but is there any direction in which I should be looking?  

Thank you.
0
Steve
5/19/2010 4:26:52 AM
📁 embarcadero.delphi.winsock
📃 1874 articles.
⭐ 2 followers.

💬 2 Replies
👁️‍🗨️ 1754 Views

<Steve Shanbaum> wrote in message news:[email protected]
> The OnExecute event of the server parses the string and, depending
> on the contents of the string, may call a method which creates a new form.

Creating and using a VCL TForm needs to be sychronized with the main thread. 
It cannot be done in the TIdTCPServer thread directly.

> This server also has a UDPServer which can listen for a UDP broadcast
> of this same string, and if it's found, will call that same method. 
> However,
> the end result of the calls is different.

The TIdUDPServer.ThreadedEvent property is False by default, so the 
OnUDPRead event handler is automatically synchronized with the main thread. 
With TIdTCPServer, you have to do the synchronization manually, such as with 
the TIdSync and TIdNotify classes.

> Just for kicks, I put the same child-form-creation method call into a 
> timer
> that I enabled when I otherwise would call that function in the TCPServer
 execute (I commented out the method call within the execute).

Like other VCL UI components, TTimer is not thread-safe.  It needs to be 
used only in the main thread as well.

-- 
Remy Lebeau (TeamB)
0
Remy
5/19/2010 7:08:11 AM
> {quote:title=Remy Lebeau (TeamB) wrote:}{quote}
> <Steve Shanbaum> wrote in message news:[email protected]
> > The OnExecute event of the server parses the string and, depending
> > on the contents of the string, may call a method which creates a new form.
> 
> Creating and using a VCL TForm needs to be sychronized with the main thread. 
> It cannot be done in the TIdTCPServer thread directly.
> With TIdTCPServer, you have to do the synchronization manually, such as with 
> the TIdSync and TIdNotify classes.
> 
> Remy Lebeau (TeamB)

Thank you - making use of TIdSync cleared this right up.
0
Steve
5/19/2010 12:31:19 PM
Reply:
(Thread closed)