Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / WinForms / System / WinForms / Design / OleDragDropHandler.cs / 2 / OleDragDropHandler.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* */ namespace System.Windows.Forms.Design { using System.Design; using System.Runtime.InteropServices; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System; using System.ComponentModel.Design; using System.ComponentModel.Design.Serialization; using System.Windows.Forms; using System.Collections; using System.Drawing; using System.Drawing.Design; using Microsoft.Win32; using System.IO; using System.Windows.Forms.Design.Behavior; using System.Runtime.Serialization.Formatters.Binary; using Microsoft.Internal.Performance; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters; using System.Globalization; internal class OleDragDropHandler { // This is a bit that we stuff into the DoDragDrop // to indicate that the thing that is being dragged should only // be allowed to be moved in the current DropTarget (e.g. parent designer). // We use this for interited components that can be modified (e.g. location/size) changed // but not removed from their parent. // protected const int AllowLocalMoveOnly = 0x04000000; private SelectionUIHandler selectionHandler; private IServiceProvider serviceProvider; private IOleDragClient client; private bool dragOk; private bool forceDrawFrames; private bool localDrag = false; private bool localDragInside = false; private Point localDragOffset = Point.Empty; private DragDropEffects localDragEffect; private object[] dragComps; private Point dragBase = Point.Empty; private static bool freezePainting = false; private static Hashtable currentDrags; private static CodeMarkers codemarkers = CodeMarkers.Instance; public const string CF_CODE = "CF_XMLCODE"; public const string CF_COMPONENTTYPES = "CF_COMPONENTTYPES"; public const string CF_TOOLBOXITEM = "CF_NESTEDTOOLBOXITEM"; public OleDragDropHandler(SelectionUIHandler selectionHandler, IServiceProvider serviceProvider, IOleDragClient client) { this.serviceProvider = serviceProvider; this.selectionHandler = selectionHandler; this.client = client; } public static string DataFormat { get { return CF_CODE; } } public static string ExtraInfoFormat { get { return CF_COMPONENTTYPES; } } public static string NestedToolboxItemFormat { get { return CF_TOOLBOXITEM; } } private IComponent GetDragOwnerComponent(IDataObject data){ if (currentDrags == null || !currentDrags.Contains(data)) { return null; } return currentDrags[data] as IComponent; } private static void AddCurrentDrag(IDataObject data, IComponent component) { if (currentDrags == null) { currentDrags = new Hashtable(); } currentDrags[data] = component; } private static void RemoveCurrentDrag(IDataObject data) { currentDrags.Remove(data); } internal IOleDragClient Destination { get { return client; } } [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] [SuppressMessage("Microsoft.Security", "CA2102:CatchNonClsCompliantExceptionsInGeneralHandlers")] protected virtual bool CanDropDataObject(IDataObject dataObj) { if (dataObj != null) { if (dataObj is ComponentDataObjectWrapper) { object[] dragObjs = GetDraggingObjects(dataObj, true); if (dragObjs == null) { return false; } bool dropOk = true; for (int i = 0; dropOk && i < dragObjs.Length; i++) { dropOk = dropOk && (dragObjs[i] is IComponent) && client.IsDropOk((IComponent)dragObjs[i]); } return dropOk; } try { object serializationData = dataObj.GetData(OleDragDropHandler.DataFormat, false); if (serializationData == null) { return false; } IDesignerSerializationService ds = (IDesignerSerializationService)GetService(typeof(IDesignerSerializationService)); if (ds == null) { return false; } ICollection objects = ds.Deserialize(serializationData); if (objects.Count > 0) { bool dropOk = true; foreach(object o in objects) { if (!(o is IComponent)) { continue; } dropOk = dropOk && client.IsDropOk((IComponent)o); if (!dropOk) break; } return dropOk; } } catch (Exception ex) { // we return false on any exception if (ClientUtils.IsCriticalException(ex)) { throw; } } } return false; } public bool Dragging { get{ return localDrag; } } public static bool FreezePainting { get { return freezePainting; } } ////// /// This is the worker method of all CreateTool methods. It is the only one /// that can be overridden. /// public IComponent[] CreateTool(ToolboxItem tool, Control parent, int x, int y, int width, int height, bool hasLocation, bool hasSize) { return CreateTool(tool, parent, x, y, width, height, hasLocation, hasSize, null); } [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] [SuppressMessage("Microsoft.Security", "CA2102:CatchNonClsCompliantExceptionsInGeneralHandlers")] public IComponent[] CreateTool(ToolboxItem tool, Control parent, int x, int y, int width, int height, bool hasLocation, bool hasSize, ToolboxSnapDragDropEventArgs e) { // Services we will need // IToolboxService toolboxSvc = (IToolboxService)GetService(typeof(IToolboxService)); ISelectionService selSvc = (ISelectionService)GetService(typeof(ISelectionService)); IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost)); IComponent[] comps = new IComponent[0]; Cursor oldCursor = Cursor.Current; Cursor.Current = Cursors.WaitCursor; DesignerTransaction trans = null; try { try { if (host != null) trans = host.CreateTransaction(SR.GetString(SR.DesignerBatchCreateTool, tool.ToString())); } catch(CheckoutException cxe) { if (cxe == CheckoutException.Canceled) return comps; throw cxe; } try { try { // First check if we are currently in localization mode (i.e., language is non-default). // If so, we should not permit addition of new components. This is an intentional // change from Everett - see VSWhidbey #292249. if (host != null && CurrentlyLocalizing(host.RootComponent)) { IUIService uiService = (IUIService)GetService(typeof(IUIService)); if (uiService != null) { uiService.ShowMessage(SR.GetString(SR.LocalizingCannotAdd)); } comps = new IComponent[0]; return comps; } // Create a dictionary of default values that the designer can // use to initialize a control with. Hashtable defaultValues = new Hashtable(); if (parent != null) defaultValues["Parent"] = parent; // adjust the location if we are in a mirrored parent. That is because the origin // will then be in the upper right rather than upper left. if (parent != null && parent.IsMirrored) { x += width; } if (hasLocation) defaultValues["Location"] = new Point(x, y); if (hasSize) defaultValues["Size"] = new Size(width, height); //store off extra behavior drag/drop information if (e != null) defaultValues["ToolboxSnapDragDropEventArgs"] = e; comps = tool.CreateComponents(host, defaultValues); } catch (CheckoutException checkoutEx) { if (checkoutEx == CheckoutException.Canceled) { comps = new IComponent[0]; } else { throw; } } catch (ArgumentException argumentEx) { IUIService uiService = (IUIService)GetService(typeof(IUIService)); if (uiService != null) { uiService.ShowError(argumentEx); } } catch (Exception ex) { IUIService uiService = (IUIService)GetService(typeof(IUIService)); string exceptionMessage = String.Empty; if (ex.InnerException != null) { exceptionMessage = ex.InnerException.ToString(); } if (String.IsNullOrEmpty(exceptionMessage)) { exceptionMessage = ex.ToString(); } if (ex is InvalidOperationException) { exceptionMessage = ex.Message; } if (uiService != null) { uiService.ShowError(ex, SR.GetString(SR.FailedToCreateComponent, tool.DisplayName, exceptionMessage)); } else { throw; } } if (comps == null) { comps = new IComponent[0]; } } finally { if (toolboxSvc != null && tool.Equals(toolboxSvc.GetSelectedToolboxItem(host))) { toolboxSvc.SelectedToolboxItemUsed(); } } } finally { if (trans != null) { trans.Commit(); } Cursor.Current = oldCursor; } // Finally, select the newly created components. // if (selSvc != null && comps.Length > 0) { if (host != null) { host.Activate(); } ArrayList selectComps = new ArrayList(comps); for (int i = 0; i < comps.Length; i++) { if (!TypeDescriptor.GetAttributes(comps[i]).Contains(DesignTimeVisibleAttribute.Yes)) { selectComps.Remove(comps[i]); } } selSvc.SetSelectedComponents(selectComps.ToArray(), SelectionTypes.Replace); } codemarkers.CodeMarker(CodeMarkerEvent.perfFXDesignCreateComponentEnd); return comps; } ////// Determines whether we are currently in localization mode - i.e., language is not (Default). /// private bool CurrentlyLocalizing(IComponent rootComponent) { if (rootComponent != null) { PropertyDescriptor prop = TypeDescriptor.GetProperties(rootComponent)["Language"]; if (prop != null && prop.PropertyType == typeof(System.Globalization.CultureInfo)) { System.Globalization.CultureInfo ci = (System.Globalization.CultureInfo)prop.GetValue(rootComponent); if (!ci.Equals(System.Globalization.CultureInfo.InvariantCulture)) { return true; } } } return false; } private void DisableDragDropChildren(ICollection controls, ArrayList allowDropCache) { foreach(Control c in controls) { if (c != null) { if (c.AllowDrop) { allowDropCache.Add(c); c.AllowDrop = false; } if (c.HasChildren) { DisableDragDropChildren(c.Controls, allowDropCache); } } } } [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] [SuppressMessage("Microsoft.Security", "CA2102:CatchNonClsCompliantExceptionsInGeneralHandlers")] private Point DrawDragFrames(object[] comps, Point oldOffset, DragDropEffects oldEffect, Point newOffset, DragDropEffects newEffect, bool drawAtNewOffset) { Control comp; Rectangle newRect = Rectangle.Empty; Point tempPt = Point.Empty; Control parentControl = client.GetDesignerControl(); if (selectionHandler == null) { Debug.Fail("selectionHandler should not be null"); return Point.Empty; } if (comps == null) { return Point.Empty; } for (int i = 0; i < comps.Length; i++) { comp = (Control)client.GetControlForComponent(comps[i]); Color backColor = SystemColors.Control; try { backColor = comp.BackColor; } catch(Exception ex) { if (ClientUtils.IsCriticalException(ex)) { throw; } } // If we are moving, we must make sure that the location property of the component // is not read only. Otherwise, we can't move the thing. // bool readOnlyLocation = true; PropertyDescriptor loc = TypeDescriptor.GetProperties(comps[i])["Location"]; if (loc != null) { readOnlyLocation = loc.IsReadOnly; } // first, undraw the old rect if (!oldOffset.IsEmpty) { if ((int)(oldEffect & DragDropEffects.Move) == 0 || !readOnlyLocation) { newRect = comp.Bounds; if (drawAtNewOffset) { newRect.X = oldOffset.X; newRect.Y = oldOffset.Y; } else { newRect.Offset(oldOffset.X, oldOffset.Y); } newRect = selectionHandler.GetUpdatedRect(comp.Bounds, newRect, false); DrawReversibleFrame(parentControl.Handle, newRect, backColor); } } if (!newOffset.IsEmpty) { if ((int)(oldEffect & DragDropEffects.Move) == 0 || !readOnlyLocation) { newRect = comp.Bounds; if (drawAtNewOffset) { newRect.X = newOffset.X; newRect.Y = newOffset.Y; } else { newRect.Offset(newOffset.X, newOffset.Y); } newRect = selectionHandler.GetUpdatedRect(comp.Bounds, newRect, false); DrawReversibleFrame(parentControl.Handle, newRect, backColor); } } } return newOffset; } private void DrawReversibleFrame(IntPtr handle, Rectangle rectangle, Color backColor) { //Bug # 71547to make drag rect visible if any the dimensions of the control are 0 if (rectangle.Width == 0) rectangle.Width = 5; if (rectangle.Height == 0) rectangle.Height = 5; // Copy of ControlPaint.DrawReversibleFrame, see VSWhidbey 581670 // If ControlPaint ever gets overrloaded, we should replace the code below by calling it: // ControlPaint.DrawReversibleFrame(handle, rectangle, backColor, FrameStyle.Thick); // Also, remove extra code from System.Design.NativeMethods, System.Design.SafeNativeMethods // and System.Design.UnsafeNativeMethods // ------ Duplicate code--------------------------------------------------------- int rop2; Color graphicsColor; if (backColor.GetBrightness() < .5) { rop2 = 0xA; // RasterOp.PEN.Invert().XorWith(RasterOp.TARGET); graphicsColor = Color.White; } else { rop2 = 0x7; // RasterOp.PEN.XorWith(RasterOp.TARGET); graphicsColor = Color.Black; } IntPtr dc = UnsafeNativeMethods.GetDC(new HandleRef(null, handle)); IntPtr pen = SafeNativeMethods.CreatePen(NativeMethods.PS_SOLID, 2, ColorTranslator.ToWin32(backColor)); int prevRop2 = SafeNativeMethods.SetROP2(new HandleRef(null, dc), rop2); IntPtr oldBrush = SafeNativeMethods.SelectObject(new HandleRef(null, dc), new HandleRef(null, UnsafeNativeMethods.GetStockObject(NativeMethods.HOLLOW_BRUSH))); IntPtr oldPen = SafeNativeMethods.SelectObject(new HandleRef(null, dc), new HandleRef(null, pen)); SafeNativeMethods.SetBkColor(new HandleRef(null, dc), ColorTranslator.ToWin32(graphicsColor)); SafeNativeMethods.Rectangle(new HandleRef(null, dc), rectangle.X, rectangle.Y, rectangle.Right, rectangle.Bottom); SafeNativeMethods.SetROP2(new HandleRef(null, dc), prevRop2); SafeNativeMethods.SelectObject(new HandleRef(null, dc), new HandleRef(null, oldBrush)); SafeNativeMethods.SelectObject(new HandleRef(null, dc), new HandleRef(null, oldPen)); if (pen != IntPtr.Zero) { SafeNativeMethods.DeleteObject(new HandleRef(null, pen)); } UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, dc)); // ------ Duplicate code--------------------------------------------------------- } public bool DoBeginDrag(object[] components, SelectionRules rules, int initialX, int initialY) { // if we're in a sizing operation, or the mouse isn't down, don't do this! if ((rules & SelectionRules.AllSizeable) != SelectionRules.None || Control.MouseButtons == MouseButtons.None) { return true; } Control c = (Control)client.GetDesignerControl(); localDrag = true; localDragInside = false; dragComps = components; dragBase = new Point(initialX, initialY); localDragOffset = Point.Empty; Point basePt = c.PointToClient(new Point(initialX,initialY)); DragDropEffects allowedEffects = DragDropEffects.Copy | DragDropEffects.None | DragDropEffects.Move; // check to see if any of the components are inherhited. if so, don't allow them to be moved. // We replace DragDropEffects.Move with a local bit called AllowLocalMoveOnly which means it // can be moved around on the current dropsource/target, but not to another target. Since only // we understand this bit, other drop targets will not allow the move to occur // for (int i = 0; i < components.Length; i++) { InheritanceAttribute attr = (InheritanceAttribute)TypeDescriptor.GetAttributes(components[i])[typeof(InheritanceAttribute)]; if (!attr.Equals(InheritanceAttribute.NotInherited) && !attr.Equals(InheritanceAttribute.InheritedReadOnly)) { allowedEffects &= ~DragDropEffects.Move; allowedEffects |= (DragDropEffects)AllowLocalMoveOnly; } } DataObject data = new ComponentDataObjectWrapper(new ComponentDataObject(client, serviceProvider, components, initialX, initialY)); // We make sure we're painted before we start the drag. Then, we disable window painting to // ensure that the drag can proceed without leaving artifacts lying around. We should be caling LockWindowUpdate, // but that causes a horrible flashing because GDI+ uses direct draw. // NativeMethods.MSG msg = new NativeMethods.MSG(); while (NativeMethods.PeekMessage(ref msg, IntPtr.Zero, NativeMethods.WM_PAINT, NativeMethods.WM_PAINT, NativeMethods.PM_REMOVE)) { NativeMethods.TranslateMessage(ref msg); NativeMethods.DispatchMessage(ref msg); } // don't do any new painting... bool oldFreezePainting = freezePainting; // asurt 90345 -- this causes some subtle bugs, so i'm turning it off to see if we really need it, and if we do // if we can find a better way. // //freezePainting = true; AddCurrentDrag(data, client.Component); // Walk through all the children recursively and disable drag-drop // for each of them. This way, we will not accidentally try to drop // ourselves into our own children. // ArrayList allowDropChanged = new ArrayList(); foreach(object comp in components) { Control ctl = comp as Control; if (ctl != null && ctl.HasChildren) { DisableDragDropChildren(ctl.Controls, allowDropChanged); } } DragDropEffects effect = DragDropEffects.None; IDesignerHost host = GetService(typeof(IDesignerHost)) as IDesignerHost; DesignerTransaction trans = null; if (host != null) { trans = host.CreateTransaction(SR.GetString(SR.DragDropDragComponents, components.Length)); } try { effect = c.DoDragDrop(data, allowedEffects); if (trans != null) { trans.Commit(); } } finally { RemoveCurrentDrag(data); // Reset the AllowDrop for the components being dragged. // foreach(Control ctl in allowDropChanged) { ctl.AllowDrop = true; } freezePainting = oldFreezePainting; if (trans != null) { ((IDisposable)trans).Dispose(); } } bool isMove = ((int)(effect & DragDropEffects.Move)) != 0 || ((int)((int)effect & AllowLocalMoveOnly)) != 0; // since the EndDrag will clear this bool isLocalMove = isMove && localDragInside; ISelectionUIService selectionUISvc = (ISelectionUIService)GetService(typeof(ISelectionUIService)); Debug.Assert(selectionUISvc != null, "Unable to get selection ui service when adding child control"); if (selectionUISvc != null) { // We must check to ensure that UI service is still in drag mode. It is // possible that the user hit escape, which will cancel drag mode. // if (selectionUISvc.Dragging) { // cancel the drag if we aren't doing a local move selectionUISvc.EndDrag(!isLocalMove); } } if (!localDragOffset.IsEmpty && effect != DragDropEffects.None) { DrawDragFrames(dragComps, localDragOffset, localDragEffect, Point.Empty, DragDropEffects.None, false); } localDragOffset = Point.Empty; dragComps = null; localDrag = localDragInside = false; dragBase = Point.Empty; /*if (!isLocalMove && isMove){ IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost)); IUndoService undoService = (IUndoService)GetService(typeof(IUndoService)); IActionUnit unit = null; if (host != null) { DesignerTransaction trans = host.CreateTransaction("Drag/drop"); try{ // delete the components try{ for (int i = 0; i < components.Length; i++){ if (components[i] is IComponent){ if (undoService != null){ unit = new CreateControlActionUnit(host, (IComponent)components[i], true); } host.DestroyComponent((IComponent)components[i]); if (undoService != null){ undoService.AddAction(unit, false); } } } }catch(CheckoutException ex){ if (ex != CheckoutException.Canceled){ throw ex; } } } finally{ trans.Commit(); } } }*/ return false; } public void DoEndDrag(object[] components, bool cancel) { dragComps = null; localDrag = false; localDragInside = false; } public void DoOleDragDrop(DragEventArgs de) { // ASURT 43757: By the time we come here, it means that the user completed the drag-drop and // we compute the new location/size of the controls if needed and set the property values. // We have to stop freezePainting right here, so that controls can get a chance to validate // their new rects. // freezePainting = false; if (selectionHandler == null) { Debug.Fail("selectionHandler should not be null"); de.Effect = DragDropEffects.None; return; } // make sure we've actually moved if ((localDrag && de.X == dragBase.X && de.Y == dragBase.Y) || de.AllowedEffect == DragDropEffects.None || (!localDrag && !dragOk)) { de.Effect = DragDropEffects.None; return; } bool localMoveOnly = ((int)((int)de.AllowedEffect & AllowLocalMoveOnly)) != 0 && localDragInside; // if we are dragging inside the local dropsource/target, and and AllowLocalMoveOnly flag is set, // we just consider this a normal move. // bool moveAllowed = (de.AllowedEffect & DragDropEffects.Move) != DragDropEffects.None || localMoveOnly; bool copyAllowed = (de.AllowedEffect & DragDropEffects.Copy) != DragDropEffects.None; if ((de.Effect & DragDropEffects.Move) != 0 && !moveAllowed) { // Try copy instead? de.Effect = DragDropEffects.Copy; } // make sure the copy is allowed if ((de.Effect & DragDropEffects.Copy) != 0 && !copyAllowed) { // if copy isn't allowed, don't do anything de.Effect = DragDropEffects.None; return; } if (localMoveOnly && (de.Effect & DragDropEffects.Move) != 0) { de.Effect |= (DragDropEffects)AllowLocalMoveOnly | DragDropEffects.Move; } else if ((de.Effect & DragDropEffects.Copy) != 0) { de.Effect = DragDropEffects.Copy; } if (forceDrawFrames || localDragInside) { // undraw the drag rect localDragOffset = DrawDragFrames(dragComps, localDragOffset, localDragEffect, Point.Empty, DragDropEffects.None, forceDrawFrames); forceDrawFrames = false; } Cursor oldCursor = Cursor.Current; try { Cursor.Current = Cursors.WaitCursor; if (dragOk || (localDragInside && de.Effect == DragDropEffects.Copy)) { // add em to this parent. IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost)); IContainer container = host.RootComponent.Site.Container; object[] components; IDataObject dataObj = de.Data; bool updateLocation = false; if (dataObj is ComponentDataObjectWrapper) { dataObj = ((ComponentDataObjectWrapper)dataObj).InnerData; ComponentDataObject cdo = (ComponentDataObject)dataObj; // if we're moving ot a different container, do a full serialization // to make sure we pick up design time props, etc. // IComponent dragOwner = GetDragOwnerComponent(de.Data); bool newContainer = dragOwner == null || client.Component == null || dragOwner.Site.Container != client.Component.Site.Container; bool collapseChildren = false; if (de.Effect == DragDropEffects.Copy || newContainer) { // this causes new elements to be created // cdo.Deserialize(serviceProvider, (int)(de.Effect & DragDropEffects.Copy) == 0); } else { collapseChildren = true; } updateLocation = true; components = cdo.Components; if (collapseChildren) { components = GetTopLevelComponents(components); } } else { object serializationData = dataObj.GetData(OleDragDropHandler.DataFormat, true); if (serializationData == null) { Debug.Fail("data object didn't return any data, so how did we allow the drop?"); components = new IComponent[0]; } else { dataObj = new ComponentDataObject(client, serviceProvider, serializationData); components = ((ComponentDataObject)dataObj).Components; updateLocation = true; } } // now we need to offset the components locations from the drop mouse // point to the parent, since their current locations are relative // the the mouse pointer if (components != null && components.Length > 0) { Debug.Assert(container != null, "Didn't get a container from the site!"); string name; IComponent comp = null; DesignerTransaction trans = null; try { trans = host.CreateTransaction(SR.GetString(SR.DragDropDropComponents)); if (!localDrag) { host.Activate(); } ArrayList selectComps = new ArrayList(); for (int i = 0; i < components.Length; i++) { comp = components[i] as IComponent; if (comp == null) { comp = null; continue; } try { name = null; if (comp.Site != null) { name = comp.Site.Name; } Control oldDesignerControl = null; if (updateLocation) { oldDesignerControl = client.GetDesignerControl(); NativeMethods.SendMessage(oldDesignerControl.Handle, NativeMethods.WM_SETREDRAW, 0, 0); } Point dropPt = client.GetDesignerControl().PointToClient(new Point(de.X, de.Y)); // First check if the component we are dropping have a TrayLocation, and if so, use it PropertyDescriptor loc = TypeDescriptor.GetProperties(comp)["TrayLocation"]; if (loc == null) { // it didn't, so let's check for the regular Location loc = TypeDescriptor.GetProperties(comp)["Location"]; } if (loc != null && !loc.IsReadOnly) { Rectangle bounds = new Rectangle(); Point pt = (Point)loc.GetValue(comp); bounds.X = dropPt.X + pt.X; bounds.Y = dropPt.Y + pt.Y; bounds = selectionHandler.GetUpdatedRect(Rectangle.Empty, bounds, false); } if (!client.AddComponent(comp, name, false)) { // this means that we just moved the control // around in the same designer. de.Effect = DragDropEffects.None; } else { // make sure the component was added to this client if (client.GetControlForComponent(comp) == null) { updateLocation = false; } } if (updateLocation) { ParentControlDesigner parentDesigner = client as ParentControlDesigner; if (parentDesigner != null) { Control c = client.GetControlForComponent(comp); dropPt = parentDesigner.GetSnappedPoint(c.Location); c.Location = dropPt; } } if (oldDesignerControl != null) { //((ComponentDataObject)dataObj).ShowControls(); NativeMethods.SendMessage(oldDesignerControl.Handle, NativeMethods.WM_SETREDRAW, 1, 0); oldDesignerControl.Invalidate(true); } if (TypeDescriptor.GetAttributes(comp).Contains(DesignTimeVisibleAttribute.Yes)) { selectComps.Add(comp); } } catch (CheckoutException ceex) { if (ceex == CheckoutException.Canceled) { break; } throw; } } if (host != null) { host.Activate(); } // select the newly added components ISelectionService selService = (ISelectionService)GetService(typeof(ISelectionService)); selService.SetSelectedComponents((object[])selectComps.ToArray(typeof(IComponent)), SelectionTypes.Replace); localDragInside = false; } finally { if (trans != null) trans.Commit(); } } } if (localDragInside) { ISelectionUIService selectionUISvc = (ISelectionUIService)GetService(typeof(ISelectionUIService)); Debug.Assert(selectionUISvc != null, "Unable to get selection ui service when adding child control"); if (selectionUISvc != null) { // We must check to ensure that UI service is still in drag mode. It is // possible that the user hit escape, which will cancel drag mode. // if (selectionUISvc.Dragging && moveAllowed) { Rectangle offset = new Rectangle(de.X - dragBase.X, de.Y - dragBase.Y, 0, 0); selectionUISvc.DragMoved(offset); } } } dragOk = false; } finally { Cursor.Current = oldCursor; } } public void DoOleDragEnter(DragEventArgs de) { /* this causes focus rects to be drawn, which we don't want to happen. Control dragHost = client.GetDesignerControl(); if (dragHost != null && dragHost.CanSelect) { dragHost.Focus(); }*/ if (!localDrag && CanDropDataObject(de.Data) && de.AllowedEffect != DragDropEffects.None) { if (!client.CanModifyComponents) { return; } dragOk = true; // this means it's not us doing the drag if ((int)(de.KeyState & NativeMethods.MK_CONTROL) != 0 && (de.AllowedEffect & DragDropEffects.Copy) != (DragDropEffects)0) { de.Effect = DragDropEffects.Copy; } else if ((de.AllowedEffect & DragDropEffects.Move) != (DragDropEffects)0) { de.Effect = DragDropEffects.Move; } else { de.Effect = DragDropEffects.None; return; } } else if (localDrag && de.AllowedEffect != DragDropEffects.None) { localDragInside = true; if ((int)(de.KeyState & NativeMethods.MK_CONTROL) != 0 && (de.AllowedEffect & DragDropEffects.Copy) != (DragDropEffects)0 && client.CanModifyComponents) { de.Effect = DragDropEffects.Copy; } bool localMoveOnly = ((int)((int)de.AllowedEffect & AllowLocalMoveOnly)) != 0 && localDragInside; if (localMoveOnly) { de.Effect |= (DragDropEffects)AllowLocalMoveOnly; } if ((de.AllowedEffect & DragDropEffects.Move) != (DragDropEffects)0) { de.Effect |= DragDropEffects.Move; } } else { de.Effect = DragDropEffects.None; } } public void DoOleDragLeave() { if (localDrag || forceDrawFrames) { localDragInside = false; localDragOffset = DrawDragFrames(dragComps, localDragOffset, localDragEffect, Point.Empty, DragDropEffects.None, forceDrawFrames); if (forceDrawFrames && dragOk) { dragBase = Point.Empty; dragComps = null; } forceDrawFrames = false; } dragOk = false; } public void DoOleDragOver(DragEventArgs de) { Debug.WriteLineIf(CompModSwitches.DragDrop.TraceInfo, "\tOleDragDropHandler.OnDragOver: " + de.ToString()); if (!localDrag && !dragOk) { de.Effect = DragDropEffects.None; return; } bool copy = (int)(de.KeyState & NativeMethods.MK_CONTROL) != 0 && (de.AllowedEffect & DragDropEffects.Copy) != (DragDropEffects)0 && client.CanModifyComponents; // we pretend AllowLocalMoveOnly is a normal move when we are over the originating container. // bool localMoveOnly = ((int)((int)de.AllowedEffect & AllowLocalMoveOnly)) != 0 && localDragInside; bool move = (de.AllowedEffect & DragDropEffects.Move) != (DragDropEffects)0 || localMoveOnly; if ((copy || move) && (localDrag || forceDrawFrames)) { // draw the shadow rects. Point newOffset = Point.Empty; Point convertedPoint = client.GetDesignerControl().PointToClient(new Point(de.X, de.Y)); if (forceDrawFrames) { newOffset = convertedPoint; } else { newOffset = new Point(de.X - dragBase.X, de.Y - dragBase.Y); } // 96845 -- only allow drops on the client area // if (!client.GetDesignerControl().ClientRectangle.Contains(convertedPoint)) { copy = false; move = false; newOffset = localDragOffset; } if (newOffset != localDragOffset) { Debug.WriteLineIf(CompModSwitches.DragDrop.TraceInfo, "\tParentControlDesigner.OnDragOver: " + de.ToString()); DrawDragFrames(dragComps, localDragOffset, localDragEffect, newOffset, de.Effect, forceDrawFrames); localDragOffset = newOffset; localDragEffect = de.Effect; } } if (copy) { de.Effect = DragDropEffects.Copy; } else if (move) { de.Effect = DragDropEffects.Move; } else { de.Effect = DragDropEffects.None; } if (localMoveOnly) { de.Effect |= (DragDropEffects)AllowLocalMoveOnly; } } public void DoOleGiveFeedback(GiveFeedbackEventArgs e) { if (selectionHandler == null) { Debug.Fail("selectionHandler should not be null"); } e.UseDefaultCursors = ((!localDragInside && !forceDrawFrames) || ((e.Effect & (DragDropEffects.Copy)) != 0)) || e.Effect == DragDropEffects.None; if (!e.UseDefaultCursors && selectionHandler != null) { selectionHandler.SetCursor(); } } private object[] GetDraggingObjects(IDataObject dataObj, bool topLevelOnly) { object[] components = null; if (dataObj is ComponentDataObjectWrapper) { dataObj = ((ComponentDataObjectWrapper)dataObj).InnerData; ComponentDataObject cdo = (ComponentDataObject)dataObj; components = cdo.Components; } if (!topLevelOnly || components == null) { return components; } return GetTopLevelComponents(components); } public object[] GetDraggingObjects(IDataObject dataObj) { return GetDraggingObjects(dataObj, false); } public object[] GetDraggingObjects(DragEventArgs de) { return GetDraggingObjects(de.Data); } private object[] GetTopLevelComponents(ICollection comps) { // Filter the top-level components. // if (!(comps is IList)) { comps = new ArrayList(comps); } IList compList = (IList)comps; ArrayList topLevel = new ArrayList(); foreach(object comp in compList) { Control c = comp as Control; if (c == null && comp != null) { topLevel.Add(comp); } else if (c != null){ if (c.Parent == null || !compList.Contains(c.Parent)) { topLevel.Add(comp); } } } return topLevel.ToArray(); } protected object GetService(Type t) { return serviceProvider.GetService(t); } protected virtual void OnInitializeComponent(IComponent comp, int x, int y, int width, int height, bool hasLocation, bool hasSize) { } // just so we can recognize the ones we create protected class ComponentDataObjectWrapper: System.Windows.Forms.DataObject{ ComponentDataObject innerData; public ComponentDataObjectWrapper(ComponentDataObject dataObject) : base((IDataObject)dataObject){ innerData = dataObject; } public ComponentDataObject InnerData{ get{ return innerData; } } } protected class ComponentDataObject : System.Windows.Forms.IDataObject { private IServiceProvider serviceProvider; private object[] components; private Stream serializationStream; private object serializationData; private int initialX; private int initialY; private IOleDragClient dragClient; private CfCodeToolboxItem toolboxitemdata; public ComponentDataObject(IOleDragClient dragClient, IServiceProvider sp, object[] comps, int x, int y) { this.serviceProvider = sp; this.components = GetComponentList(comps, null, -1); this.initialX = x; this.initialY = y; this.dragClient = dragClient; } public ComponentDataObject(IOleDragClient dragClient, IServiceProvider sp, object serializationData) { this.serviceProvider = sp; this.serializationData = serializationData; this.dragClient = dragClient; } private Stream SerializationStream { get { if (serializationStream == null && Components != null) { IDesignerSerializationService ds = (IDesignerSerializationService)serviceProvider.GetService(typeof(IDesignerSerializationService)); if (ds != null) { object[] comps = new object[components.Length]; for (int i = 0; i < components.Length; i++) { Debug.Assert(components[i] is IComponent, "Item " + components[i].GetType().Name + " is not an IComponent"); comps[i] = (IComponent)components[i]; } object sd = ds.Serialize(comps); serializationStream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(serializationStream, sd); serializationStream.Seek(0, SeekOrigin.Begin); } } return serializationStream; } } public object[] Components{ get{ if (components == null && (serializationStream != null || serializationData != null)) { Deserialize(null, false); if (components == null) { return new object[0]; } } return(object[])components.Clone(); } } /// /// computes the IDataObject which constitutes this whole toolboxitem for storage in the toolbox. /// private CfCodeToolboxItem NestedToolboxItem { get { if (toolboxitemdata == null) { toolboxitemdata = new CfCodeToolboxItem(this.GetData(OleDragDropHandler.DataFormat)); } return toolboxitemdata; } } ////// /// Used to retrieve the selection for a copy. The default implementation /// retrieves the current selection. /// private object[] GetComponentList(object[] components, ArrayList list, int index) { if (serviceProvider == null) { return components; } ISelectionService selSvc = (ISelectionService)this.serviceProvider.GetService(typeof(ISelectionService)); if (selSvc == null) { return components; } ICollection selectedComponents; if (components == null) selectedComponents = selSvc.GetSelectedComponents(); else selectedComponents = new ArrayList(components); IDesignerHost host = (IDesignerHost)serviceProvider.GetService(typeof(IDesignerHost)); if (host != null) { ArrayList copySelection = new ArrayList(); foreach (IComponent comp in selectedComponents) { copySelection.Add(comp); GetAssociatedComponents(comp, host, copySelection); } selectedComponents = copySelection; } object[] comps = new object[selectedComponents.Count]; selectedComponents.CopyTo(comps, 0); return comps; } private void GetAssociatedComponents(IComponent component, IDesignerHost host, ArrayList list) { ComponentDesigner designer = host.GetDesigner(component) as ComponentDesigner; if (designer == null) { return; } foreach (IComponent childComp in designer.AssociatedComponents) { list.Add(childComp); GetAssociatedComponents(childComp, host, list); } } public virtual object GetData(string format) { return GetData(format, false); } public virtual object GetData(string format, bool autoConvert) { if (format.Equals(OleDragDropHandler.DataFormat)) { BinaryFormatter formatter = new BinaryFormatter(); SerializationStream.Seek(0, SeekOrigin.Begin); return formatter.Deserialize(this.SerializationStream); } else if (format.Equals(OleDragDropHandler.NestedToolboxItemFormat)){ NestedToolboxItem.SetDisplayName(); return NestedToolboxItem; } return null; } public virtual object GetData(Type t) { return GetData(t.FullName); } ////// /// If the there is data store in the data object associated with /// format this will return true. /// /// public bool GetDataPresent(string format, bool autoConvert){ return Array.IndexOf(GetFormats(), format) != -1; } ////// /// If the there is data store in the data object associated with /// format this will return true. /// /// public bool GetDataPresent(string format){ return GetDataPresent(format, false); } ////// /// If the there is data store in the data object associated with /// format this will return true. /// /// public bool GetDataPresent(Type format){ return GetDataPresent(format.FullName, false); } ////// /// Retrieves a list of all formats stored in this data object. /// /// public string[] GetFormats(bool autoConvert){ return GetFormats(); } ////// /// Retrieves a list of all formats stored in this data object. /// /// public string[] GetFormats(){ return new string[] { OleDragDropHandler.NestedToolboxItemFormat, OleDragDropHandler.DataFormat, DataFormats.Serializable, OleDragDropHandler.ExtraInfoFormat }; } public void Deserialize(IServiceProvider serviceProvider, bool removeCurrentComponents) { if (serviceProvider == null) { serviceProvider = this.serviceProvider; } IDesignerSerializationService ds = (IDesignerSerializationService)serviceProvider.GetService(typeof(IDesignerSerializationService)); IDesignerHost host = null; DesignerTransaction trans = null; try { if (serializationData == null) { BinaryFormatter formatter = new BinaryFormatter(); serializationData = formatter.Deserialize(SerializationStream); } if (removeCurrentComponents && components != null) { foreach (IComponent removeComp in components) { if (host == null && removeComp.Site != null) { host = (IDesignerHost)removeComp.Site.GetService(typeof(IDesignerHost)); if (host != null) { trans = host.CreateTransaction(SR.GetString(SR.DragDropMoveComponents, components.Length)); } } if (host != null) { host.DestroyComponent(removeComp); } } components = null; } ICollection objects = ds.Deserialize(serializationData); components = new IComponent[objects.Count]; IEnumerator e = objects.GetEnumerator(); int idx = 0; while(e.MoveNext()) { components[idx++] = (IComponent)e.Current; } // only do top-level components here, // because other are already parented. // otherwise, when we process these // components it's too hard to know what we // should be reparenting. ArrayList topComps = new ArrayList(); for (int i = 0; i < components.Length; i++) { if (components[i] is Control) { Control c = (Control)components[i]; if (c.Parent == null) { topComps.Add(components[i]); } } else { topComps.Add(components[i]); } } components = (object[])topComps.ToArray(); } finally { if (trans != null) { trans.Commit(); } } } ////// /// Sets the data to be associated with the specific data format. For /// a listing of predefined formats see System.Windows.Forms.DataFormats. /// /// public void SetData(string format, bool autoConvert, object data){ SetData(format, data); } ////// /// Sets the data to be associated with the specific data format. For /// a listing of predefined formats see System.Windows.Forms.DataFormats. /// /// public void SetData(string format, object data){ throw new Exception(SR.GetString(SR.DragDropSetDataError)); } ////// /// Sets the data to be associated with the specific data format. /// /// public void SetData(Type format, object data){ SetData(format.FullName, data); } ////// /// Stores data in the data object. The format assumed is the /// class of data /// /// public void SetData(object data){ SetData(data.GetType(), data); } } [Serializable] internal class CfCodeToolboxItem : ToolboxItem { private object serializationData; private static int template = 0; bool displaynameset = false; public CfCodeToolboxItem(object serializationData) : base() { this.serializationData = serializationData; } [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] private CfCodeToolboxItem(SerializationInfo info, StreamingContext context) { Deserialize(info, context); } ////// public void SetDisplayName() { if (!displaynameset) { displaynameset = true; this.DisplayName = "Template" + (++template).ToString(CultureInfo.CurrentCulture); } } ////// protected override void Serialize(SerializationInfo info, StreamingContext context) { base.Serialize(info, context); if (serializationData != null) { info.AddValue("CfCodeToolboxItem.serializationData", serializationData); } } ///Saves the state of this ///to /// the specified serialization info. /// protected override void Deserialize(SerializationInfo info, StreamingContext context) { base.Deserialize(info, context); foreach (SerializationEntry entry in info) { if (entry.Name == "CfCodeToolboxItem.serializationData") { serializationData = entry.Value; break; } } } protected override IComponent[] CreateComponentsCore(IDesignerHost host, IDictionary defaultValues) { IDesignerSerializationService ds = (IDesignerSerializationService)host.GetService(typeof(IDesignerSerializationService)); if (ds == null) { return null; } // Deserialize to components collection // ICollection objects = ds.Deserialize(serializationData); ArrayList components = new ArrayList(); foreach(object obj in objects) { if (obj != null && obj is IComponent) { components.Add(obj); } } IComponent[] componentsArray = new IComponent[components.Count]; components.CopyTo(componentsArray, 0); ArrayList trayComponents = null; // Parent and locate each Control // if (defaultValues == null) defaultValues = new Hashtable(); Control parentControl = parentControl = defaultValues["Parent"] as Control; if (parentControl != null) { ParentControlDesigner parentControlDesigner = host.GetDesigner(parentControl) as ParentControlDesigner; if (parentControlDesigner != null) { // Determine bounds of all controls // Rectangle bounds = Rectangle.Empty; foreach (IComponent component in componentsArray) { Control childControl = component as Control; if (childControl != null && childControl != parentControl && childControl.Parent == null) { if (bounds.IsEmpty) { bounds = childControl.Bounds; } else { bounds = Rectangle.Union(bounds, childControl.Bounds); } } } defaultValues.Remove("Size"); // don't care about the drag size foreach (IComponent component in componentsArray) { Control childControl = component as Control; Form form = childControl as Form; if (childControl != null && !(form != null && form.TopLevel) // Don't add top-level forms && childControl.Parent == null) { defaultValues["Offset"] = new Size(childControl.Bounds.X - bounds.X, childControl.Bounds.Y - bounds.Y); parentControlDesigner.AddControl(childControl, defaultValues); } } } } // VSWhidbey 516338 - When creating an item for the tray, template items will have // an old location stored in them, so they may show up on top of other items. // So we need to call UpdatePastePositions for each one to get the tray to // arrange them properly. // ComponentTray tray = (ComponentTray)host.GetService(typeof(ComponentTray)); if (tray != null) { foreach(IComponent component in componentsArray) { ComponentTray.TrayControl c = tray.GetTrayControlFromComponent(component); if (c != null) { if (trayComponents == null) { trayComponents = new ArrayList(); } trayComponents.Add(c); } } if (trayComponents != null) { tray.UpdatePastePositions(trayComponents); } } return componentsArray; } protected override IComponent[] CreateComponentsCore(IDesignerHost host) { return CreateComponentsCore(host, null); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.Loads the state of this ////// from the stream.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DataColumnMapping.cs
- TextTreeTextNode.cs
- AutomationEvent.cs
- VectorAnimationUsingKeyFrames.cs
- IListConverters.cs
- Pair.cs
- ImageIndexConverter.cs
- WorkflowDefinitionDispenser.cs
- SudsParser.cs
- StrongTypingException.cs
- ObservableCollection.cs
- QueryAccessibilityHelpEvent.cs
- GenerateScriptTypeAttribute.cs
- MulticastNotSupportedException.cs
- SqlGenericUtil.cs
- ReadingWritingEntityEventArgs.cs
- dsa.cs
- X509CertificateTrustedIssuerElementCollection.cs
- TextModifierScope.cs
- InheritedPropertyChangedEventArgs.cs
- FilteredDataSetHelper.cs
- CurrencyWrapper.cs
- DBConnectionString.cs
- DbConnectionHelper.cs
- ImageButton.cs
- TextCompositionManager.cs
- Point.cs
- XamlStyleSerializer.cs
- DbConnectionStringCommon.cs
- CheckBoxList.cs
- RegexGroup.cs
- TokenCreationException.cs
- Button.cs
- HttpListenerPrefixCollection.cs
- ContextMenuAutomationPeer.cs
- CompensatableSequenceActivity.cs
- ParallelDesigner.cs
- CompareValidator.cs
- ListenerElementsCollection.cs
- TriggerCollection.cs
- RequestQueue.cs
- XmlAnyElementAttribute.cs
- AnnotationDocumentPaginator.cs
- AnchoredBlock.cs
- XmlCodeExporter.cs
- WorkflowEnvironment.cs
- Message.cs
- RegexReplacement.cs
- ChtmlTextWriter.cs
- NavigationService.cs
- MatrixKeyFrameCollection.cs
- LingerOption.cs
- ListenerSessionConnectionReader.cs
- XPathConvert.cs
- ContainerAction.cs
- ScriptControlDescriptor.cs
- SqlCommand.cs
- CollectionViewGroup.cs
- PathStreamGeometryContext.cs
- SecurityManager.cs
- IPAddress.cs
- AssertUtility.cs
- HttpModuleAction.cs
- RotationValidation.cs
- ComNativeDescriptor.cs
- BatchWriter.cs
- SqlSupersetValidator.cs
- SectionVisual.cs
- ClientRoleProvider.cs
- Point4D.cs
- ReadOnlyCollectionBase.cs
- CodeSnippetTypeMember.cs
- MergeFilterQuery.cs
- UIInitializationException.cs
- ButtonColumn.cs
- SharedHttpTransportManager.cs
- ConsoleCancelEventArgs.cs
- CodeTryCatchFinallyStatement.cs
- GenericEnumConverter.cs
- RedirectionProxy.cs
- Int32CollectionValueSerializer.cs
- HGlobalSafeHandle.cs
- XsltCompileContext.cs
- DirectionalLight.cs
- CorrelationKeyCalculator.cs
- DetailsViewDeleteEventArgs.cs
- XmlAutoDetectWriter.cs
- ResourceManager.cs
- IApplicationTrustManager.cs
- XmlExceptionHelper.cs
- sqlser.cs
- WebBrowser.cs
- DbBuffer.cs
- TypeElementCollection.cs
- CallbackValidatorAttribute.cs
- CompleteWizardStep.cs
- OperationAbortedException.cs
- x509store.cs
- WarningException.cs
- XamlTemplateSerializer.cs