Пример #1
0
        /// <summary>
        /// Override for a form's Window Procedure to handle WM_COPYDATA
        /// messages sent by other instances of this class.
        /// </summary>
        /// <param name="m">The Windows Message information.</param>
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_COPYDATA)
            {
                var cds = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
                if (cds.cbData > 0)
                {
                    byte[] data = new byte[cds.cbData];
                    Marshal.Copy(cds.lpData, data, 0, cds.cbData);
                    MemoryStream       stream = new MemoryStream(data);
                    BinaryFormatter    b      = new BinaryFormatter();
                    CopyDataObjectData cdo    = (CopyDataObjectData)b.Deserialize(stream);

                    if (_channels != null && _channels.Contains(cdo.Channel))
                    {
                        CopyDataReceivedEventArgs d = new CopyDataReceivedEventArgs(cdo.Channel, cdo.Data, cdo.Sent);
                        OnCopyDataReceived(d);
                        m.Result = (IntPtr)1;
                    }
                }
            }
            else if (m.Msg == WM_DESTROY)
            {
                // WM_DESTROY fires before OnHandleChanged and is
                // a better place to ensure that we've cleared
                // everything up.
                _channels?.OnHandleChange();
                base.OnHandleChange();
            }
            base.WndProc(ref m);
        }
Пример #2
0
        /// <summary>
        /// Sends the specified object on this channel to any other
        /// applications which are listening.  The object must have the
        /// SerializableAttribute set, or must implement ISerializable.
        /// </summary>
        /// <param name="obj">The object to send</param>
        /// <returns>The number of recipients</returns>
        public int Send(object obj)
        {
            int recipients = 0;

            if (disposed) {
                throw new InvalidOperationException("Object has been disposed");
            }

            if (recreateChannel) {
                // handle has changed
                addChannel();
            }

            CopyDataObjectData cdo = new CopyDataObjectData(obj, channelName);

            // Try to do a binary serialization on obj.
            // This will throw and exception if the object to
            // be passed isn't serializable.
            BinaryFormatter b = new BinaryFormatter();
            MemoryStream stream = new MemoryStream();
            b.Serialize(stream, cdo);
            stream.Flush();

            // Now move the data into a pointer so we can send
            // it using WM_COPYDATA:
            // Get the length of the data:
            int dataSize = (int)stream.Length;
            if (dataSize > 0) {
                // This isn't very efficient if your data is very large.
                // First we copy to a byte array, then copy to a CoTask
                // Mem object... And when we use WM_COPYDATA windows will
                // make yet another copy!  But if you're talking about 4K
                // or less of data then it doesn't really matter.
                byte[] data = new byte[dataSize];
                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(data, 0, dataSize);
                IntPtr ptrData = Marshal.AllocCoTaskMem(dataSize);
                Marshal.Copy(data, 0, ptrData, dataSize);

                // Send the data to each window identified on
                // the channel:
                foreach(WindowDetails window in WindowDetails.GetAllWindows()) {
                    if (!window.Handle.Equals(this.owner.Handle)) {
                        if (GetProp(window.Handle, this.channelName) != 0) {
                            COPYDATASTRUCT cds = new COPYDATASTRUCT();
                            cds.cbData = dataSize;
                            cds.dwData = IntPtr.Zero;
                            cds.lpData = ptrData;
                            int res = SendMessage(window.Handle, WM_COPYDATA, (int)owner.Handle, ref cds);
                            recipients += (Marshal.GetLastWin32Error() == 0 ? 1 : 0);
                        }
                    }
                }

                // Clear up the data:
                Marshal.FreeCoTaskMem(ptrData);
            }
            stream.Close();

            return recipients;
        }
Пример #3
0
        /// <summary>
        /// Sends the specified object on this channel to any other
        /// applications which are listening.  The object must have the
        /// SerializableAttribute set, or must implement ISerializable.
        /// </summary>
        /// <param name="obj">The object to send</param>
        /// <returns>The number of recipients</returns>
        public int Send(object obj)
        {
            int recipients = 0;

            if (_recreateChannel)
            {
                // handle has changed
                AddChannel();
            }

            CopyDataObjectData cdo = new CopyDataObjectData(obj, ChannelName);


            // Try to do a binary serialization on obj.
            // This will throw and exception if the object to
            // be passed isn't serializable.
            BinaryFormatter b      = new BinaryFormatter();
            MemoryStream    stream = new MemoryStream();

            b.Serialize(stream, cdo);
            stream.Flush();

            // Now move the data into a pointer so we can send
            // it using WM_COPYDATA:
            // Get the length of the data:
            int dataSize = (int)stream.Length;

            if (dataSize > 0)
            {
                // This isn't very efficient if your data is very large.
                // First we copy to a byte array, then copy to a CoTask
                // Mem object... And when we use WM_COPYDATA windows will
                // make yet another copy!  But if you're talking about 4K
                // or less of data then it doesn't really matter.
                byte[] data = new byte[dataSize];
                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(data, 0, dataSize);
                IntPtr ptrData = Marshal.AllocCoTaskMem(dataSize);
                Marshal.Copy(data, 0, ptrData, dataSize);

                // Send the data to each window identified on
                // the channel:
                foreach (WindowDetails window in WindowDetails.GetAllWindows())
                {
                    if (!window.Handle.Equals(_owner.Handle))
                    {
                        if (GetProp(window.Handle, ChannelName) != IntPtr.Zero)
                        {
                            COPYDATASTRUCT cds = new COPYDATASTRUCT
                            {
                                cbData = dataSize,
                                dwData = IntPtr.Zero,
                                lpData = ptrData
                            };
                            SendMessage(window.Handle, WM_COPYDATA, _owner.Handle, ref cds);
                            recipients += Marshal.GetLastWin32Error() == 0 ? 1 : 0;
                        }
                    }
                }

                // Clear up the data:
                Marshal.FreeCoTaskMem(ptrData);
            }
            stream.Close();

            return(recipients);
        }