コード例 #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 System.Windows.Forms.Message m)
    {
        if (m.Msg == WM_COPYDATA)
        {
            COPYDATASTRUCT cds = new COPYDATASTRUCT();
            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.Contains(cdo.Channel))
                {
                    DataReceivedEventArgs d = new
                                              DataReceivedEventArgs(cdo.Channel, cdo.Data, cdo.Sent);
                    OnDataReceived(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);

            // Enumerate all windows which have the
            // channel name, send the data to each one
            EnumWindows ew = new EnumWindows();
            ew.GetWindows();

            // Send the data to each window identified on
            // the channel:
            foreach (EnumWindowsItem window in ew.Items)
            {
                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
ファイル: InterCom.cs プロジェクト: BackupTheBerlios/nomp-svn
    /// <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);

            // Enumerate all windows which have the
            // channel name, send the data to each one
            EnumWindows ew = new EnumWindows();
            ew.GetWindows();

            // Send the data to each window identified on
            // the channel:
            foreach(EnumWindowsItem window in ew.Items)
            {
                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;
    }