Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / WinForms / System / WinForms / Design / DocumentDesigner.cs / 2 / DocumentDesigner.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
/*
*/
namespace System.Windows.Forms.Design {
using System.Design;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Diagnostics;
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Drawing.Design;
using System.Reflection;
using System.Windows.Forms;
using System.Windows.Forms.Design.Behavior;
using System.Globalization;
using System.Runtime.InteropServices.ComTypes;
using TYPELIBATTR = System.Runtime.InteropServices.ComTypes.TYPELIBATTR;
using IDataObject = System.Windows.Forms.IDataObject;
///
///
/// Provides a designer that extends the ScrollableControlDesigner and implements
/// IRootDesigner.
///
[
ToolboxItemFilter("System.Windows.Forms")
]
public class DocumentDesigner : ScrollableControlDesigner, IRootDesigner, IToolboxUser, IOleDragClient {
private DesignerFrame frame;
private ControlCommandSet commandSet;
private InheritanceService inheritanceService;
private EventHandlerService eventHandlerService;
private DesignBindingValueUIHandler designBindingValueUIHandler;
private BehaviorService behaviorService;
private SelectionManager selectionManager;
private DesignerExtenders designerExtenders;
private InheritanceUI inheritanceUI;
private PbrsForward pbrsFwd;
private ArrayList suspendedComponents = null;
private UndoEngine undoEngine = null;
private bool initializing; // is the designer initializing?
//used to keep the state of the tab order view
//
private bool queriedTabOrder = false;
private MenuCommand tabOrderCommand = null;
//our menu editor service
//
///
protected IMenuEditorService menuEditorService = null;
// The component tray
//
private ComponentTray componentTray;
private int trayHeight = 80;
private bool trayLargeIcon = false;
private bool trayAutoArrange = false;
private bool trayLayoutSuspended = false;
// ActiveX support
//
private static Guid htmlDesignTime = new Guid("73CEF3DD-AE85-11CF-A406-00AA00C00940");
private Hashtable axTools = null;
private static TraceSwitch AxToolSwitch = new TraceSwitch("AxTool", "ActiveX Toolbox Tracing");
private static readonly string axClipFormat = "CLSID";
private ToolboxItemCreatorCallback toolboxCreator = null;
///
/// Property shadow for ContainerControl's AutoScaleDimenions. We shadow here so it
/// always returns the CurrentAutoScaleDimensions for the control. This way the control's
/// state always adapts to the current font / monitor.
///
private SizeF AutoScaleDimensions {
get {
ContainerControl c = Control as ContainerControl;
if (c != null) {
return c.CurrentAutoScaleDimensions;
}
Debug.Fail("AutoScaleDimensions should not be shadowed on non-ContainerControl objects.");
return SizeF.Empty;
}
set {
ContainerControl c = Control as ContainerControl;
if (c != null) {
c.AutoScaleDimensions = value;
}
}
}
///
/// Property shadow for ContainerControl's AutoScaleMode. We shadow here so it
/// never gets to the control; it can be very distracting if you change the font
/// and have the form you're designing suddenly move on you.
///
private AutoScaleMode AutoScaleMode {
get {
ContainerControl c = Control as ContainerControl;
if (c != null) {
return c.AutoScaleMode;
}
Debug.Fail("AutoScaleMode should not be shadowed on non-ContainerControl objects.");
return AutoScaleMode.Inherit;
}
set {
ShadowProperties["AutoScaleMode"] = value;
ContainerControl c = Control as ContainerControl;
if (c != null && c.AutoScaleMode != value) {
c.AutoScaleMode = value;
// If we're not loading and this changes update
// the current auto scale dimensions.
IDesignerHost host = GetService(typeof(IDesignerHost)) as IDesignerHost;
if (host != null && !host.Loading) {
c.AutoScaleDimensions = c.CurrentAutoScaleDimensions;
}
}
}
}
///
/// BackColor property on control. We shadow this property at design time.
///
private Color BackColor {
get {
return Control.BackColor;
}
set {
ShadowProperties["BackColor"] = value;
if (value.IsEmpty) {
value = SystemColors.Control;
}
Control.BackColor = value;
}
}
///
/// Location property on control. We shadow this property at design time.
///
[DefaultValue(typeof(Point), "0, 0")]
private Point Location {
get {
return (Point)ShadowProperties["Location"];
}
set {
ShadowProperties["Location"] = value;
}
}
///
///
/// We override our selectino rules to make the document non-sizeable.
///
public override SelectionRules SelectionRules {
get {
SelectionRules rules = base.SelectionRules;
rules &= ~(SelectionRules.Moveable | SelectionRules.TopSizeable | SelectionRules.LeftSizeable);
return rules;
}
}
///
/// Determines if the tab order UI is active. When tab order is active, we don't want to forward
/// any WndProc messages to the menu editor service (those are all non-selectable components)
///
private bool TabOrderActive {
get {
if (!queriedTabOrder) {
queriedTabOrder = true;
IMenuCommandService menuCommandService = (IMenuCommandService)GetService(typeof(IMenuCommandService));
if (menuCommandService != null)
tabOrderCommand = menuCommandService.FindCommand(MenuCommands.TabOrder);
}
if (tabOrderCommand != null) {
return tabOrderCommand.Checked;
}
return false;
}
}
///
///
[DefaultValue(true)]
private bool TrayAutoArrange {
get {
return trayAutoArrange;
}
set {
trayAutoArrange = value;
if (componentTray != null) {
componentTray.AutoArrange = trayAutoArrange;
}
}
}
///
///
[DefaultValue(false)]
private bool TrayLargeIcon {
get {
return trayLargeIcon;
}
set {
trayLargeIcon = value;
if (componentTray != null) {
componentTray.ShowLargeIcons = trayLargeIcon;
}
}
}
///
///
[DefaultValue(80)]
private int TrayHeight {
get {
if (componentTray != null) {
return componentTray.Height;
}
else {
return trayHeight;
}
}
set {
trayHeight = value;
if (componentTray != null) {
componentTray.Height = trayHeight;
}
}
}
///
///
///
/// Retrieves the control view instance for the given component.
/// For Win32 designer, this will often be the component itself.
///
Control IOleDragClient.GetControlForComponent(object component) {
Control c = GetControl(component);
if (c != null)
return c;
if (componentTray != null) {
return ((IOleDragClient)componentTray).GetControlForComponent(component);
}
return null;
}
internal virtual bool CanDropComponents(DragEventArgs de) {
// If there is no tray we bail.
if (componentTray == null)
return true;
// Figure out if any of the components in the drag-drop are children
// of our own tray. If so, we should prevent this drag-drop from proceeding.
//
OleDragDropHandler ddh = GetOleDragHandler();
object[] dragComps = ddh.GetDraggingObjects(de);
if (dragComps != null) {
IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));
for (int i = 0; i < dragComps.Length; i++) {
IComponent comp = dragComps[i] as IComponent;
if (host == null || dragComps[i] == null || comp == null) {
continue;
}
if (componentTray.IsTrayComponent(comp)) {
return false;
}
}
}
//ToolStripItems cannot be dropped on any ParentControlDesigners since they have custom DataObject Format.
if (de.Data is ToolStripItemDataObject)
{
return false;
}
return true;
}
private ToolboxItem CreateAxToolboxItem(IDataObject dataObject) {
AxToolboxItem tool = null;
// Read the stream out of the dataobject and get hold of the CLSID of the Toolbox item.
//
MemoryStream stm = (MemoryStream)dataObject.GetData(axClipFormat, true);
int len = (int)stm.Length;
byte[] bytes = new byte[len];
stm.Read(bytes, 0, len);
string clsid = System.Text.Encoding.Default.GetString(bytes);
int index = clsid.IndexOf("}");
clsid = clsid.Substring(0, index+1);
Debug.WriteLineIf(AxToolSwitch.TraceVerbose, "\tCLSID of the Toolbox item: " + clsid);
// Look to see if we can find the Control key for this CLSID. If present, create a
// new AxToolboxItem and add it to the cache.
//
if (IsSupportedActiveXControl(clsid)) {
// Look to see if we have already cached the ToolboxItem.
//
if (axTools != null) {
tool = (AxToolboxItem)axTools[clsid];
if (tool != null) {
if (AxToolSwitch.TraceVerbose) Debug.WriteLine("Found AxToolboxItem in tool cache");
return tool;
}
}
tool = new AxToolboxItem(clsid);
if (axTools == null) {
axTools = new Hashtable();
}
axTools.Add(clsid, tool);
Debug.WriteLineIf(AxToolSwitch.TraceVerbose, "\tAdded AxToolboxItem");
return tool;
}
else {
return null;
}
}
private ToolboxItem CreateCfCodeToolboxItem(IDataObject dataObject) {
object serializationData = null;
serializationData = dataObject.GetData(OleDragDropHandler.NestedToolboxItemFormat, false);
if (serializationData != null) {
return (ToolboxItem)serializationData;
}
serializationData = dataObject.GetData(OleDragDropHandler.DataFormat, false);
if (serializationData != null) { //backcompat
return new OleDragDropHandler.CfCodeToolboxItem(serializationData); ;
}
return null;
}
///
///
/// Disposes of this designer.
///
protected override void Dispose(bool disposing) {
if (disposing) {
IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));
Debug.Assert(host != null, "Must have a designer host on dispose");
if (host != null) {
//Remove Adorner Window which hosts DropDowns.
ToolStripAdornerWindowService toolWindow = (ToolStripAdornerWindowService)GetService(typeof(ToolStripAdornerWindowService));
if (toolWindow != null)
{
toolWindow.Dispose();
host.RemoveService(typeof(ToolStripAdornerWindowService));
}
host.Activated -= new EventHandler(OnDesignerActivate);
host.Deactivated -= new EventHandler(OnDesignerDeactivate);
// If the tray wasn't destroyed, then we got some sort of inbalance
// in our add/remove calls. Don't sweat it, but do remove the tray.
//
if (componentTray != null) {
ISplitWindowService sws = (ISplitWindowService)GetService(typeof(ISplitWindowService));
if (sws != null) {
sws.RemoveSplitWindow(componentTray);
componentTray.Dispose();
componentTray = null;
}
host.RemoveService(typeof(ComponentTray));
}
IComponentChangeService cs = (IComponentChangeService)GetService(typeof(IComponentChangeService));
if (cs != null) {
cs.ComponentAdded -= new ComponentEventHandler(this.OnComponentAdded);
cs.ComponentChanged -= new ComponentChangedEventHandler(this.OnComponentChanged);
cs.ComponentRemoved -= new ComponentEventHandler(this.OnComponentRemoved);
}
if (undoEngine != null) {
undoEngine.Undoing -= new EventHandler(this.OnUndoing);
undoEngine.Undone -= new EventHandler(this.OnUndone);
}
if (toolboxCreator != null) {
IToolboxService toolbox = (IToolboxService)GetService(typeof(IToolboxService));
Debug.Assert(toolbox != null, "No toolbox service available");
if (toolbox != null) {
Debug.WriteLineIf(AxToolSwitch.TraceVerbose, "Removing DocumentDesigner as CLSID ToolboxItemCreator");
toolbox.RemoveCreator(axClipFormat, host);
Debug.WriteLineIf(AxToolSwitch.TraceVerbose, "Removing DocumentDesigner as CF_CODE ToolboxItemCreator");
toolbox.RemoveCreator(OleDragDropHandler.DataFormat, host);
Debug.WriteLineIf(AxToolSwitch.TraceVerbose, "Removing DocumentDesigner as CF_TOOLBOXITEM ToolboxItemCreator");
toolbox.RemoveCreator(OleDragDropHandler.NestedToolboxItemFormat, host);
}
toolboxCreator = null;
}
}
ISelectionService ss = (ISelectionService)GetService(typeof(ISelectionService));
if (ss != null) {
ss.SelectionChanged -= new EventHandler(this.OnSelectionChanged);
}
if (behaviorService != null) {
behaviorService.Dispose();
behaviorService = null;
}
if (selectionManager != null) {
selectionManager.Dispose();
selectionManager = null;
}
if (componentTray != null) {
if (host != null) {
ISplitWindowService sws = (ISplitWindowService)GetService(typeof(ISplitWindowService));
if (sws != null) {
sws.RemoveSplitWindow(componentTray);
}
}
componentTray.Dispose();
componentTray = null;
}
if (this.pbrsFwd != null) {
this.pbrsFwd.Dispose();
this.pbrsFwd = null;
}
if (frame != null) {
frame.Dispose();
frame = null;
}
if (commandSet != null) {
commandSet.Dispose();
commandSet = null;
}
if (inheritanceService != null) {
inheritanceService.Dispose();
inheritanceService = null;
}
if (inheritanceUI != null) {
inheritanceUI.Dispose();
inheritanceUI = null;
}
if (designBindingValueUIHandler != null) {
IPropertyValueUIService pvUISvc = (IPropertyValueUIService)GetService(typeof(IPropertyValueUIService));
if (pvUISvc != null) {
pvUISvc.RemovePropertyValueUIHandler(new PropertyValueUIHandler(designBindingValueUIHandler.OnGetUIValueItem));
pvUISvc = null;
}
designBindingValueUIHandler.Dispose();
designBindingValueUIHandler = null;
}
if (designerExtenders != null) {
designerExtenders.Dispose();
designerExtenders = null;
}
if (axTools != null) {
axTools.Clear();
}
if (host != null) {
host.RemoveService(typeof(BehaviorService));
host.RemoveService(typeof(ToolStripAdornerWindowService));
host.RemoveService(typeof(SelectionManager));
host.RemoveService(typeof(IInheritanceService));
host.RemoveService(typeof(IEventHandlerService));
host.RemoveService(typeof(IOverlayService));
host.RemoveService(typeof(ISplitWindowService));
host.RemoveService(typeof(InheritanceUI));
}
}
base.Dispose(disposing);
}
///
///
/// Returns an array of Glyph objects representing the selection
/// borders and grab handles for the related Component. Note that
/// based on 'selType' the Glyphs returned will either: represent
/// a fully resizeable selection border with grab handles, a locked
/// selection border, or a single 'hidden' selection Glyph.
///
public override GlyphCollection GetGlyphs(GlyphSelectionType selectionType) {
GlyphCollection glyphs = new GlyphCollection();
if (selectionType != GlyphSelectionType.NotSelected) {
Point loc = BehaviorService.ControlToAdornerWindow((Control)Component);
Rectangle translatedBounds = new Rectangle(loc, ((Control)Component).Size);
bool primarySelection = (selectionType == GlyphSelectionType.SelectedPrimary);
bool locked = false;
PropertyDescriptor prop = TypeDescriptor.GetProperties(Component)["Locked"];
if (prop != null) {
locked = (bool)prop.GetValue(Component);
}
bool autoSize = false;
prop = TypeDescriptor.GetProperties(Component)["AutoSize"];
if (prop != null) {
autoSize = (bool)prop.GetValue(Component);
}
AutoSizeMode mode = AutoSizeMode.GrowOnly;
prop = TypeDescriptor.GetProperties(Component)["AutoSizeMode"];
if (prop != null) {
mode = (AutoSizeMode)prop.GetValue(Component);
}
SelectionRules rules = SelectionRules;
if (locked) {
// the lock glyph
glyphs.Add(new LockedHandleGlyph(translatedBounds, primarySelection));
//the four locked border glyphs
glyphs.Add(new LockedBorderGlyph(translatedBounds, SelectionBorderGlyphType.Top));
glyphs.Add(new LockedBorderGlyph(translatedBounds, SelectionBorderGlyphType.Bottom));
glyphs.Add(new LockedBorderGlyph(translatedBounds, SelectionBorderGlyphType.Left));
glyphs.Add(new LockedBorderGlyph(translatedBounds, SelectionBorderGlyphType.Right));
}
// we check if the control is a form because we only want to disable resizing
// for components that are not Forms.
else if (autoSize && (mode == AutoSizeMode.GrowAndShrink) && !(Control is Form)) {
//the non-resizeable grab handle
glyphs.Add(new NoResizeHandleGlyph(translatedBounds, rules, primarySelection, null));
//the four resizeable border glyphs
glyphs.Add(new NoResizeSelectionBorderGlyph(translatedBounds, rules, SelectionBorderGlyphType.Top, null));
glyphs.Add(new NoResizeSelectionBorderGlyph(translatedBounds, rules, SelectionBorderGlyphType.Bottom, null));
glyphs.Add(new NoResizeSelectionBorderGlyph(translatedBounds, rules, SelectionBorderGlyphType.Left, null));
glyphs.Add(new NoResizeSelectionBorderGlyph(translatedBounds, rules, SelectionBorderGlyphType.Right, null));
}
else {
glyphs.Add(new GrabHandleGlyph(translatedBounds, GrabHandleGlyphType.MiddleRight, StandardBehavior, primarySelection));
glyphs.Add(new GrabHandleGlyph(translatedBounds, GrabHandleGlyphType.LowerRight, StandardBehavior, primarySelection));
glyphs.Add(new GrabHandleGlyph(translatedBounds, GrabHandleGlyphType.MiddleBottom, StandardBehavior, primarySelection));
glyphs.Add(new SelectionBorderGlyph(translatedBounds, rules, SelectionBorderGlyphType.Top, null));
glyphs.Add(new SelectionBorderGlyph(translatedBounds, rules, SelectionBorderGlyphType.Bottom, StandardBehavior));
glyphs.Add(new SelectionBorderGlyph(translatedBounds, rules, SelectionBorderGlyphType.Left, null));
glyphs.Add(new SelectionBorderGlyph(translatedBounds, rules, SelectionBorderGlyphType.Right, StandardBehavior));
}
}
return glyphs;
}
///
/// Examines the current selection for a suitable frame designer. This
/// is used when we are creating a new component so we know what control
/// to parent the component to. This will always return a frame designer,
/// and may walk all the way up the control parent chain to this designer
/// if it needs to.
///
private ParentControlDesigner GetSelectedParentControlDesigner() {
ISelectionService s = (ISelectionService)GetService(typeof(ISelectionService));
ParentControlDesigner parentControlDesigner = null;
if (s != null) {
// We first try the primary selection. If that is null
// or isn't a Control, we then walk the set of selected
// objects. Failing all of this, we default to us.
//
object sel = s.PrimarySelection;
if (sel == null || !(sel is Control)) {
sel = null;
ICollection sels = s.GetSelectedComponents();
foreach(object obj in sels) {
if (obj is Control) {
sel = obj;
break;
}
}
}
if (sel != null) {
// Now that we have our currently selected component
// we can walk up the parent chain looking for a frame
// designer.
//
Debug.Assert(sel is Control, "Our logic is flawed - sel should be a Control");
Control c = (Control)sel;
IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));
if (host != null) {
while (c != null) {
ParentControlDesigner designer = host.GetDesigner(c) as ParentControlDesigner;
if (designer != null) {
parentControlDesigner = designer;
break;
}
c = c.Parent;
}
}
}
}
if (parentControlDesigner == null) {
parentControlDesigner = this;
}
return parentControlDesigner;
}
///
///
/// Determines if the given tool is supported by this designer.
/// If a tool is supported then it will be enabled in the toolbox
/// when this designer regains focus. Otherwise, it will be disabled.
/// Once a tool is marked as enabled or disabled it may not be
/// queried again.
///
protected virtual bool GetToolSupported(ToolboxItem tool) {
return true;
}
///
///
/// Initializes the designer with the given component. The designer can
/// get the component's site and request services from it in this call.
///
public override void Initialize(IComponent component) {
initializing = true;
base.Initialize(component);
initializing = false;
// If the back color of the control has not been established, force it to be
// "Control" so it doesn't walk up the parent chain and grab the document window's
// back color.
//
PropertyDescriptor backProp = TypeDescriptor.GetProperties(Component.GetType())["BackColor"];
if (backProp != null && backProp.PropertyType == typeof(Color) && !backProp.ShouldSerializeValue(Component)) {
Control.BackColor = SystemColors.Control;
}
IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));
IExtenderProviderService exps = (IExtenderProviderService)GetService(typeof(IExtenderProviderService));
if (exps != null) {
designerExtenders = new DesignerExtenders(exps);
}
if (host != null) {
host.Activated += new EventHandler(OnDesignerActivate);
host.Deactivated += new EventHandler(OnDesignerDeactivate);
ServiceCreatorCallback callback = new ServiceCreatorCallback(this.OnCreateService);
host.AddService(typeof(IEventHandlerService), callback);
// M3.2 CONTROL ARRAY IS CUT
// Create the view for this component. We first create the designer frame so we can provide
// the overlay and split window services, and then later on we initilaize the frame with
// the designer view.
//
frame = new DesignerFrame(component.Site);
IOverlayService os = (IOverlayService)frame;
host.AddService(typeof(IOverlayService), os);
host.AddService(typeof(ISplitWindowService), frame);
behaviorService = new BehaviorService(Component.Site, frame);
host.AddService(typeof(BehaviorService), behaviorService);
selectionManager = new SelectionManager(host, behaviorService);
host.AddService(typeof(SelectionManager), selectionManager);
host.AddService(typeof(ToolStripAdornerWindowService), callback);
// And component add and remove events for our tray
//
IComponentChangeService cs = (IComponentChangeService)GetService(typeof(IComponentChangeService));
if (cs != null) {
cs.ComponentAdded += new ComponentEventHandler(this.OnComponentAdded);
cs.ComponentChanged += new ComponentChangedEventHandler(this.OnComponentChanged);
cs.ComponentRemoved += new ComponentEventHandler(this.OnComponentRemoved);
}
// We must do the ineritance scan early, but not so early that we haven't hooked events
// to handle invisible components. We also use the variable "inheritanceService"
// as a check in OnCreateHandle -- we cannot call base.OnCreateHandle if we have
// not done an inheritance scan yet, because this will cause the base control
// class to hook all of the controls we may want to inherit. So, we do the
// scan, assign the variable, and then call OnCreateHandle if needed.
//
inheritanceUI = new InheritanceUI();
host.AddService(typeof(InheritanceUI), inheritanceUI);
InheritanceService isvc = new DocumentInheritanceService(this);
host.AddService(typeof(IInheritanceService), isvc);
isvc.AddInheritedComponents(component, component.Site.Container);
inheritanceService = isvc;
if (Control.IsHandleCreated) {
OnCreateHandle();
}
IPropertyValueUIService pvUISvc = (IPropertyValueUIService)component.Site.GetService(typeof(IPropertyValueUIService));
if (pvUISvc != null) {
designBindingValueUIHandler = new DesignBindingValueUIHandler();
pvUISvc.AddPropertyValueUIHandler(new PropertyValueUIHandler(designBindingValueUIHandler.OnGetUIValueItem));
}
// Add the DocumentDesigner as a creator of CLSID toolbox items.
//
IToolboxService toolbox = (IToolboxService)host.GetService(typeof(IToolboxService));
if (toolbox != null) {
Debug.WriteLineIf(AxToolSwitch.TraceVerbose, "Adding DocumentDesigner as CLSID ToolboxItemCreator");
toolboxCreator = new ToolboxItemCreatorCallback(this.OnCreateToolboxItem);
toolbox.AddCreator(toolboxCreator, axClipFormat, host);
toolbox.AddCreator(toolboxCreator, OleDragDropHandler.DataFormat, host);
toolbox.AddCreator(toolboxCreator, OleDragDropHandler.NestedToolboxItemFormat, host);
}
// Listen for the completed load. When finished, we need to select the form. We don'
// want to do it before we're done, however, or else the dimensions of the selection rectangle
// could be off because during load, change events are not fired.
//
host.LoadComplete += new EventHandler(this.OnLoadComplete);
}
// Setup our menu command structure.
//
Debug.Assert(component.Site != null, "Designer host should have given us a site by now.");
commandSet = new ControlCommandSet(component.Site);
// Finally hook the designer view into the frame. We do this last because the frame may
// cause the control to be created, and if this happens before the inheritance scan we
// will subclass the inherited controls before we get a chance to attach designers.
//
frame.Initialize(Control);
this.pbrsFwd = new PbrsForward(frame, component.Site);
// And force some shadow properties that we change in the course of
// initializing the form.
//
Location = new Point(0, 0);
}
///
/// Checks to see if the give CLSID is an ActiveX control
/// that we support. This ignores designtime controls.
///
private bool IsSupportedActiveXControl(string clsid) {
RegistryKey key = null;
RegistryKey designtimeKey = null;
try {
string controlKey = "CLSID\\" + clsid + "\\Control";
key = Registry.ClassesRoot.OpenSubKey(controlKey);
if (key != null) {
// ASURT 36817:
// We are not going to support design-time controls for this revision. We use the guids under
// HKCR\Component Categories to decide which categories to avoid. Currently the only one is
// the "HTML Design-time Control" category implemented by VID controls.
//
string category = "CLSID\\" + clsid + "\\Implemented Categories\\{" + htmlDesignTime.ToString() + "}";
designtimeKey = Registry.ClassesRoot.OpenSubKey(category);
return(designtimeKey == null);
}
return false;
}
finally {
if (key != null)
key.Close();
if (designtimeKey != null)
designtimeKey.Close();
}
}
private void OnUndone(object source, EventArgs e) {
//resume all suspended comps we found earlier
if (suspendedComponents != null) {
foreach (Control c in suspendedComponents) {
c.ResumeLayout(false/*performLayout*/);
c.PerformLayout();
}
}
}
private void OnUndoing(object source, EventArgs e) {
// attempt to suspend all components within the icontainer
// plus the root component's parent.
//
IDesignerHost host = GetService(typeof(IDesignerHost)) as IDesignerHost;
if (host != null) {
IContainer container = host.Container;
if (container != null) {
suspendedComponents = new ArrayList(container.Components.Count + 1);
foreach (IComponent comp in container.Components) {
Control control = comp as Control;
if (control != null) {
control.SuspendLayout();
//add this control to our suspended components list so we can resume
//later
suspendedComponents.Add(control);
}
}
// Also suspend the rooot component's parent.
Control root = host.RootComponent as Control;
if (root != null) {
Control rootParent = root.Parent as Control;
if (rootParent != null) {
rootParent.SuspendLayout();
suspendedComponents.Add(rootParent);
}
}
}
}
}
///
/// Called when a component is added to the design container.
/// If the component isn't a control, this will demand create
/// the component tray and add the component to it.
///
private void OnComponentAdded(object source, ComponentEventArgs ce) {
IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));
if (host != null) {
IComponent component = ce.Component;
//if the component is a contextMenu - we'll start of the service
EnsureMenuEditorService(ce.Component);
bool addControl = true;
// This is the mirror to logic in ParentControlDesigner. The component should be
// added somewhere, and this logic decides where.
//
// LETS SEE IF WE ARE TOOLSTRIP in which case we want to get added
// to the componentTray even though this is a control..
// We should think of implementing an interface so that we can have many more
// controls behaving like this.
//
ToolStripDesigner td = host.GetDesigner(component) as ToolStripDesigner;
if (td == null) {
ControlDesigner cd = host.GetDesigner(component) as ControlDesigner;
if (cd != null) {
Form form = cd.Control as Form;
if (form == null || !form.TopLevel) {
addControl = false;
}
}
}
if (addControl &&
TypeDescriptor.GetAttributes(component).Contains(DesignTimeVisibleAttribute.Yes)) {
if (componentTray == null) {
ISplitWindowService sws = (ISplitWindowService)GetService(typeof(ISplitWindowService));
if (sws != null) {
componentTray = new ComponentTray(this, Component.Site);
sws.AddSplitWindow(componentTray);
componentTray.Height = trayHeight;
componentTray.ShowLargeIcons = trayLargeIcon;
componentTray.AutoArrange = trayAutoArrange;
host.AddService(typeof(ComponentTray), componentTray);
}
}
if (componentTray != null) {
// Suspend the layout of the tray through the loading
// process. This way, we won't continuosly try to layout
// components in auto arrange mode. We will instead let
// the controls restore themselves to their persisted state
// and then let auto-arrange kick in once.
//
if (host != null && host.Loading && !trayLayoutSuspended) {
trayLayoutSuspended = true;
componentTray.SuspendLayout();
}
componentTray.AddComponent(component);
}
}
}
}
///
/// Called when a component is removed from the design container.
/// Here we check to see there are no more components on the tray
/// and if not, we will remove the tray.
///
private void OnComponentRemoved(object source, ComponentEventArgs ce) {
// ToolStrip is designableAsControl but has a ComponentTray Entry ... so special case it out.
bool designableAsControl = (ce.Component is Control && !(ce.Component is ToolStrip)) && !(ce.Component is Form && ((Form)ce.Component).TopLevel);
if (!designableAsControl && componentTray != null) {
componentTray.RemoveComponent(ce.Component);
if (componentTray.ComponentCount == 0) {
ISplitWindowService sws = (ISplitWindowService)GetService(typeof(ISplitWindowService));
if (sws != null) {
sws.RemoveSplitWindow(componentTray);
IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));
if (host != null) {
host.RemoveService(typeof(ComponentTray));
}
componentTray.Dispose();
componentTray = null;
}
}
}
}
///
///
/// Called when the context menu should be displayed. This displays the document
/// context menu.
///
protected override void OnContextMenu(int x, int y) {
IMenuCommandService mcs = (IMenuCommandService)GetService(typeof(IMenuCommandService));
if (mcs != null) {
ISelectionService selSvc = (ISelectionService)GetService(typeof(ISelectionService));
if (selSvc != null) {
// Here we check to see if we're the only component selected. If not, then
// we'll display the standard component menu.
//
if (selSvc.SelectionCount == 1 && selSvc.GetComponentSelected(Component)) {
mcs.ShowContextMenu(MenuCommands.ContainerMenu, x, y);
}
// Try to see if the component selected has a contextMenuStrip to show
else
{
Component selComp = selSvc.PrimarySelection as Component;
if (selComp != null)
{
IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));
if (host != null)
{
ComponentDesigner compDesigner = host.GetDesigner(selComp) as ComponentDesigner;
if (compDesigner != null)
{
compDesigner.ShowContextMenu(x, y);
return;
}
}
}
mcs.ShowContextMenu(MenuCommands.SelectionMenu, x, y);
}
}
}
}
///
///
/// This is called immediately after the control handle has been created.
///
protected override void OnCreateHandle() {
// Don't call base unless our inheritance serivce is already running.
if (inheritanceService != null) {
base.OnCreateHandle();
}
}
///
/// Creates some of the more infrequently used services we offer.
///
private object OnCreateService(IServiceContainer container, Type serviceType) {
if (serviceType == typeof(IEventHandlerService)) {
if (eventHandlerService == null) {
eventHandlerService = new EventHandlerService(frame);
}
return eventHandlerService;
}
else if (serviceType == typeof(ToolStripAdornerWindowService)) {
return new ToolStripAdornerWindowService(Component.Site, frame);
}
Debug.Fail("Called back to create a service we don't know how to create: " + serviceType.Name);
return null;
}
///
/// Called when our document becomes active. We paint our form's
/// border the appropriate color here.
///
private ToolboxItem OnCreateToolboxItem(object serializedData, string format) {
Debug.WriteLineIf(AxToolSwitch.TraceVerbose, "Checking to see if: " + format + " is supported.");
IDataObject dataObject = serializedData as IDataObject;
if (dataObject == null) {
Debug.Fail("Toolbox service didn't pass us a data object; that should never happen");
return null;
}
// CLSID format.
//
if (format.Equals(axClipFormat)) {
return CreateAxToolboxItem(dataObject);
}
// CF_CODE format
//
if (format.Equals(OleDragDropHandler.DataFormat) ||
format.Equals(OleDragDropHandler.NestedToolboxItemFormat)) {
return CreateCfCodeToolboxItem(dataObject);
}
return null;
}
///
/// Called when our document becomes active. Here we try to
/// select the appropriate toolbox tab.
///
private void OnDesignerActivate(object source, EventArgs evevent) {
if (undoEngine == null) {
undoEngine = GetService(typeof(UndoEngine)) as UndoEngine;
if (undoEngine != null) {
undoEngine.Undoing += new EventHandler(this.OnUndoing);
undoEngine.Undone += new EventHandler(this.OnUndone);
}
}
}
///
/// Called by the host when we become inactive. Here we update the
/// title bar of our form so it's the inactive color.
///
private void OnDesignerDeactivate(object sender, EventArgs e) {
Control control = Control;
if (control != null && control.IsHandleCreated) {
NativeMethods.SendMessage(control.Handle, NativeMethods.WM_NCACTIVATE, 0, 0);
SafeNativeMethods.RedrawWindow(control.Handle, null, IntPtr.Zero, NativeMethods.RDW_FRAME);
}
}
///
/// Called when the designer is finished loading. Here we select the form.
///
private void OnLoadComplete(object sender, EventArgs e) {
// Remove the handler; we're done looking at this.
//
((IDesignerHost)sender).LoadComplete -= new EventHandler(this.OnLoadComplete);
// Restore the tray layout.
//
if (trayLayoutSuspended && componentTray != null)
componentTray.ResumeLayout();
// Select this component.
//
ISelectionService ss = (ISelectionService)GetService(typeof(ISelectionService));
if (ss != null) {
ss.SelectionChanged += new EventHandler(this.OnSelectionChanged);
ss.SetSelectedComponents(new object[] {Component}, SelectionTypes.Replace);
Debug.Assert(ss.PrimarySelection == Component, "Bug in selection service: form should have primary selection.");
}
}
private void OnComponentChanged(object sender, ComponentChangedEventArgs e) {
Control ctrl = e.Component as Control;
if (ctrl != null && ctrl.IsHandleCreated) {
UnsafeNativeMethods.NotifyWinEvent((int)AccessibleEvents.LocationChange, new HandleRef(ctrl, ctrl.Handle), NativeMethods.OBJID_CLIENT, 0);
if (this.frame.Focused) {
UnsafeNativeMethods.NotifyWinEvent((int)AccessibleEvents.Focus, new HandleRef(ctrl, ctrl.Handle), NativeMethods.OBJID_CLIENT, 0);
}
}
}
///
/// Called by the selection service when the selection has changed. We do a number
/// of selection-related things here.
///
private void OnSelectionChanged(Object sender, EventArgs e) {
ISelectionService svc = (ISelectionService)GetService( typeof(ISelectionService) );
if (svc != null) {
ICollection selComponents = svc.GetSelectedComponents();
// Setup the correct active accessibility selection / focus data
//
Debug.WriteLineIf(CompModSwitches.MSAA.TraceInfo, "MSAA: SelectionChanged");
foreach(object selObj in selComponents) {
Control c = selObj as Control;
if (c != null) {
Debug.WriteLineIf(CompModSwitches.MSAA.TraceInfo, "MSAA: SelectionAdd, control = " + c.ToString());
UnsafeNativeMethods.NotifyWinEvent((int)AccessibleEvents.SelectionAdd, new HandleRef(c, c.Handle), NativeMethods.OBJID_CLIENT, 0);
}
}
Control primary = svc.PrimarySelection as Control;
if (primary != null) {
Debug.WriteLineIf(CompModSwitches.MSAA.TraceInfo, "MSAA: Focus, control = " + primary.ToString());
UnsafeNativeMethods.NotifyWinEvent((int)AccessibleEvents.Focus, new HandleRef(primary, primary.Handle), NativeMethods.OBJID_CLIENT, 0);
}
// see if there are visual controls selected. If so, we add a context attribute.
// Otherwise, we remove the attribute. We do not count the form.
//
IHelpService hs = (IHelpService)GetService(typeof(IHelpService));
if (hs != null) {
ushort type = 0;
string[] types = new string[] {
"VisualSelection",
"NonVisualSelection",
"MixedSelection"
};
foreach(object obj in selComponents) {
if (obj is Control) {
if (obj != Component) {
type |= 1;
}
}
else {
type |= 2;
}
if (type == 3) {
break;
}
}
// Remove any prior attribute
//
for (int i = 0; i < types.Length; i++) {
hs.RemoveContextAttribute("Keyword", types[i]);
}
if (type != 0) {
hs.AddContextAttribute("Keyword", types[type - 1], HelpKeywordType.GeneralKeyword);
}
}
// Activate / deactivate the menu editor.
//
if (menuEditorService != null)
DoProperMenuSelection(selComponents);
}
}
internal virtual void DoProperMenuSelection(ICollection selComponents) {
foreach(object obj in selComponents) {
ContextMenu cm = obj as ContextMenu;
if (cm != null) {
menuEditorService.SetMenu((Menu)obj);
}
else {
MenuItem item = obj as MenuItem;
if (item != null) {
//before we set the selection, we need to check if the item belongs the current menu,
//if not, we need to set the menu editor to the appropiate menu, then set selection
//
MenuItem parent = item;
while (parent.Parent is MenuItem) {
parent = (MenuItem)parent.Parent;
}
if(menuEditorService.GetMenu() != parent.Parent) {
menuEditorService.SetMenu(parent.Parent);
}
//ok, here we have the correct editor selected for this item.
//Now, if there's only one item selected, then let the editor service know,
//if there is more than one - then the selection was done through the
//menu editor and we don't need to tell it
if(selComponents.Count == 1) {
menuEditorService.SetSelection(item);
}
}
//Here, something is selected, but the menuservice isn't interested
//so, we'll collapse our active menu accordingly
else menuEditorService.SetMenu(null);
}
}
}
///
///
/// Determines if a MenuEditorService has already been started. If not,
/// this method will create a new instance of the service.
///
protected virtual void EnsureMenuEditorService(IComponent c) {
if (menuEditorService == null && c is ContextMenu) {
menuEditorService = (IMenuEditorService)GetService(typeof(IMenuEditorService));
}
}
///
///
/// Allows a designer to filter the set of properties
/// the component it is designing will expose through the
/// TypeDescriptor object. This method is called
/// immediately before its corresponding "Post" method.
/// If you are overriding this method you should call
/// the base implementation before you perform your own
/// filtering.
///
protected override void PreFilterProperties(IDictionary properties) {
PropertyDescriptor prop;
base.PreFilterProperties(properties);
// Add any properties that the Tray will persist.
properties["TrayHeight"] = TypeDescriptor.CreateProperty(typeof(DocumentDesigner), "TrayHeight", typeof(int),
BrowsableAttribute.No,
DesignOnlyAttribute.Yes,
new SRDescriptionAttribute("FormDocumentDesignerTraySizeDescr"),
CategoryAttribute.Design);
properties["TrayLargeIcon"] = TypeDescriptor.CreateProperty(typeof(DocumentDesigner), "TrayLargeIcon", typeof(bool),
BrowsableAttribute.No,
DesignOnlyAttribute.Yes,
CategoryAttribute.Design);
// Expose the doublebuffered property on control
properties["DoubleBuffered"] = TypeDescriptor.CreateProperty(typeof(Control), "DoubleBuffered", typeof(bool),
BrowsableAttribute.Yes,
DesignOnlyAttribute.No);
// Handle shadowed properties
//
string[] shadowProps = new string[] {
"Location",
"BackColor"
};
string[] noBrowseProps = new string[] {
"Anchor",
"Dock",
"TabIndex",
"TabStop",
"Visible"
};
Attribute[] empty = new Attribute[0];
for (int i = 0; i < shadowProps.Length; i++) {
prop = (PropertyDescriptor)properties[shadowProps[i]];
if (prop != null) {
properties[shadowProps[i]] = TypeDescriptor.CreateProperty(typeof(DocumentDesigner), prop, empty);
}
}
prop = (PropertyDescriptor)properties["AutoScaleDimensions"];
if (prop != null) {
properties["AutoScaleDimensions"] = TypeDescriptor.CreateProperty(typeof(DocumentDesigner), prop, DesignerSerializationVisibilityAttribute.Visible);
}
prop = (PropertyDescriptor)properties["AutoScaleMode"];
if (prop != null) {
properties["AutoScaleMode"] = TypeDescriptor.CreateProperty(typeof(DocumentDesigner), prop, DesignerSerializationVisibilityAttribute.Visible, BrowsableAttribute.Yes);
}
for (int i = 0; i < noBrowseProps.Length; i++) {
prop = (PropertyDescriptor)properties[noBrowseProps[i]];
if (prop != null) {
properties[noBrowseProps[i]] = TypeDescriptor.CreateProperty(prop.ComponentType, prop, BrowsableAttribute.No, DesignerSerializationVisibilityAttribute.Hidden);
}
}
}
///
/// Resets the back color to be based on the parent's back color.
///
private void ResetBackColor() {
BackColor = Color.Empty;
}
private bool ShouldSerializeAutoScaleDimensions() {
// Visual inheritance always adds default
// value attributes that adopt the current values. This
// isn't right for auto scale, however,because we always
// want to write out the auto scale values. So, we have
// to be a bit sleazy here and trick the inheritance engine
// to think that these properties currently have their
// default values.
return !initializing && AutoScaleMode != AutoScaleMode.None && AutoScaleMode != AutoScaleMode.Inherit;
}
private bool ShouldSerializeAutoScaleMode() {
// Visual inheritance always adds default
// value attributes that adopt the current values. This
// isn't right for auto scale, however,because we always
// want to write out the auto scale values. So, we have
// to be a bit sleazy here and trick the inheritance engine
// to think that these properties currently have their
// default values.
return !initializing && ShadowProperties.Contains("AutoScaleMode");
}
///
/// Returns true if the BackColor property should be persisted in code gen.
///
private bool ShouldSerializeBackColor() {
// We push Color.Empty into our shadow cash during
// init and also whenever we are reset. We do this
// so we can push a real color into the controls
// back color to stop it from walking the parent chain.
// But, we want it to look like we didn't push a color
// so code gen won't write out "Color.Control"
if (!ShadowProperties.Contains("BackColor") || ((Color)ShadowProperties["BackColor"]).IsEmpty) {
return false;
}
return true;
}
///
///
/// This will be called when the user double-clicks on a
/// toolbox item. The document designer should create
/// a component for the given tool.
///
protected virtual void ToolPicked(ToolboxItem tool) {
// If the tab order UI is showing, don't allow us to place a tool.
//
IMenuCommandService mcs = (IMenuCommandService)GetService(typeof(IMenuCommandService));
if (mcs != null) {
MenuCommand cmd = mcs.FindCommand(StandardCommands.TabOrder);
if (cmd != null && cmd.Checked) {
return;
}
}
IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));
if (host != null) {
host.Activate();
}
// Just find the currently selected frame designer and ask it to create the tool.
//
try {
ParentControlDesigner designer = GetSelectedParentControlDesigner();
if (!InvokeGetInheritanceAttribute(designer).Equals(InheritanceAttribute.InheritedReadOnly)) {
InvokeCreateTool(designer, tool);
IToolboxService toolboxService = (IToolboxService)GetService(typeof(IToolboxService));
if (toolboxService != null) {
toolboxService.SelectedToolboxItemUsed();
}
}
}
catch(Exception e) {
DisplayError(e);
if (ClientUtils.IsCriticalException(e)) {
throw;
}
}
catch {
Debug.Fail("non-CLS compliant exception");
}
}
///
///
///
/// The list of technologies that this designer can support
/// for its view. Examples of different technologies are
/// WinForms and Web Forms. Other object models can be
/// supported at design time, but they most be able to
/// provide a view in one of the supported technologies.
///
ViewTechnology[] IRootDesigner.SupportedTechnologies {
get {
return new ViewTechnology[] {ViewTechnology.Default, (ViewTechnology)1};
}
}
///
///
///
/// The view for this document. The designer
/// should assume that the view will be shown shortly
/// after this call is made and make any necessary
/// preparations.
///
//We can live with this one. We have obsoleted some of the enum values. This method
//only takes on argument, so it is pretty obvious what argument is bad.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")]
object IRootDesigner.GetView(ViewTechnology technology) {
if (technology != ViewTechnology.Default && technology != (ViewTechnology)1) {
throw new ArgumentException();
}
return frame;
}
///
///
///
/// Gets a value indicating whether the specified tool is supported by the current
/// designer.
///
//
bool IToolboxUser.GetToolSupported(ToolboxItem tool) {
return GetToolSupported(tool);
}
///
///
///
/// Selects the specified tool.
///
void IToolboxUser.ToolPicked(ToolboxItem tool) {
ToolPicked(tool);
}
///
/// Handles the WM_WINDOWPOSCHANGING message
///
///
private unsafe void WmWindowPosChanged(ref Message m) {
NativeMethods.WINDOWPOS* wp = (NativeMethods.WINDOWPOS *)m.LParam;
if ((wp->flags & NativeMethods.SWP_NOSIZE) == 0 && menuEditorService != null) {
BehaviorService.SyncSelection();
}
}
///
///
/// Overrides our base class WndProc to provide support for
/// the menu editor service.
///
protected override void WndProc(ref Message m) {
if( menuEditorService != null) {
// We want to pass the messages to the menu editor unless the taborder view is active
// and the message will activate the menu editor (wm_ncXbuttondown messages)
//
if (!(TabOrderActive && (m.Msg == NativeMethods.WM_NCLBUTTONDOWN || m.Msg == NativeMethods.WM_NCRBUTTONDOWN))) {
if(menuEditorService.MessageFilter(ref m)) {
return;
}
}
}
base.WndProc(ref m);
if (m.Msg == NativeMethods.WM_WINDOWPOSCHANGED) {
WmWindowPosChanged(ref m);
}
}
//
//
//
// Toolbox item we implement so we can create ActiveX controls.
//
//
//
[Serializable]
private class AxToolboxItem : ToolboxItem {
private string clsid;
private Type axctlType = null;
private string version = String.Empty;
public AxToolboxItem(string clsid) : base(typeof(AxHost)) {
this.clsid = clsid;
this.Company = null; //we don't get any company info for ax controls.
LoadVersionInfo();
}
// Since we don't call the base constructor here, which does call Deserialize which we
// override, we should be okay.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
private AxToolboxItem(SerializationInfo info, StreamingContext context) {
Deserialize(info, context);
}
///
///
/// The Component Type is ".Net Component" -- unless otherwise specified by a derived toolboxitem
///
public override string ComponentType {
get {
return SR.GetString(SR.Ax_Control);
}
}
public override string Version {
get {
return version;
}
}
private void LoadVersionInfo() {
string controlKey = "CLSID\\" + clsid;
RegistryKey key = Registry.ClassesRoot.OpenSubKey(controlKey);
//fail later -- not for tooltip info...
if (key != null) {
RegistryKey verKey = key.OpenSubKey("Version");
if (verKey != null) {
version = (string)verKey.GetValue("");
}
}
}
///
///
/// Creates an instance of the ActiveX control. Calls VS7 project system
/// to generate the wrappers if they are needed..
///
protected override IComponent[] CreateComponentsCore(IDesignerHost host) {
IComponent[] comps = null;
Debug.Assert(host != null, "Designer host is null!!!");
// Get the DTE References object
//
object references = GetReferences(host);
if (references != null) {
try {
TYPELIBATTR tlibAttr = GetTypeLibAttr();
object[] args = new object[5];
args[0] = "{" + tlibAttr.guid.ToString() + "}";
args[1] = (int)tlibAttr.wMajorVerNum;
args[2] = (int)tlibAttr.wMinorVerNum;
args[3] = (int)tlibAttr.lcid;
args[4] = "";
object tlbRef = references.GetType().InvokeMember("AddActiveX", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, references, args, CultureInfo.InvariantCulture);
Debug.Assert(tlbRef != null, "Null reference returned by AddActiveX (tlbimp) by the project system for: " + clsid);
args[4] = "aximp";
object axRef = references.GetType().InvokeMember("AddActiveX", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, references, args, CultureInfo.InvariantCulture);
Debug.Assert(axRef != null, "Null reference returned by AddActiveX (aximp) by the project system for: " + clsid);
axctlType = GetAxTypeFromReference(axRef, host);
}
catch(TargetInvocationException tie) {
Debug.WriteLineIf(DocumentDesigner.AxToolSwitch.TraceVerbose, "Generating Ax References failed: " + tie.InnerException);
throw tie.InnerException;
}
catch(Exception e) {
Debug.WriteLineIf(DocumentDesigner.AxToolSwitch.TraceVerbose, "Generating Ax References failed: " + e);
throw e;
}
catch {
Debug.WriteLineIf(DocumentDesigner.AxToolSwitch.TraceVerbose, "Generating Ax References failed due to non-CLS compliant exception");
throw;
}
}
if (axctlType == null) {
IUIService uiSvc = (IUIService)host.GetService(typeof(IUIService));
if (uiSvc == null) {
RTLAwareMessageBox.Show(null, SR.GetString(SR.AxImportFailed), null, MessageBoxButtons.OK, MessageBoxIcon.Error,
MessageBoxDefaultButton.Button1, 0);
}
else {
uiSvc.ShowError(SR.GetString(SR.AxImportFailed));
}
return new IComponent[0];
}
comps = new IComponent[1];
try {
comps[0] = host.CreateComponent(axctlType);
}
catch (Exception e) {
Debug.Fail("Could not create type: " + e);
throw e;
}
catch {
throw;
}
Debug.Assert(comps[0] != null, "Could not create instance of ActiveX control wrappers!!!");
return comps;
}
///
///
/// Loads the state of this 'AxToolboxItem'
/// from the stream.
///
protected override void Deserialize(SerializationInfo info, StreamingContext context) {
base.Deserialize(info, context);
clsid = info.GetString("Clsid");
}
///
/// Gets hold of the DTE Reference object and from there, opens the assembly of the
/// ActiveX control we want to create. It then walks through all AxHost derived classes
/// in that assembly, and returns the type that matches our control's CLSID.
///
private Type GetAxTypeFromReference(object reference, IDesignerHost host) {
string path = (string)reference.GetType().InvokeMember("Path", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null, reference, null, CultureInfo.InvariantCulture);
// Missing reference will show up as an empty string.
//
if (path == null || path.Length <= 0) {
return null;
}
FileInfo file = new FileInfo(path);
string fullPath = file.FullName;
Debug.WriteLineIf(AxToolSwitch.TraceVerbose, "Checking: " + fullPath);
ITypeResolutionService trs = (ITypeResolutionService)host.GetService(typeof(ITypeResolutionService));
Debug.Assert(trs != null, "No type resolution service found.");
Assembly a = trs.GetAssembly(AssemblyName.GetAssemblyName(fullPath));
Debug.Assert(a != null, "No assembly found at " + fullPath);
return GetAxTypeFromAssembly(a);
}
///
/// Walks through all AxHost derived classes in the given assembly,
/// and returns the type that matches our control's CLSID.
///
private Type GetAxTypeFromAssembly(Assembly a) {
Type[] types = a.GetTypes();
int len = types.Length;
for (int i = 0; i < len; ++i) {
Type t = types[i];
if (!(typeof(AxHost).IsAssignableFrom(t))) {
continue;
}
object[] attrs = t.GetCustomAttributes(typeof(AxHost.ClsidAttribute), false);
Debug.Assert(attrs != null && attrs.Length == 1, "Invalid number of GuidAttributes found on: " + t.FullName);
AxHost.ClsidAttribute guid = (AxHost.ClsidAttribute)attrs[0];
if (String.Equals(guid.Value, clsid, StringComparison.OrdinalIgnoreCase)) {
return t;
}
}
return null;
}
///
/// Gets the References collection object from the designer host. The steps are:
/// Get the ProjectItem from the IDesignerHost.
/// Get the Containing Project of the ProjectItem.
/// Get the VSProject of the Containing Project.
/// Get the References property of the VSProject.
///
private object GetReferences(IDesignerHost host) {
Debug.Assert(host != null, "Null Designer Host");
Type type;
object ext = null;
type = Type.GetType("EnvDTE.ProjectItem, " + AssemblyRef.EnvDTE);
if (type == null) {
return null;
}
ext = host.GetService(type);
if (ext == null)
return null;
string name = ext.GetType().InvokeMember("Name", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null, ext, null, CultureInfo.InvariantCulture).ToString();
object project = ext.GetType().InvokeMember("ContainingProject", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null, ext, null, CultureInfo.InvariantCulture);
Debug.Assert(project != null, "No DTE Project for the current project item: " + name);
object vsproject = project.GetType().InvokeMember("Object", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null, project, null, CultureInfo.InvariantCulture);
Debug.Assert(vsproject != null, "No VS Project for the current project item: " + name);
object references = vsproject.GetType().InvokeMember("References", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null, vsproject, null, CultureInfo.InvariantCulture);
Debug.Assert(references != null, "No References for the current project item: " + name);
return references;
}
///
/// Gets the TypeLibAttr corresponding to the TLB containing our ActiveX control.
///
private TYPELIBATTR GetTypeLibAttr() {
string controlKey = "CLSID\\" + clsid;
RegistryKey key = Registry.ClassesRoot.OpenSubKey(controlKey);
if (key == null) {
if (DocumentDesigner.AxToolSwitch.TraceVerbose) Debug.WriteLine("No registry key found for: " + controlKey);
throw new ArgumentException(SR.GetString(SR.AXNotRegistered, controlKey.ToString()));
}
// Load the typelib into memory.
//
ITypeLib pTLB = null;
// Try to get the TypeLib's Guid.
//
Guid tlbGuid = Guid.Empty;
// Open the key for the TypeLib
//
RegistryKey tlbKey = key.OpenSubKey("TypeLib");
if (tlbKey != null) {
// Get the major and minor version numbers.
//
RegistryKey verKey = key.OpenSubKey("Version");
Debug.Assert(verKey != null, "No version registry key found for: " + controlKey);
short majorVer = -1;
short minorVer = -1;
string ver = (string)verKey.GetValue("");
int dot = ver.IndexOf('.');
if (dot == -1) {
majorVer = Int16.Parse(ver, CultureInfo.InvariantCulture);
minorVer = 0;
}
else {
majorVer = Int16.Parse(ver.Substring(0, dot), CultureInfo.InvariantCulture);
minorVer = Int16.Parse(ver.Substring(dot + 1, ver.Length - dot - 1), CultureInfo.InvariantCulture);
}
Debug.Assert(majorVer > 0 && minorVer >= 0, "No Major version number found for: " + controlKey);
verKey.Close();
object o = tlbKey.GetValue("");
tlbGuid = new Guid((string)o);
Debug.Assert(!tlbGuid.Equals(Guid.Empty), "No valid Guid found for: " + controlKey);
tlbKey.Close();
try {
pTLB = NativeMethods.LoadRegTypeLib(ref tlbGuid, majorVer, minorVer, Application.CurrentCulture.LCID);
}
catch (Exception e) {
if (AxWrapperGen.AxWrapper.Enabled) Debug.WriteLine("Failed to LoadRegTypeLib: " + e.ToString());
if (ClientUtils.IsCriticalException(e)) {
throw;
}
}
catch {
Debug.Fail("non-CLS compliant exception");
}
}
// Try to load the TLB directly from the InprocServer32.
//
// If that fails, try to load the TLB based on the TypeLib guid key.
//
if (pTLB == null) {
RegistryKey inprocServerKey = key.OpenSubKey("InprocServer32");
if (inprocServerKey != null) {
string inprocServer = (string)inprocServerKey.GetValue("");
Debug.Assert(inprocServer != null, "No valid InprocServer32 found for: " + controlKey);
inprocServerKey.Close();
pTLB = NativeMethods.LoadTypeLib(inprocServer);
}
}
key.Close();
if (pTLB != null) {
try {
IntPtr pTlibAttr = NativeMethods.InvalidIntPtr;
pTLB.GetLibAttr(out pTlibAttr);
if (pTlibAttr == NativeMethods.InvalidIntPtr)
throw new ArgumentException(SR.GetString(SR.AXNotRegistered, controlKey.ToString()));
else {
// Marshal the returned int as a TLibAttr structure
//
TYPELIBATTR typeLibraryAttributes = (TYPELIBATTR) Marshal.PtrToStructure(pTlibAttr, typeof(TYPELIBATTR));
pTLB.ReleaseTLibAttr(pTlibAttr);
return typeLibraryAttributes;
}
}
finally {
Marshal.ReleaseComObject(pTLB);
}
}
else {
throw new ArgumentException(SR.GetString(SR.AXNotRegistered, controlKey.ToString()));
}
}
///
///
/// Saves the state of this 'AxToolboxItem' to
/// the specified serialization info.
///
protected override void Serialize(SerializationInfo info, StreamingContext context) {
if (DocumentDesigner.AxToolSwitch.TraceVerbose) Debug.WriteLine("Serializing AxToolboxItem:" + clsid);
base.Serialize(info, context);
info.AddValue("Clsid", clsid);
}
}
///
/// Document designer's version of the inheritance service. For UI
/// components, we will allow private controls if those controls are
/// children of our document, since they will be visible.
///
private class DocumentInheritanceService : InheritanceService {
private DocumentDesigner designer;
///
///
/// Creates a new document inheritance service.
///
public DocumentInheritanceService(DocumentDesigner designer) {
this.designer = designer;
}
///
///
/// Indicates the inherited members to ignore.
///
protected override bool IgnoreInheritedMember(MemberInfo member, IComponent component) {
// We allow private members if they are controls on our design surface or
// derive from Menu.
//
bool privateMember = false;
Type memberType = null;
FieldInfo field = member as FieldInfo;
MethodInfo method = member as MethodInfo;
if (field != null) {
privateMember = field.IsPrivate || field.IsAssembly;
memberType = field.FieldType;
}
else if (method != null) {
privateMember = method.IsPrivate || method.IsAssembly;
memberType = method.ReturnType;
}
else {
Debug.Fail("Unknown member type passed to IgnoreInheritedMember");
return true;
}
if (privateMember) {
if (typeof(Control).IsAssignableFrom(memberType)) {
// See if this member is a child of our document...
//
Control child = null;
if (field != null) {
child = (Control)field.GetValue(component);
}
else if (method != null) {
child = (Control)method.Invoke(component, null);
}
Control parent = designer.Control;
while (child != null && child != parent) {
child = child.Parent;
}
// If it is a child of our designer, we don't want to ignore this member.
//
if (child != null) {
return false;
}
}
else if (typeof(Menu).IsAssignableFrom(memberType)) {
object menu = null;
if (field != null) {
menu = field.GetValue(component);
}
else if (method != null) {
menu = method.Invoke(component, null);
}
if (menu != null) {
return false;
}
}
}
return base.IgnoreInheritedMember(member, component);
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DataContractJsonSerializer.cs
- ArrayTypeMismatchException.cs
- GPStream.cs
- XmlDataLoader.cs
- CollectionViewGroupInternal.cs
- ResourcesChangeInfo.cs
- PrimitiveType.cs
- ConnectionConsumerAttribute.cs
- HttpWebRequest.cs
- ResourceReader.cs
- ConcurrentDictionary.cs
- User.cs
- listviewsubitemcollectioneditor.cs
- MemberDescriptor.cs
- WebPartConnection.cs
- WindowsNonControl.cs
- MethodToken.cs
- CustomTypeDescriptor.cs
- InstanceNotReadyException.cs
- RadioButtonList.cs
- PrePrepareMethodAttribute.cs
- PagePropertiesChangingEventArgs.cs
- SmtpClient.cs
- XmlChildNodes.cs
- MouseButtonEventArgs.cs
- autovalidator.cs
- PtsCache.cs
- AnnotationHighlightLayer.cs
- UiaCoreProviderApi.cs
- DataListCommandEventArgs.cs
- PartialTrustVisibleAssembly.cs
- Latin1Encoding.cs
- Socket.cs
- BitHelper.cs
- exports.cs
- ProfilePropertySettingsCollection.cs
- ControlUtil.cs
- BidirectionalDictionary.cs
- TraceRecord.cs
- BindableAttribute.cs
- WorkflowMarkupSerializationProvider.cs
- TreeNode.cs
- RectConverter.cs
- OleServicesContext.cs
- SafeNativeMemoryHandle.cs
- IdentitySection.cs
- ToolboxComponentsCreatingEventArgs.cs
- AutomationProperties.cs
- SafeRegistryHandle.cs
- UriSection.cs
- SqlServer2KCompatibilityCheck.cs
- AggregateNode.cs
- SecurityTokenValidationException.cs
- SoapElementAttribute.cs
- ObjectQuery_EntitySqlExtensions.cs
- Visual3DCollection.cs
- XmlDocumentSerializer.cs
- DataGridBoolColumn.cs
- DataTemplateSelector.cs
- ControlParser.cs
- XmlSchemaComplexContent.cs
- ButtonFlatAdapter.cs
- FontCacheLogic.cs
- HttpFormatExtensions.cs
- FloaterBaseParagraph.cs
- RayMeshGeometry3DHitTestResult.cs
- Page.cs
- Merger.cs
- CodeNamespace.cs
- WbemProvider.cs
- SpotLight.cs
- MatrixTransform.cs
- XmlException.cs
- QueryExpr.cs
- EncryptedXml.cs
- FirstMatchCodeGroup.cs
- BrushConverter.cs
- GlobalizationSection.cs
- DigitShape.cs
- PropertiesTab.cs
- WindowsFormsHostPropertyMap.cs
- SynchronizingStream.cs
- WmlTextViewAdapter.cs
- DataControlFieldHeaderCell.cs
- GeneralTransform2DTo3D.cs
- ReferentialConstraint.cs
- BinaryConverter.cs
- TagMapInfo.cs
- SiblingIterators.cs
- WindowInteractionStateTracker.cs
- ArrayElementGridEntry.cs
- SizeAnimationUsingKeyFrames.cs
- Rotation3D.cs
- DiagnosticsConfiguration.cs
- EdmComplexPropertyAttribute.cs
- DateTimeOffsetStorage.cs
- QuaternionAnimationBase.cs
- TaskDesigner.cs
- TargetParameterCountException.cs
- TableProviderWrapper.cs