Hi,

using old pure C, I was able to define a custom windows message. Once done, it was possible to broadcast the message across my application. Any object, with defined listener was able to receive and process the message. OK, right now, I need to do the same in C#. I have a class (let’s call it ABC), which should broadcast a message in case something happens. The application has multiple forms (some of the are active, some of them not - that’s why I need general broadcast message/event instead of call a specific method). In case, something happens (e.g. ABC finishes some calculation), I want ABC to send a broadcast message (by broadcast I mean, the ABC class doesn’t know, who will receive it). The message will be processed by all active forms with defined listener. Please, could you let me know, how to send the message and how to define the listeners?

Marek

Recommended Answers

All 6 Replies

Hi,

thanks, the article looks great! Thanks a lot, I am going to study :-).

M.

So I went through the arcticle and it looks like something different. My understanding is, a receiver has to know the instance of the sender as it has to subscribe to the event receiving. And that's my problem - I want to send a broadcast. It means to me - the classes doesn't know each other. Here is the example - the sender raises event ID #1234. It's passed to all existing listeners within the application. In case, they have implemented its receiveing like if(event.id == 1234) then ..., they will process the event.

See if this article meets your needs: alternative to .NET Remoting based on low-level Windows Messaging...

In the above link (and code excerpts below):

  • the author uses the WM_COPYDATA message to broadcast and listen, but you should be able to define WM_USER +0x?? if that is your wish; but, he also forwards the message on (in WndProc) to other windows...
  • the author creates a hidden window when the listener object is invoked, which receives the window's messages via override of the window's WndProc...
  • the author uses a filter when enumerating the desktop windows, but you should be able to enumerate ALL open windows...

Excerpt showing SendMessage code:

// Use a filter with the EnumWindows class to get a list of windows containing
            // a property name that matches the destination channel. These are the listening
            // applications.
            WindowEnumFilter filter = new WindowEnumFilter(XDListener.GetChannelKey(channel));
            WindowsEnum winEnum = new WindowsEnum(filter.WindowFilterHandler);
            foreach (IntPtr hWnd in winEnum.Enumerate(Win32.GetDesktopWindow()))
            {
                IntPtr outPtr = IntPtr.Zero;
                // For each listening window, send the message data. Return if hang or unresponsive within 1 sec.
                Win32.SendMessageTimeout(hWnd, Win32.WM_COPYDATA, (int)IntPtr.Zero, ref dataStruct, Win32.SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 1000, out outPtr);
            }

Excerpt of listener (WndProc override) code:

/// The native window message filter used to catch our custom WM_COPYDATA
        /// messages containing cross AppDomain messages. All other messages are ignored.
        /// </summary>
        /// <param name="msg">A representation of the native Windows Message.</param>
        protected override void WndProc(ref Message msg)
        {
            base.WndProc(ref msg);
            if (msg.Msg == Win32.WM_COPYDATA)
            {
                if (MessageReceived == null) return;
                DataGram dataGram = DataGram.FromPointer(msg.LParam);
                MessageReceived(this, new XDMessageEventArgs(dataGram));
            }
        }

Thanks a lot guys, finally solved!!!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.