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("-", "");
}
}
}