using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Interop; using System.Windows.Markup; using System.Xml.Linq; using Tango.Core.DI; using Tango.FSE.Common.Notifications; using Tango.FSE.Common.Threading; using Tango.FSE.Common.WindowsManager; using Tango.FSE.Procedures.Windows; namespace Tango.FSE.Procedures { public class WindowController : IDialogWindowController { private const int GWL_HWNDPARENT = -8; [DllImport("user32.dll")] static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle); private String _xaml; private FrameworkElement _rootElement; private ProcedureDialogWindow _dialogWindow; private Thread _windowThread; private String _title; private bool _isShown; [TangoInject] private IDispatcherProvider DispatcherProvider { get; set; } public static void SetOwnerWindowMultithread(IntPtr windowHandleOwned, IntPtr intPtrOwner) { if (windowHandleOwned != IntPtr.Zero && intPtrOwner != IntPtr.Zero) { SetWindowLong(windowHandleOwned, GWL_HWNDPARENT, intPtrOwner.ToInt32()); } } internal WindowController(String xaml, String title) { _xaml = xaml; _title = title; TangoIOC.Default.Inject(this); } internal void Init() { String xaml = _xaml; XDocument doc = XDocument.Parse(xaml); var textBoxes = doc.Descendants().Where(x => x.Name.LocalName == "TextBox").ToList(); textBoxes.ForEach(x => x.SetAttributeValue("Style", "{StaticResource ProcedureWindowTextBoxStyle}")); xaml = doc.ToString(); FrameworkElement rootElement; var stream = new MemoryStream(); var writer = new StreamWriter(stream); writer.Write(xaml); writer.Flush(); stream.Position = 0; rootElement = (FrameworkElement)XamlReader.Load(stream); _rootElement = rootElement; stream.Dispose(); _dialogWindow = new ProcedureDialogWindow(); _dialogWindow.Width = _rootElement.Width; _dialogWindow.Height = _rootElement.Height; _dialogWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen; _dialogWindow.Title = _title; _dialogWindow.SetContent(rootElement); //var textBoxesToRestore = rootElement.FindVisualChildren().ToList(); //textBoxesToRestore.ForEach(x => x.Style = null); var helper = new WindowInteropHelper(_dialogWindow); helper.EnsureHandle(); _windowThread = _dialogWindow.Dispatcher.Thread; //System.Windows.Threading.Dispatcher.Run(); //Make the main window as owner ? could be risky.. //IntPtr mainWindowHanle = IntPtr.Zero; //DispatcherProvider.InvokeBlock(() => //{ // mainWindowHanle = new WindowInteropHelper(Application.Current.MainWindow).Handle; //}); //SetOwnerWindowMultithread(helper.Handle, mainWindowHanle); } public void Show() { if (!_isShown) { _isShown = true; _dialogWindow.ShowDialog(); } else { //_dialogWindow.Visibility = Visibility.Visible; _dialogWindow.WindowState = WindowState.Normal; } } public T FindControl(String name) where T : DependencyObject { if (Thread.CurrentThread == _windowThread) { return _rootElement.FindChild(name) as T; } else { bool completed = false; T child = null; DispatcherProvider.Invoke(() => { child = _rootElement.FindChild(name) as T; completed = true; }); while (!completed) { Thread.Sleep(10); } return child; } } public void Close() { _dialogWindow.Close(); } public void Hide() { //_dialogWindow.Hide(); _dialogWindow.WindowState = WindowState.Minimized; } } }