/// <summary> /// Gets the current DropDescription's drop image type. /// </summary> /// <param name="dataObject">The DataObject.</param> /// <returns>The current drop image type.</returns> private static DropImageType GetDropImageType(IDataObject dataObject) { object data = ComDataObjectExtensions.GetDropDescription((System.Runtime.InteropServices.ComTypes.IDataObject)dataObject); if (data is DropDescription) { return((DropImageType)((DropDescription)data).type); } return(DropImageType.Invalid); }
/// <summary> /// Checks if the current drop description, if any, is valid. /// </summary> /// <param name="dataObject">The DataObject from which to get the drop description.</param> /// <returns>True if the drop description is set, and the /// DropImageType is not DropImageType.Invalid.</returns> private static bool IsDropDescriptionValid(IDataObject dataObject) { object data = ComDataObjectExtensions.GetDropDescription((Runtime.InteropServices.ComTypes.IDataObject)dataObject); if (data is DropDescription) { return((DropImageType)((DropDescription)data).type != DropImageType.Invalid); } return(false); }
/// <summary> /// Handles DataChanged events from a COM IDataObject. /// </summary> /// <param name="format">The data format that had a change.</param> /// <param name="stgmedium">The data value.</param> public void OnDataChange(ref FORMATETC format, ref STGMEDIUM stgmedium) { // We listen to DropDescription changes, so that we can unset the IsDefault // drop description flag. object odd = ComDataObjectExtensions.GetDropDescription((System.Runtime.InteropServices.ComTypes.IDataObject)data); if (odd != null) { SetDropDescriptionIsDefault(data, false); } }
/// <summary> /// Sets managed data to a clipboard DataObject. /// </summary> /// <param name="dataObject">The DataObject to set the data on.</param> /// <param name="format">The clipboard format.</param> /// <param name="data">The data object.</param> /// <remarks> /// Because the underlying data store is not storing managed objects, but /// unmanaged ones, this function provides intelligent conversion, allowing /// you to set unmanaged data into the COM implemented IDataObject.</remarks> public static void SetDataEx(this IDataObject dataObject, string format, object data) { DataFormat dataFormat = DataFormats.GetDataFormat(format); // Initialize the format structure var formatETC = new FORMATETC(); formatETC.cfFormat = (short)dataFormat.Id; formatETC.dwAspect = DVASPECT.DVASPECT_CONTENT; formatETC.lindex = -1; formatETC.ptd = IntPtr.Zero; // Try to discover the TYMED from the format and data TYMED tymed = GetCompatibleTymed(format, data); // If a TYMED was found, we can use the system DataObject // to convert our value for us. if (tymed != TYMED.TYMED_NULL) { formatETC.tymed = tymed; // Set data on an empty DataObject instance var conv = new System.Windows.DataObject(); conv.SetData(format, data, true); // Now retrieve the data, using the COM interface. // This will perform a managed to unmanaged conversion for us. STGMEDIUM medium; ((ComIDataObject)conv).GetData(ref formatETC, out medium); try { // Now set the data on our data object ((ComIDataObject)dataObject).SetData(ref formatETC, ref medium, true); } catch { // On exceptions, release the medium ReleaseStgMedium(ref medium); throw; } } else { // Since we couldn't determine a TYMED, this data // is likely custom managed data, and won't be used // by unmanaged code, so we'll use our custom marshaling // implemented by our COM IDataObject extensions. ComDataObjectExtensions.SetManagedData((ComIDataObject)dataObject, format, data); } }
/// <summary> /// Gets managed data from a clipboard DataObject. /// </summary> /// <param name="dataObject">The DataObject to obtain the data from.</param> /// <param name="format">The format for which to get the data in.</param> /// <returns>The data object instance.</returns> public static object GetDataEx(this IDataObject dataObject, string format) { // Get the data object data = dataObject.GetData(format, true); // If the data is a stream, we'll check to see if it // is stamped by us for custom marshaling if (data is Stream) { object data2 = ComDataObjectExtensions.GetManagedData((ComIDataObject)dataObject, format); if (data2 != null) { return(data2); } } return(data); }
/// <summary> /// Sets the drop description for the drag image manager. /// </summary> /// <param name="dataObject">The DataObject to set.</param> /// <param name="type">The type of the drop image.</param> /// <param name="format">The format string for the description.</param> /// <param name="insert">The parameter for the drop description.</param> /// <remarks> /// When setting the drop description, the text can be set in two part, /// which will be rendered slightly differently to distinguish the description /// from the subject. For example, the format can be set as "Move to %1" and /// the insert as "Temp". When rendered, the "%1" in format will be replaced /// with "Temp", but "Temp" will be rendered slightly different from "Move to ". /// </remarks> public static void SetDropDescription(this IDataObject dataObject, DropImageType type, string format, string insert) { if (format != null && format.Length > 259) { throw new ArgumentException("Format string exceeds the maximum allowed length of 259.", "format"); } if (insert != null && insert.Length > 259) { throw new ArgumentException("Insert string exceeds the maximum allowed length of 259.", "insert"); } // Fill the structure DropDescription dd; dd.type = (int)type; dd.szMessage = format; dd.szInsert = insert; ComDataObjectExtensions.SetDropDescription((ComIDataObject)dataObject, dd); }
/// <summary> /// Registers a Control as a drag source and provides default implementations of /// GiveFeedback and QueryContinueDrag. /// </summary> /// <param name="control">The drag source Control instance.</param> /// <param name="data">The DataObject associated to the drag source.</param> /// <remarks>Callers must call UnregisterDefaultDragSource when the drag and drop /// operation is complete to avoid memory leaks.</remarks> public static void RegisterDefaultDragSource(Control control, IDataObject data) { // Cache the drag source and the associated data object DragSourceEntry entry = new DragSourceEntry(data); if (!s_dataContext.ContainsKey(control)) { s_dataContext.Add(control, entry); } else { s_dataContext[control] = entry; } // We need to listen for drop description changes. If a drop target // changes the drop description, we shouldn't provide a default one. entry.adviseConnection = ComDataObjectExtensions.Advise(((Runtime.InteropServices.ComTypes.IDataObject)data), new AdviseSink(data), DropDescriptionFormat, 0); // Hook up the default drag source event handlers control.GiveFeedback += DefaultGiveFeedbackHandler; control.QueryContinueDrag += DefaultQueryContinueDragHandler; }