Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / WinForms / System / WinForms / Design / DesignerFrame.cs / 1 / DesignerFrame.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* */ namespace System.Windows.Forms.Design { using System.Collections; using System.ComponentModel; using System.Diagnostics; using System; using System.Design; using System.ComponentModel.Design; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Windows.Forms.Design.Behavior; using System.Drawing; using Microsoft.Win32; using System.Diagnostics.CodeAnalysis; ////// /// /// This class implements our design time document. This is the outer window /// that encompases a designer. It maintains a control hierarchy that /// looks like this: /// /// DesignerFrame /// ScrollableControl /// Designer /// Splitter /// ScrollableControl /// Component Tray /// /// The splitter and second scrollable control are created on demand /// when a tray is added. /// internal class DesignerFrame : Control, IOverlayService, ISplitWindowService { private ISite designerSite; private OverlayControl designerRegion; private Splitter splitter; private Control designer; private BehaviorService behaviorService; ////// /// [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters")] public DesignerFrame(ISite site) { this.Text = "DesignerFrame"; this.designerSite = site; this.designerRegion = new OverlayControl(site); this.Controls.Add(designerRegion); // Now we must configure our designer to be at the correct // location, and setup the autoscrolling for its container. // designerRegion.AutoScroll = true; designerRegion.Dock = DockStyle.Fill; SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(OnUserPreferenceChanged); } ///Initializes a new instance of the ///class. /// Returns the scroll offset for the scrollable control that manages all // overlays. This is needed by the BehaviorService so we can correctly /// invalidate our AdornerWindow based on scrollposition. /// internal Point AutoScrollPosition { get { return designerRegion.AutoScrollPosition; } } ////// Demand creates a ptr to the BehaviorService - we do this so we can /// route keyboard message to it. /// private BehaviorService BehaviorService { get { if (behaviorService == null) { behaviorService = designerSite.GetService(typeof(BehaviorService)) as BehaviorService; } return behaviorService; } } protected override void Dispose(bool disposing) { if (disposing) { if (this.designer != null) { Control designerHolder = this.designer; this.designer = null; designerHolder.Visible = false; designerHolder.Parent = null; SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(OnUserPreferenceChanged); } } base.Dispose(disposing); } private void ForceDesignerRedraw(bool focus) { if (designer != null && designer.IsHandleCreated) { NativeMethods.SendMessage(designer.Handle, NativeMethods.WM_NCACTIVATE, focus ? 1 : 0, 0); SafeNativeMethods.RedrawWindow(designer.Handle, null, IntPtr.Zero, NativeMethods.RDW_FRAME); } } ////// /// Initializes this frame with the given designer view. /// public void Initialize(Control view) { this.designer = view; Form form = designer as Form; if (form != null) { form.TopLevel = false; } designerRegion.Controls.Add(designer); SyncDesignerUI(); designer.Visible = true; designer.Enabled = true; // VSWhidbey 481301 // We need to force handle creation here, since setting Visible = true // won't if the control is already Visible = true. // (UserControl starts out Visible true, Form does not) // This guarantees that as controls are added to the root component // their handles will be created correctly, and not the first time // they're queried after load. IntPtr handle = designer.Handle; } ////// /// When we get an lose focus, we need to make sure the form /// designer knows about it so it'll paint it's caption right. /// protected override void OnGotFocus(EventArgs e) { ForceDesignerRedraw(true); ISelectionService selSvc = (ISelectionService)designerSite.GetService(typeof(ISelectionService)); if (selSvc != null) { Control ctrl = selSvc.PrimarySelection as Control; if (ctrl != null) { UnsafeNativeMethods.NotifyWinEvent((int)AccessibleEvents.Focus, new HandleRef(ctrl, ctrl.Handle), NativeMethods.OBJID_CLIENT, 0); } } } ////// /// When we get an lose focus, we need to make sure the form /// designer knows about it so it'll paint it's caption right. /// protected override void OnLostFocus(EventArgs e) { ForceDesignerRedraw(false); } void OnSplitterMoved(object sender, SplitterEventArgs e) { // Dirty the designer. // IComponentChangeService cs = designerSite.GetService(typeof(IComponentChangeService)) as IComponentChangeService; if (cs != null) { try { cs.OnComponentChanging(designerSite.Component, null); cs.OnComponentChanged(designerSite.Component, null, null, null); } catch { } } } void OnUserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) { if (e.Category == UserPreferenceCategory.Window) { SyncDesignerUI(); } } ////// /// We override this to do nothing. Otherwise, all the nice keyboard m /// messages we want would get run through the Form's keyboard handling /// procedure. /// protected override bool ProcessDialogKey(Keys keyData) { return false; } void SyncDesignerUI() { Size selectionSize = DesignerUtils.GetAdornmentDimensions(AdornmentType.Maximum); designerRegion.AutoScrollMargin = selectionSize; designer.Location = new Point(selectionSize.Width, selectionSize.Height); if (BehaviorService != null) { BehaviorService.SyncSelection(); } } ////// /// Base wndProc. All messages are sent to wndProc after getting filtered /// through the preProcessMessage function. Inheriting controls should /// call base.wndProc for any messages that they don't handle. /// protected override void WndProc(ref Message m) { switch (m.Msg) { // Provide MouseWheel access for scrolling case NativeMethods.WM_MOUSEWHEEL: // Send a message to ourselves to scroll if (!designerRegion.messageMouseWheelProcessed) { designerRegion.messageMouseWheelProcessed = true; NativeMethods.SendMessage(designerRegion.Handle, NativeMethods.WM_MOUSEWHEEL, m.WParam , m.LParam); return; } break; // Provide keyboard access for scrolling case NativeMethods.WM_KEYDOWN: int wScrollNotify = 0; int msg = 0; int keycode = (int)m.WParam & 0xFFFF; switch ((Keys)keycode) { case Keys.Up: wScrollNotify = NativeMethods.SB_LINEUP; msg = NativeMethods.WM_VSCROLL; break; case Keys.Down: wScrollNotify = NativeMethods.SB_LINEDOWN; msg = NativeMethods.WM_VSCROLL; break; case Keys.PageUp: wScrollNotify = NativeMethods.SB_PAGEUP; msg = NativeMethods.WM_VSCROLL; break; case Keys.PageDown: wScrollNotify = NativeMethods.SB_PAGEDOWN; msg = NativeMethods.WM_VSCROLL; break; case Keys.Home: wScrollNotify = NativeMethods.SB_TOP; msg = NativeMethods.WM_VSCROLL; break; case Keys.End: wScrollNotify = NativeMethods.SB_BOTTOM; msg = NativeMethods.WM_VSCROLL; break; case Keys.Left: wScrollNotify = NativeMethods.SB_LINEUP; msg = NativeMethods.WM_HSCROLL; break; case Keys.Right: wScrollNotify = NativeMethods.SB_LINEDOWN; msg = NativeMethods.WM_HSCROLL; break; } if ((msg == NativeMethods.WM_VSCROLL) || (msg == NativeMethods.WM_HSCROLL)) { // Send a message to ourselves to scroll NativeMethods.SendMessage(designerRegion.Handle, msg, NativeMethods.Util.MAKELONG(wScrollNotify, 0), 0); return; } break; case NativeMethods.WM_CONTEXTMENU: NativeMethods.SendMessage(designer.Handle, m.Msg, m.WParam, m.LParam); return; } base.WndProc(ref m); } ////// /// Pushes the given control on top of the overlay list. This is a "push" /// operation, meaning that it forces this control to the top of the existing /// overlay list. /// int IOverlayService.PushOverlay(Control control) { return designerRegion.PushOverlay(control); } ////// /// Removes the given control from the overlay list. Unlike pushOverlay, /// this can remove a control from the middle of the overlay list. /// void IOverlayService.RemoveOverlay(Control control) { designerRegion.RemoveOverlay(control); } ////// /// Inserts the overlay. /// void IOverlayService.InsertOverlay(Control control, int index) { designerRegion.InsertOverlay(control, index); } ////// /// Invalidate child overlays /// void IOverlayService.InvalidateOverlays(Rectangle screenRectangle) { designerRegion.InvalidateOverlays(screenRectangle); } ////// /// Invalidate child overlays /// void IOverlayService.InvalidateOverlays(Region screenRegion) { designerRegion.InvalidateOverlays(screenRegion); } ////// /// Requests the service to add a window 'pane'. /// void ISplitWindowService.AddSplitWindow(Control window) { if (splitter == null) { splitter = new Splitter(); splitter.BackColor = SystemColors.Control; splitter.BorderStyle = BorderStyle.Fixed3D; splitter.Height = 7; splitter.Dock = DockStyle.Bottom; splitter.SplitterMoved += new SplitterEventHandler(this.OnSplitterMoved); } SuspendLayout(); window.Dock = DockStyle.Bottom; // Compute a minimum height for this window. // int minHeight = 80; if (window.Height < minHeight) { window.Height = minHeight; } Controls.Add(splitter); Controls.Add(window); ResumeLayout(); } ////// /// Requests the service to remove a window 'pane'. /// void ISplitWindowService.RemoveSplitWindow(Control window) { SuspendLayout(); Controls.Remove(window); Controls.Remove(splitter); ResumeLayout(); } ////// /// This is a scrollable control that supports additional floating /// overlay controls. /// private class OverlayControl : ScrollableControl { private ArrayList overlayList; private IServiceProvider provider; internal bool messageMouseWheelProcessed; private BehaviorService behaviorService; ////// /// Creates a new overlay control. /// [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters")] public OverlayControl(IServiceProvider provider) { this.provider = provider; overlayList = new ArrayList(); AutoScroll = true; this.Text = "OverlayControl"; } protected override AccessibleObject CreateAccessibilityInstance() { return new OverlayControlAccessibleObject(this); } ////// Demand creates a ptr to the BehaviorService /// private BehaviorService BehaviorService { get { if (behaviorService == null) { behaviorService = provider.GetService(typeof(BehaviorService)) as BehaviorService; } return behaviorService; } } ////// /// At handle creation time we request the designer's handle and /// parent it. /// protected override void OnCreateControl() { base.OnCreateControl(); // Loop through all of the overlays, create them, and hook them up // if (overlayList != null) { foreach(Control c in overlayList) { ParentOverlay(c); } } // We've reparented everything, which means that our selection UI is probably // out of sync. Ask it to sync. // if (BehaviorService != null) { BehaviorService.SyncSelection(); } } ////// /// We override onLayout to provide our own custom layout functionality. /// This just overlaps all of the controls. /// protected override void OnLayout(LayoutEventArgs e) { base.OnLayout(e); Rectangle client = DisplayRectangle; // Loop through all of the overlays and size them. Also make // sure that they are still on top of the zorder, because a handle // recreate could have changed this. // if (overlayList != null) { foreach(Control c in overlayList) { c.Bounds = client; } } } ////// /// Called to parent an overlay window into our document. This assumes that /// we call in reverse stack order, as it always pushes to the top of the /// z-order. /// private void ParentOverlay(Control control) { NativeMethods.SetParent(control.Handle, Handle); SafeNativeMethods.SetWindowPos(control.Handle, (IntPtr)NativeMethods.HWND_TOP, 0, 0, 0, 0, NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOMOVE); } ////// /// Pushes the given control on top of the overlay list. This is a "push" /// operation, meaning that it forces this control to the top of the existing /// overlay list. /// public int PushOverlay(Control control) { Debug.Assert(overlayList.IndexOf(control)==-1, "Duplicate overlay in overlay service :" + control.GetType().FullName); overlayList.Add(control); // We cheat a bit here. We need to have these components parented, but we don't // want them to effect our layout. // if (IsHandleCreated) { ParentOverlay(control); control.Bounds = DisplayRectangle; } return overlayList.IndexOf(control); } ////// /// Removes the given control from the overlay list. Unlike pushOverlay, /// this can remove a control from the middle of the overlay list. /// public void RemoveOverlay(Control control) { Debug.Assert(overlayList.IndexOf(control)!=-1, "Control is not in overlay service :" + control.GetType().FullName); overlayList.Remove(control); control.Visible = false; control.Parent = null; } ////// /// Inserts Overlay. /// public void InsertOverlay(Control control, int index) { Debug.Assert(overlayList.IndexOf(control)==-1, "Duplicate overlay in overlay service :" + control.GetType().FullName); Control c = (Control)overlayList[index]; RemoveOverlay(c); PushOverlay(control); PushOverlay(c); c.Visible = true; } ////// /// Invalidates overlays that intersect with the given section of the screen; /// public void InvalidateOverlays(Rectangle screenRectangle) { // paint in inverse order so that things at the front paint last. for (int i = overlayList.Count-1; i >= 0; i--) { Control overlayControl = overlayList[i] as Control; if (overlayControl != null) { Rectangle invalidateRect = new Rectangle(overlayControl.PointToClient(screenRectangle.Location), screenRectangle.Size); if (overlayControl.ClientRectangle.IntersectsWith(invalidateRect)) { overlayControl.Invalidate(invalidateRect); } } } } ////// /// Invalidates overlays that intersect with the given section of the screen; /// public void InvalidateOverlays(Region screenRegion) { // paint in inverse order so that things at the front paint last. for (int i = overlayList.Count-1; i >= 0; i--) { Control overlayControl = overlayList[i] as Control; if (overlayControl != null) { Rectangle overlayControlScreenBounds =overlayControl.Bounds; overlayControlScreenBounds.Location = overlayControl.PointToScreen(overlayControl.Location); using (Region intersectionRegion = screenRegion.Clone()) { // get the intersection of everything on the screen that's invalidating // and the overlaycontrol intersectionRegion.Intersect(overlayControlScreenBounds); // translate this down to overlay control coordinates. intersectionRegion.Translate(-overlayControlScreenBounds.X, -overlayControlScreenBounds.Y); overlayControl.Invalidate(intersectionRegion); } } } } ////// Need to know when child windows are created so we can properly set the Z-order /// protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == NativeMethods.WM_PARENTNOTIFY && NativeMethods.Util.LOWORD((int)m.WParam) == (short)NativeMethods.WM_CREATE) { if (overlayList != null) { bool ourWindow = false; foreach(Control c in overlayList) { if (c.IsHandleCreated && m.LParam == c.Handle) { ourWindow = true; break; } } if (!ourWindow) { foreach(Control c in overlayList) { SafeNativeMethods.SetWindowPos(c.Handle, (IntPtr)NativeMethods.HWND_TOP, 0, 0, 0, 0, NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOMOVE); } } } } else if ((m.Msg == NativeMethods.WM_VSCROLL || m.Msg == NativeMethods.WM_HSCROLL) && BehaviorService != null) { BehaviorService.SyncSelection(); } else if ((m.Msg == NativeMethods.WM_MOUSEWHEEL)) { messageMouseWheelProcessed = false; if (BehaviorService != null) { BehaviorService.SyncSelection(); } } } public class OverlayControlAccessibleObject : Control.ControlAccessibleObject { public OverlayControlAccessibleObject(OverlayControl owner) : base(owner) { } public override AccessibleObject HitTest(int x, int y) { // Since the SelectionUIOverlay in first in the z-order, it normally gets // returned from accHitTest. But we'd rather expose the form that is being // designed. // foreach(Control c in Owner.Controls) { AccessibleObject cao = c.AccessibilityObject; if (cao.Bounds.Contains(x, y)) { return cao; } } return base.HitTest(x, y); } } } } } // 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
- SubpageParagraph.cs
- BaseProcessor.cs
- BooleanFunctions.cs
- WriterOutput.cs
- ExeContext.cs
- UnsafeNetInfoNativeMethods.cs
- DateTimeConstantAttribute.cs
- TransferMode.cs
- HttpSessionStateWrapper.cs
- DbFunctionCommandTree.cs
- HtmlInputFile.cs
- XmlSchemaSimpleContentRestriction.cs
- MetaData.cs
- XmlChildNodes.cs
- Rotation3D.cs
- MenuItemCollection.cs
- FileSystemWatcher.cs
- DataGridViewCellPaintingEventArgs.cs
- Enum.cs
- PartialCachingAttribute.cs
- TrustLevelCollection.cs
- InheritanceContextHelper.cs
- LeaseManager.cs
- NameGenerator.cs
- LocalizableAttribute.cs
- ZipPackagePart.cs
- DataAdapter.cs
- Viewport3DVisual.cs
- FocusChangedEventArgs.cs
- ListSortDescription.cs
- Command.cs
- PaperSize.cs
- RadialGradientBrush.cs
- TextOptionsInternal.cs
- PointHitTestParameters.cs
- CombinedHttpChannel.cs
- DataGridState.cs
- View.cs
- CodeSubDirectory.cs
- GenericParameterDataContract.cs
- RenderDataDrawingContext.cs
- ObjectViewFactory.cs
- SafeFileMappingHandle.cs
- ResourceContainer.cs
- SqlConnectionString.cs
- DataGridPagerStyle.cs
- GridLengthConverter.cs
- InplaceBitmapMetadataWriter.cs
- SerializationUtilities.cs
- VarInfo.cs
- GACMembershipCondition.cs
- SchemaMerger.cs
- SocketInformation.cs
- SqlNodeAnnotation.cs
- WindowsGraphicsCacheManager.cs
- MemberInfoSerializationHolder.cs
- metadatamappinghashervisitor.hashsourcebuilder.cs
- EdmEntityTypeAttribute.cs
- MediaTimeline.cs
- ObjectDataSourceWizardForm.cs
- CmsInterop.cs
- _LocalDataStore.cs
- OutputCacheSection.cs
- RelativeSource.cs
- Security.cs
- X509ChainElement.cs
- SQLDateTimeStorage.cs
- EventLogEntryCollection.cs
- InstalledFontCollection.cs
- Vector3DAnimationBase.cs
- Vector3DCollectionConverter.cs
- ScrollChangedEventArgs.cs
- SchemaElementDecl.cs
- CreateSequence.cs
- Domain.cs
- TextRange.cs
- PeerInvitationResponse.cs
- AssociationType.cs
- ParserOptions.cs
- HttpCapabilitiesBase.cs
- UnmanagedMemoryStream.cs
- SqlAliasesReferenced.cs
- ExpressionBinding.cs
- CodeMemberEvent.cs
- UnaryNode.cs
- ExeConfigurationFileMap.cs
- SqlUnionizer.cs
- InitializationEventAttribute.cs
- MultitargetingHelpers.cs
- ApplicationDirectory.cs
- ListViewGroupConverter.cs
- ZipIOZip64EndOfCentralDirectoryBlock.cs
- DbConnectionPoolCounters.cs
- VisualCollection.cs
- TypeConverterHelper.cs
- SqlInfoMessageEvent.cs
- TableCellsCollectionEditor.cs
- TransformGroup.cs
- StorageComplexTypeMapping.cs
- DataSourceSelectArguments.cs