| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537 |
- /*************************************************************************************
- Extended WPF Toolkit
- Copyright (C) 2007-2013 Xceed Software Inc.
- This program is provided to you under the terms of the Microsoft Public
- License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
- For more features, controls, and fast professional support,
- pick up the Plus Edition at http://xceed.com/wpf_toolkit
- Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
- ***********************************************************************************/
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Windows;
- using System.Runtime.InteropServices;
- using System.Windows.Interop;
- using System.Windows.Input;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Media;
- using Xceed.Wpf.AvalonDock.Layout;
- using System.Diagnostics;
- using System.Windows.Documents;
- using Xceed.Wpf.AvalonDock.Themes;
- namespace Xceed.Wpf.AvalonDock.Controls
- {
- public abstract class LayoutFloatingWindowControl : Window, ILayoutControl
- {
- private ResourceDictionary currentThemeResourceDictionary; // = null
- static LayoutFloatingWindowControl()
- {
- LayoutFloatingWindowControl.ContentProperty.OverrideMetadata(typeof(LayoutFloatingWindowControl), new FrameworkPropertyMetadata(null, null, new CoerceValueCallback(CoerceContentValue)));
- AllowsTransparencyProperty.OverrideMetadata(typeof(LayoutFloatingWindowControl), new FrameworkPropertyMetadata(false));
- ShowInTaskbarProperty.OverrideMetadata(typeof(LayoutFloatingWindowControl), new FrameworkPropertyMetadata(false));
- }
- static object CoerceContentValue(DependencyObject sender, object content)
- {
- return new FloatingWindowContentHost(sender as LayoutFloatingWindowControl) { Content = content as UIElement };
- }
- protected class FloatingWindowContentHost : HwndHost
- {
- LayoutFloatingWindowControl _owner;
- public FloatingWindowContentHost(LayoutFloatingWindowControl owner)
- {
- _owner = owner;
- var manager = _owner.Model.Root.Manager;
- }
- HwndSource _wpfContentHost = null;
- Border _rootPresenter = null;
- DockingManager _manager = null;
- protected override System.Runtime.InteropServices.HandleRef BuildWindowCore(System.Runtime.InteropServices.HandleRef hwndParent)
- {
- _wpfContentHost = new HwndSource(new HwndSourceParameters()
- {
- ParentWindow = hwndParent.Handle,
- WindowStyle = Win32Helper.WS_CHILD | Win32Helper.WS_VISIBLE | Win32Helper.WS_CLIPSIBLINGS | Win32Helper.WS_CLIPCHILDREN,
- Width = 1,
- Height = 1
- });
- _rootPresenter = new Border() { Child = new AdornerDecorator() { Child = Content }, Focusable = true };
- _rootPresenter.SetBinding(Border.BackgroundProperty, new Binding("Background") { Source = _owner });
- _wpfContentHost.RootVisual = _rootPresenter;
- _wpfContentHost.SizeToContent = SizeToContent.Manual;
- _manager = _owner.Model.Root.Manager;
- _manager.InternalAddLogicalChild(_rootPresenter);
- return new HandleRef(this, _wpfContentHost.Handle);
- }
- protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
- {
- Trace.WriteLine("FloatingWindowContentHost.GotKeyboardFocus");
- base.OnGotKeyboardFocus(e);
- }
- protected override void DestroyWindowCore(HandleRef hwnd)
- {
- _manager.InternalRemoveLogicalChild(_rootPresenter);
- if (_wpfContentHost != null)
- {
- _wpfContentHost.Dispose();
- _wpfContentHost = null;
- }
- }
- protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
- {
- switch (msg)
- {
- case Win32Helper.WM_SETFOCUS:
- Trace.WriteLine("FloatingWindowContentHost.WM_SETFOCUS");
- break;
- case Win32Helper.WM_KILLFOCUS:
- Trace.WriteLine("FloatingWindowContentHost.WM_KILLFOCUS");
- break;
- }
- return base.WndProc(hwnd, msg, wParam, lParam, ref handled);
- }
- public Visual RootVisual
- {
- get { return _rootPresenter; }
- }
- protected override Size MeasureOverride(Size constraint)
- {
- if (Content == null)
- return base.MeasureOverride(constraint);
- Content.Measure(constraint);
- return Content.DesiredSize;
- }
- #region Content
- /// <summary>
- /// Content Dependency Property
- /// </summary>
- public static readonly DependencyProperty ContentProperty =
- DependencyProperty.Register("Content", typeof(UIElement), typeof(FloatingWindowContentHost),
- new FrameworkPropertyMetadata((UIElement)null,
- new PropertyChangedCallback(OnContentChanged)));
- /// <summary>
- /// Gets or sets the Content property. This dependency property
- /// indicates ....
- /// </summary>
- public UIElement Content
- {
- get { return (UIElement)GetValue(ContentProperty); }
- set { SetValue(ContentProperty, value); }
- }
- /// <summary>
- /// Handles changes to the Content property.
- /// </summary>
- private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- ((FloatingWindowContentHost)d).OnContentChanged(e);
- }
- /// <summary>
- /// Provides derived classes an opportunity to handle changes to the Content property.
- /// </summary>
- protected virtual void OnContentChanged(DependencyPropertyChangedEventArgs e)
- {
- if (_rootPresenter != null)
- _rootPresenter.Child = Content;
- }
- #endregion
- }
- ILayoutElement _model;
- protected LayoutFloatingWindowControl(ILayoutElement model)
- {
- this.Loaded += new RoutedEventHandler(OnLoaded);
- this.Unloaded += new RoutedEventHandler(OnUnloaded);
- _model = model;
- UpdateThemeResources();
- }
- internal virtual void UpdateThemeResources(Theme oldTheme = null)
- {
- if (oldTheme != null)
- {
- if( oldTheme is DictionaryTheme )
- {
- if( currentThemeResourceDictionary != null )
- {
- Resources.MergedDictionaries.Remove( currentThemeResourceDictionary );
- currentThemeResourceDictionary = null;
- }
- }
- else
- {
- var resourceDictionaryToRemove =
- Resources.MergedDictionaries.FirstOrDefault( r => r.Source == oldTheme.GetResourceUri() );
- if( resourceDictionaryToRemove != null )
- Resources.MergedDictionaries.Remove(
- resourceDictionaryToRemove );
- }
- }
- var manager = _model.Root.Manager;
- if (manager.Theme != null)
- {
- if( manager.Theme is DictionaryTheme )
- {
- currentThemeResourceDictionary = ( ( DictionaryTheme )manager.Theme ).ThemeResourceDictionary;
- Resources.MergedDictionaries.Add( currentThemeResourceDictionary );
- }
- else
- {
- Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = manager.Theme.GetResourceUri() });
- }
- }
- }
- protected override void OnClosed(EventArgs e)
- {
- if (Content != null)
- {
- var host = Content as FloatingWindowContentHost;
- host.Dispose();
- if (_hwndSrc != null)
- {
- _hwndSrc.RemoveHook(_hwndSrcHook);
- _hwndSrc.Dispose();
- _hwndSrc = null;
- }
- }
- base.OnClosed(e);
- }
- bool _attachDrag = false;
- internal void AttachDrag(bool onActivated = true)
- {
- if (onActivated)
- {
- _attachDrag = true;
- this.Activated += new EventHandler(OnActivated);
- }
- else
- {
- IntPtr windowHandle = new WindowInteropHelper(this).Handle;
- IntPtr lParam = new IntPtr(((int)Left & (int)0xFFFF) | (((int)Top) << 16));
- Win32Helper.SendMessage(windowHandle, Win32Helper.WM_NCLBUTTONDOWN, new IntPtr(Win32Helper.HT_CAPTION), lParam);
- }
- }
- HwndSource _hwndSrc;
- HwndSourceHook _hwndSrcHook;
- void OnLoaded(object sender, RoutedEventArgs e)
- {
- this.Loaded -= new RoutedEventHandler(OnLoaded);
- this.SetParentToMainWindowOf(Model.Root.Manager);
- _hwndSrc = HwndSource.FromDependencyObject(this) as HwndSource;
- _hwndSrcHook = new HwndSourceHook(FilterMessage);
- _hwndSrc.AddHook(_hwndSrcHook);
- }
- void OnUnloaded(object sender, RoutedEventArgs e)
- {
- this.Unloaded -= new RoutedEventHandler(OnUnloaded);
- if (_hwndSrc != null)
- {
- _hwndSrc.RemoveHook(_hwndSrcHook);
- _hwndSrc.Dispose();
- _hwndSrc = null;
- }
- }
- void OnActivated(object sender, EventArgs e)
- {
- this.Activated -= new EventHandler(OnActivated);
- if (_attachDrag && Mouse.LeftButton == MouseButtonState.Pressed)
- {
- IntPtr windowHandle = new WindowInteropHelper(this).Handle;
- var mousePosition = this.PointToScreenDPI(Mouse.GetPosition(this));
- var clientArea = Win32Helper.GetClientRect(windowHandle);
- var windowArea = Win32Helper.GetWindowRect(windowHandle);
- Left = mousePosition.X - windowArea.Width / 2.0;
- Top = mousePosition.Y - (windowArea.Height - clientArea.Height) / 2.0;
- _attachDrag = false;
- IntPtr lParam = new IntPtr(((int)mousePosition.X & (int)0xFFFF) | (((int)mousePosition.Y) << 16));
- Win32Helper.SendMessage(windowHandle, Win32Helper.WM_NCLBUTTONDOWN, new IntPtr(Win32Helper.HT_CAPTION), lParam);
- }
- }
- protected override void OnInitialized(EventArgs e)
- {
- CommandBindings.Add(new CommandBinding(Microsoft.Windows.Shell.SystemCommands.CloseWindowCommand,
- new ExecutedRoutedEventHandler((s, args) => Microsoft.Windows.Shell.SystemCommands.CloseWindow((Window)args.Parameter))));
- CommandBindings.Add(new CommandBinding(Microsoft.Windows.Shell.SystemCommands.MaximizeWindowCommand,
- new ExecutedRoutedEventHandler((s, args) => Microsoft.Windows.Shell.SystemCommands.MaximizeWindow((Window)args.Parameter))));
- CommandBindings.Add(new CommandBinding(Microsoft.Windows.Shell.SystemCommands.MinimizeWindowCommand,
- new ExecutedRoutedEventHandler((s, args) => Microsoft.Windows.Shell.SystemCommands.MinimizeWindow((Window)args.Parameter))));
- CommandBindings.Add(new CommandBinding(Microsoft.Windows.Shell.SystemCommands.RestoreWindowCommand,
- new ExecutedRoutedEventHandler((s, args) => Microsoft.Windows.Shell.SystemCommands.RestoreWindow((Window)args.Parameter))));
- //Debug.Assert(this.Owner != null);
- base.OnInitialized(e);
- }
- public abstract ILayoutElement Model { get; }
- #region IsDragging
- /// <summary>
- /// IsDragging Read-Only Dependency Property
- /// </summary>
- private static readonly DependencyPropertyKey IsDraggingPropertyKey
- = DependencyProperty.RegisterReadOnly("IsDragging", typeof(bool), typeof(LayoutFloatingWindowControl),
- new FrameworkPropertyMetadata((bool)false,
- new PropertyChangedCallback(OnIsDraggingChanged)));
- public static readonly DependencyProperty IsDraggingProperty
- = IsDraggingPropertyKey.DependencyProperty;
- /// <summary>
- /// Gets the IsDragging property. This dependency property
- /// indicates that this floating window is being dragged.
- /// </summary>
- public bool IsDragging
- {
- get { return (bool)GetValue(IsDraggingProperty); }
- }
- /// <summary>
- /// Provides a secure method for setting the IsDragging property.
- /// This dependency property indicates that this floating window is being dragged.
- /// </summary>
- /// <param name="value">The new value for the property.</param>
- protected void SetIsDragging(bool value)
- {
- SetValue(IsDraggingPropertyKey, value);
- }
- /// <summary>
- /// Handles changes to the IsDragging property.
- /// </summary>
- private static void OnIsDraggingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- ((LayoutFloatingWindowControl)d).OnIsDraggingChanged(e);
- }
- /// <summary>
- /// Provides derived classes an opportunity to handle changes to the IsDragging property.
- /// </summary>
- protected virtual void OnIsDraggingChanged(DependencyPropertyChangedEventArgs e)
- {
- //Trace.WriteLine("IsDragging={0}", e.NewValue);
- }
- #endregion
- DragService _dragService = null;
- void UpdatePositionAndSizeOfPanes()
- {
- foreach (var posElement in Model.Descendents().OfType<ILayoutElementForFloatingWindow>())
- {
- posElement.FloatingLeft = Left;
- posElement.FloatingTop = Top;
- posElement.FloatingWidth = Width;
- posElement.FloatingHeight = Height;
- }
- }
- void UpdateMaximizedState( bool isMaximized )
- {
- foreach( var posElement in Model.Descendents().OfType<ILayoutElementForFloatingWindow>() )
- {
- posElement.IsMaximized = isMaximized;
- }
- }
- protected virtual IntPtr FilterMessage(
- IntPtr hwnd,
- int msg,
- IntPtr wParam,
- IntPtr lParam,
- ref bool handled
- )
- {
- handled = false;
- switch (msg)
- {
- case Win32Helper.WM_ACTIVATE:
- if (((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE)
- {
- if (lParam == this.GetParentWindowHandle())
- {
- Win32Helper.SetActiveWindow(_hwndSrc.Handle);
- handled = true;
- }
- }
- break;
- case Win32Helper.WM_EXITSIZEMOVE:
- UpdatePositionAndSizeOfPanes();
- if (_dragService != null)
- {
- bool dropFlag;
- var mousePosition = this.TransformToDeviceDPI(Win32Helper.GetMousePosition());
- _dragService.Drop(mousePosition, out dropFlag);
- _dragService = null;
- SetIsDragging(false);
- if (dropFlag)
- InternalClose();
- }
- break;
- case Win32Helper.WM_MOVING:
- {
- UpdateDragPosition();
- }
- break;
- case Win32Helper.WM_LBUTTONUP: //set as handled right button click on title area (after showing context menu)
- if (_dragService != null && Mouse.LeftButton == MouseButtonState.Released)
- {
- _dragService.Abort();
- _dragService = null;
- SetIsDragging(false);
- }
- break;
- case Win32Helper.WM_SYSCOMMAND:
- IntPtr wMaximize = new IntPtr( Win32Helper.SC_MAXIMIZE );
- IntPtr wRestore = new IntPtr( Win32Helper.SC_RESTORE );
- if( wParam == wMaximize || wParam == wRestore )
- {
- UpdateMaximizedState( wParam == wMaximize );
- }
- break;
- }
- return IntPtr.Zero;
- }
- private void UpdateDragPosition()
- {
- if (_dragService == null)
- {
- _dragService = new DragService(this);
- SetIsDragging(true);
- }
- var mousePosition = this.TransformToDeviceDPI(Win32Helper.GetMousePosition());
- _dragService.UpdateMouseLocation(mousePosition);
- }
- bool _internalCloseFlag = false;
- internal void InternalClose()
- {
- _internalCloseFlag = true;
- Close();
- }
- protected bool CloseInitiatedByUser
- {
- get { return !_internalCloseFlag; }
- }
- internal bool KeepContentVisibleOnClose
- {
- get;
- set;
- }
- protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
- {
- base.OnMouseLeftButtonUp(e);
- }
- #region IsMaximized
- /// <summary>
- /// IsMaximized Read-Only Dependency Property
- /// </summary>
- private static readonly DependencyPropertyKey IsMaximizedPropertyKey
- = DependencyProperty.RegisterReadOnly("IsMaximized", typeof(bool), typeof(LayoutFloatingWindowControl),
- new FrameworkPropertyMetadata((bool)false));
- public static readonly DependencyProperty IsMaximizedProperty
- = IsMaximizedPropertyKey.DependencyProperty;
- /// <summary>
- /// Gets the IsMaximized property. This dependency property
- /// indicates if the window is maximized.
- /// </summary>
- public bool IsMaximized
- {
- get { return (bool)GetValue(IsMaximizedProperty); }
- }
- /// <summary>
- /// Provides a secure method for setting the IsMaximized property.
- /// This dependency property indicates if the window is maximized.
- /// </summary>
- /// <param name="value">The new value for the property.</param>
- protected void SetIsMaximized(bool value)
- {
- SetValue(IsMaximizedPropertyKey, value);
- }
- protected override void OnStateChanged(EventArgs e)
- {
- SetIsMaximized(WindowState == System.Windows.WindowState.Maximized);
- base.OnStateChanged(e);
- }
- #endregion
- }
- }
|