using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Threading; namespace Tango.Editors { /// /// /// Contains some helper methods for UI interaction. /// internal static class UIHelper { #region Native Classes [StructLayout(LayoutKind.Sequential)] internal struct RECT { private int _Left; private int _Top; private int _Right; private int _Bottom; public RECT(RECT Rectangle) : this(Rectangle.Left, Rectangle.Top, Rectangle.Right, Rectangle.Bottom) { } public RECT(int Left, int Top, int Right, int Bottom) { _Left = Left; _Top = Top; _Right = Right; _Bottom = Bottom; } public int X { get { return _Left; } set { _Left = value; } } public int Y { get { return _Top; } set { _Top = value; } } public int Left { get { return _Left; } set { _Left = value; } } public int Top { get { return _Top; } set { _Top = value; } } public int Right { get { return _Right; } set { _Right = value; } } public int Bottom { get { return _Bottom; } set { _Bottom = value; } } public int Height { get { return _Bottom - _Top; } set { _Bottom = value + _Top; } } public int Width { get { return _Right - _Left; } set { _Right = value + _Left; } } public System.Drawing.Point Location { get { return new System.Drawing.Point(Left, Top); } set { _Left = value.X; _Top = value.Y; } } public System.Drawing.Size Size { get { return new System.Drawing.Size(Width, Height); } set { _Right = value.Width + _Left; _Bottom = value.Height + _Top; } } public static implicit operator System.Drawing.Rectangle(RECT Rectangle) { return new System.Drawing.Rectangle(Rectangle.Left, Rectangle.Top, Rectangle.Width, Rectangle.Height); } public static implicit operator RECT(System.Drawing.Rectangle Rectangle) { return new RECT(Rectangle.Left, Rectangle.Top, Rectangle.Right, Rectangle.Bottom); } public static bool operator ==(RECT Rectangle1, RECT Rectangle2) { return Rectangle1.Equals(Rectangle2); } public static bool operator !=(RECT Rectangle1, RECT Rectangle2) { return !Rectangle1.Equals(Rectangle2); } public override string ToString() { return "{Left: " + _Left + "; " + "Top: " + _Top + "; Right: " + _Right + "; Bottom: " + _Bottom + "}"; } public override int GetHashCode() { return ToString().GetHashCode(); } public bool Equals(RECT Rectangle) { return Rectangle.Left == _Left && Rectangle.Top == _Top && Rectangle.Right == _Right && Rectangle.Bottom == _Bottom; } public override bool Equals(object Object) { if (Object is RECT) { return Equals((RECT)Object); } else if (Object is System.Drawing.Rectangle) { return Equals(new RECT((System.Drawing.Rectangle)Object)); } return false; } } #endregion [DllImport("user32.dll")] internal static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); [DllImport("user32.dll")] internal static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, int nFlags); [DllImport("user32.dll", CharSet = CharSet.Auto)] internal static extern IntPtr GetCapture(); internal static void InvokeUI(Action action) { EnsureDispatcher(); try { Application.Current.Dispatcher.BeginInvoke(action); } catch { } } internal static void InvokeUIUrgent(Action action) { EnsureDispatcher(); Application.Current.Dispatcher.Invoke(action, DispatcherPriority.Send); } internal static void EnsureDispatcher() { try { if (System.Windows.Application.Current == null) //Using this to enable processing outside a WPF application. { new System.Windows.Application { ShutdownMode = ShutdownMode.OnExplicitShutdown }; } } catch { } } internal static void DoEvents() { Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate { })); } internal static void ReleaseMouseCapture() { IntPtr capturingHandle = GetCapture(); for (int i = 0; i < Application.Current.Windows.Count; i++) { if (new WindowInteropHelper(Application.Current.Windows[i]).Handle == capturingHandle) { Mouse.Capture(Application.Current.Windows[i], CaptureMode.Element); Application.Current.Windows[i].ReleaseMouseCapture(); break; } } } internal static void RemoveChild(DependencyObject parent, UIElement child) { var panel = parent as Panel; if (panel != null) { panel.Children.Remove(child); return; } var decorator = parent as Decorator; if (decorator != null) { if (decorator.Child == child) { decorator.Child = null; } return; } var contentPresenter = parent as ContentPresenter; if (contentPresenter != null) { if (contentPresenter.Content == child) { contentPresenter.Content = null; } return; } var contentControl = parent as ContentControl; if (contentControl != null) { if (contentControl.Content == child) { contentControl.Content = null; } return; } } internal static void AddChild(DependencyObject parent, UIElement child) { var panel = parent as Panel; if (panel != null) { panel.Children.Add(child); return; } var decorator = parent as Decorator; if (decorator != null) { decorator.Child = child; return; } var contentPresenter = parent as ContentPresenter; if (contentPresenter != null) { contentPresenter.Content = child; return; } var contentControl = parent as ContentControl; if (contentControl != null) { contentControl.Content = child; return; } } public static RenderTargetBitmap TakeSnapshot(Visual oVisual, Size oSize) { int nWidth = (int)Math.Ceiling(oSize.Width); int nHeight = (int)Math.Ceiling(oSize.Height); RenderTargetBitmap oTargetBitmap = new RenderTargetBitmap( nWidth, nHeight, 96, 96, PixelFormats.Pbgra32 ); DrawingVisual oDrawingVisual = new DrawingVisual(); using (DrawingContext oDrawingContext = oDrawingVisual.RenderOpen()) { VisualBrush oVisualBrush = new VisualBrush(oVisual) { Stretch = Stretch.Fill }; oDrawingContext.DrawRectangle( oVisualBrush, null, new Rect( new Point(), new Size(nWidth, nHeight) ) ); oDrawingContext.Close(); oTargetBitmap.Render(oDrawingVisual); } oTargetBitmap.Freeze(); return oTargetBitmap; } public static RenderTargetBitmap TakeSnapshot(FrameworkElement element) { int nWidth = (int)Math.Ceiling(element.ActualWidth); int nHeight = (int)Math.Ceiling(element.ActualHeight); RenderTargetBitmap oTargetBitmap = new RenderTargetBitmap( nWidth, nHeight, 96, 96, PixelFormats.Pbgra32 ); DrawingVisual oDrawingVisual = new DrawingVisual(); using (DrawingContext oDrawingContext = oDrawingVisual.RenderOpen()) { VisualBrush oVisualBrush = new VisualBrush(element) { Stretch = Stretch.Fill }; oDrawingContext.DrawRectangle( oVisualBrush, null, new Rect( new Point(), new Size(nWidth, nHeight) ) ); oDrawingContext.Close(); oTargetBitmap.Render(oDrawingVisual); } return oTargetBitmap; } public static System.Drawing.Bitmap TakeSnapshot(Window window) { var handle = new WindowInteropHelper(window).Handle; RECT rc; GetWindowRect(handle, out rc); System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(rc.Width, rc.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); var gfxBmp = System.Drawing.Graphics.FromImage(bmp); IntPtr hdcBitmap = gfxBmp.GetHdc(); PrintWindow(handle, hdcBitmap, 0); gfxBmp.ReleaseHdc(hdcBitmap); gfxBmp.Dispose(); return bmp; } internal static Stream GetApplicationResource(String resourcePath) { String callingAssembly = Assembly.GetCallingAssembly().GetName().Name; Uri uri = new Uri("/" + callingAssembly + ";component/" + resourcePath, UriKind.Relative); System.Windows.Resources.StreamResourceInfo info = Application.GetResourceStream(uri); return info.Stream; } internal static BitmapSource GetImageFromApplicationResource(String resourcePath) { String callingAssembly = Assembly.GetCallingAssembly().GetName().Name; Uri uri = new Uri("/" + callingAssembly + ";component/" + resourcePath, UriKind.Relative); System.Windows.Resources.StreamResourceInfo info = Application.GetResourceStream(uri); var bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.CacheOption = BitmapCacheOption.OnLoad; bitmapImage.StreamSource = info.Stream; bitmapImage.EndInit(); return bitmapImage; } internal static String GetStartupPath() { return System.AppDomain.CurrentDomain.BaseDirectory; } internal static String GetRandomAnimationName() { return "ani" + Guid.NewGuid().ToString().Replace("-", ""); } } }