Re: Message Loops and Application.Run() by Michael
Michael
Mon Feb 07 14:29:28 CST 2005
"Steve" <Steve@discussions.microsoft.com> wrote in message
news:0CD3976B-61B6-49F5-9248-760F77050D1A@microsoft.com...
>
>
> "Wiktor Zychla" wrote:
>
> > > Now, how do I actually send messages to the
> > > message loop since there's no window defined on that thread?
> > > There must be a way since the MSDN doc for Application.Run()
> > > states: "Begins running a standard application message loop on the
current
> > > thread, without a form." I looked at the System.Messaging namespace
> > > but I'm not even sure if MSMQ is the same thing as an Application
> > > Message loop.
> >
> > what kind of messages would you like to send to the message loop without
a
> > window?
> >
> > [btw. msmq is not the same thing as appliaction message loop]
> >
> > Wiktor Zychla
> >
>
> Well, I'm calling a vendor API that requires calls to be made on a thread
> with a message loop. But the DLL I'm writing is being called from an
> application that spawns a new thread w/o a message loop. So, right now,
I'm
> creating a hidden window and then calling Application.Run(HiddenForm) in a
> new thread. Then whenever my parent application calls my DLL, I can use
> HiddenForm.Invoke to run the vendor function which guarentees it will be
> running in a thread that has a message loop.
>
> Having a form (hidden or not) doesn't seem like the most efficient or
> elegant solution. I was hoping to (1) Create a new thread, (2)define a
> message handler using Application.AddMessageFilter, (3) call
> Application.Run() on the new thread which creates an Application message
> loop, and finally (4) Put messages on that loop which basically equates to
> "call function X" or "call function Y".... same thing as using
> Control.Invoke() only without the hidden form.
>
> Do I have to use a Win32 API call to send a message? Is that possible
> without a Window handle?
> Is there any better doc out there for Windows messaging?
> I couldn't find anything on MSDN.
>
> Thanks!!!
> Steve
>
I'm not sure if using the message pump to pass data to your thread is the
best way. I guess it depends on how the callbacks are initiated from the
vendor API. I have a similar situation where the vendor API is a COM server
component that does callbacks via Connection Point events. What I did was:
1) Created a class that inherits from System.Windows.Forms.Control. This
will allow you to create a control with a window handle, which is required
in order to have a Message Pump.
2) Create a thread from your main GUI thread. In the startup method of the
thread, instantiate the control. Then, create the window handle for the
control using the CreateControl method.
3) Call Application.Run() in the startup method of step #2. This will keep
the spawned thread alive. The control can now be used to accept Connection
Point callbacks from COM objects created and owned by the user control.
It is important that any calls from the main GUI thread to the user control
and vice-versa be wrapped in Invoke or BeginInvoke statements. This will
prevent certain odd multi-threading issues. What I did was pass a reference
of the owner control to the created user control, and then use the owner
control reference to issue Invoke callbacks. You need to be careful about
simply using Invoke instead of BeginInvoke, as it opens you up to potential
thread Deadlock issues. For example, if your main GUI thread uses Invoke to
call into your User control, and then your user control calls Invoke to
return an Exception to your main GUI thread, a thread deadlock will occur.
There is no simple answer for when it is best to use Invoke vs.
BeginInvoke...it depends on your application requirements.
Regards,
MP