/// <summary> /// Constructor which creates the data gram from a message and channel name. /// </summary> /// <param name="channel">The channel through which the message will be sent.</param> /// <param name="message">The string message to send.</param> public DataGram(string channel, string message) { this.allocatedMemory = false; this.dataStruct = new Native.COPYDATASTRUCT(); this.channel = channel; this.message = message; }
public void SendToChannel(string channelName, string message) { if (string.IsNullOrEmpty(channelName)) { throw new ArgumentNullException(channelName, "The channel name must be defined"); } if (message == null) { throw new ArgumentNullException(message, "The messsage packet cannot be null"); } if (string.IsNullOrEmpty(channelName)) { throw new ArgumentException("The channel name may not contain the ':' character.", "channelName"); } // create a DataGram instance, and ensure memory is freed using (DataGram dataGram = new DataGram(channelName, message)) { // Allocate the DataGram to a memory address contained in COPYDATASTRUCT Native.COPYDATASTRUCT dataStruct = dataGram.ToStruct(); // 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(channelName)); WindowsEnum winEnum = new WindowsEnum(filter.WindowFilterHandler); foreach (IntPtr hWnd in winEnum.Enumerate()) { IntPtr outPtr = IntPtr.Zero; // For each listening window, send the message data. Return if hang or unresponsive within 1 sec. Native.SendMessageTimeout(hWnd, Native.WM_COPYDATA, IntPtr.Zero, ref dataStruct, Native.SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 1000, out outPtr); } } }
/// <summary> /// Constructor creates an instance of the class from a pointer address, and expands /// the data packet into the originating channel name and message. /// </summary> /// <param name="lpParam">A pointer the a COPYDATASTRUCT containing information required to /// expand the DataGram.</param> private DataGram(IntPtr lpParam) { this.allocatedMemory = false; this.dataStruct = (Native.COPYDATASTRUCT)Marshal.PtrToStructure(lpParam, typeof(Native.COPYDATASTRUCT)); byte[] bytes = new byte[this.dataStruct.cbData]; Marshal.Copy(this.dataStruct.lpData, bytes, 0, this.dataStruct.cbData); string rawmessage; using (MemoryStream stream = new MemoryStream(bytes)) { BinaryFormatter b = new BinaryFormatter(); rawmessage = (string)b.Deserialize(stream); } // use helper method to expand the raw message using (DataGram dataGram = DataGram.ExpandFromRaw(rawmessage)) { this.channel = dataGram.Channel; this.message = dataGram.Message; } }