using Prism.Regions; using System.Collections.Generic; using System.Windows; using CyberX8_Themes.CustomControls; using Venus_Unity; using System.Linq; using System.Threading; using System; using CyberX8_MainPages.Views; using System.Windows.Controls; using Aitex.Core.UI.View.Frame; using System.Windows.Media; using CyberX8_Core; using System.Reflection; using CyberX8_MainPages.Unity; using MECF.Framework.Common.DataCenter; using MECF.Framework.Common.OperationCenter; using Aitex.Core.RT.OperationCenter; using CyberX8_MainPages.ViewModels; using MECF.Framework.Common.CommonData; using System.Windows.Controls.Primitives; using System.Timers; using System.Windows.Threading; using CyberX8_Themes.Unity; using CyberX8_Themes.UserControls; using OpenSEMI.Ctrlib.Controls; using OpenSEMI.ClientBase; using MECF.Framework.Common.Equipment; using WinInterop = System.Windows.Interop; using System.Runtime.InteropServices; using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; using Aitex.Core.RT.IOCore; using CyberX8_UI.Themes.Attach; using CyberX8_MainPages.Roles; using System.Collections.ObjectModel; using System.Diagnostics; using System.Windows.Input; using System.Net.Sockets; using System.Net; namespace CyberX8_UI.Views { /// <summary> /// ShellView.xaml 的交互逻辑 /// </summary> public partial class ShellView : Window { IRegionManager m_regionManager; IRegionNavigationService m_regionNavigationService; List<VenusMenu> MainMenu; List<TabControl> centerTabViews = new List<TabControl>(); List<Button> buttonList = new List<Button>(); DispatcherTimer timer = new DispatcherTimer(); List<AduRadioButtonIcon> _aduRadioButtons = new List<AduRadioButtonIcon>(); Dictionary<string, int> _rootTabDic = new Dictionary<string, int>(); Dictionary<string, int> _parentTabDic = new Dictionary<string, int>(); Dictionary<string, int> _childrenTabDic = new Dictionary<string, int>(); /// <summary> /// 1切多页面字典(key-主页面Id.子页面Id,value-子页面) /// </summary> Dictionary<string, TabItem> _multiMenuItemsDictionary = new Dictionary<string, TabItem>(); readonly User _currentUser; RoleDefine _currentRole; ObservableCollection<RoleDefine> _roles; Stopwatch _logoutStopWatch; int _logoutTime; int _xPosition; private bool _isAllViewUnable = true; public ShellView(IRegionManager regionManager, IRegionNavigationService regionNavigationService) { InitializeComponent(); LoginView loginView = new LoginView(); loginView.ShowDialog(); _currentUser = loginView.CurrentUser; if (!loginView.IsLoginSuccess) { this.Close(); } loginView = null; m_regionManager = regionManager; m_regionNavigationService = regionNavigationService; m_regionManager.RegisterViewWithRegion("TopRegion", typeof(CyberX8_MainPages.Views.TopView)); CyberX8_Core.GlobalEvents.SlotRightClickChangedEvent += Instance_SlotRightClickChangedEvent; CyberX8_Core.GlobalEvents.SlotWaferTransferEvent += Instance_SlotStartTransferEvent; CyberX8_Core.GlobalEvents.SwitchFixedTabItem += GlobalEvents_SwitchFixedTabItem; CyberX8_Core.GlobalEvents.SwitchFixedChildSubItem += GlobalEvents_SwitchFixedChildSubItem; timer.Tick += timer_Tick; timer.Interval = TimeSpan.FromSeconds(0.5); timer.Start(); UIEvents.PMDoorRaiseChangedEvent += UIEvents_PMDoorRaiseChangedEvent; UIEvents.LLTDoorRaiseChangedEvent += UIEvents_LLTDoorRaiseChangedEvent; UIEvents.LLEDoorRaiseChangedEvent += UIEvents_LLEDoorRaiseChangedEvent; UIEvents.ChamberCreateDeleteWaferEvent += UIEvents_ChamberCreateDeleteWaferEvent; this.SourceInitialized += (o, e) => { System.IntPtr handler = (new WinInterop.WindowInteropHelper(this)).Handle; WinInterop.HwndSource.FromHwnd(handler).AddHook(new WinInterop.HwndSourceHook(WindowProc)); }; this.MaxHeight = SystemParameters.WorkArea.Height; ResizeMode = ResizeMode.CanMinimize; this.WindowState = this.WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized; AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); } static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { ShowMessageDialog((Exception)e.ExceptionObject); } static void ShowMessageDialog(Exception ex) { string message = string.Format(" UI unknown exception:{0},\n", $"{ex.StackTrace} {DateTime.Now}"); System.Windows.MessageBox.Show(message + ex.Message, "Unexpected exception", System.Windows.MessageBoxButton.YesNo, System.Windows.MessageBoxImage.Exclamation, System.Windows.MessageBoxResult.No, System.Windows.MessageBoxOptions.DefaultDesktopOnly); //Environment.Exit(0); } void timer_Tick(object sender, EventArgs e) { if (ControlPermission.Instance.Permission && _isAllViewUnable) { SetAllViewEnable(); } if (!ControlPermission.Instance.Permission && !_isAllViewUnable) { SetAllViewDisable(); } if (Anychange.needchange) { Anystationchange(Anychange.menuname, Anychange.args); Anychange.needchange = false; } Tag = DateTime.Now; if (GlobalLogin.Instance.ReLogin) { RestartUI(); } if (_currentRole.IsLocked) { if (_xPosition == (int)(Mouse.GetPosition(this).X)) { if (_logoutStopWatch.ElapsedMilliseconds > _currentRole.LockTime * 1000) { RestartUI(); } } else { _logoutStopWatch.Restart(); } } _xPosition = (int)(Mouse.GetPosition(this).X); } private void Instance_SlotRightClickChangedEvent(OpenSEMI.Ctrlib.Controls.Slot slot) { if (slot != null) { ContextMenu cm = ContextMenuManager.Instance.GetSlotMenus(slot); if (cm != null) { slot.ContextMenu = cm; } return; } } private void Instance_SlotStartTransferEvent(OpenSEMI.Ctrlib.Controls.DragDropEventArgs e) { string info = " from " + e.TranferFrom.ModuleID + " slot " + (e.TranferFrom.SlotID + 1).ToString() + " to " + e.TranferTo.ModuleID + " slot " + (e.TranferTo.SlotID + 1).ToString(); string message = "Are you sure to transfer the wafer: \n" + info; WaferDialogViewModel vm = new WaferDialogViewModel(); vm.ConfirmText = message; WaferDialogView dialog = new WaferDialogView() { Owner = Application.Current.MainWindow, }; dialog.DataContext = vm; dialog.Height = 300; dialog.Width = 400; bool alignflag = false; bool coolingflag = false; double angel = 0; double coolingtime = 0; if (dialog.ShowDialog() == true) { alignflag = (bool)dialog.AlignFlag; coolingflag = (bool)dialog.CoolingFlag; if (alignflag && !string.IsNullOrEmpty(dialog.Angle)) { angel = Convert.ToDouble(dialog.Angle); } if (coolingflag && !string.IsNullOrEmpty(dialog.CoolingTime)) { coolingtime = Convert.ToDouble(dialog.CoolingTime); } //from robot to robot is illegal. Must be stop if (e.TranferFrom.ModuleID == e.TranferTo.ModuleID && (e.TranferTo.ModuleID == ModuleName.EfemRobot.ToString())) { } else InvokeClient.Instance.Service.DoOperation("System.MoveWafer", e.TranferFrom.ModuleID, e.TranferFrom.SlotID, e.TranferTo.ModuleID, e.TranferTo.SlotID, alignflag, angel, coolingflag, coolingtime, ""); } else { ModuleManager.OnFlashWafer(new FlashWaferInformation() { ModuleName = e.TranferFrom.ModuleID, SoltId = e.TranferFrom.SlotID }); //ModuleManager.OnFlashWafer(new FlashWaferInformation() { ModuleName = e.TranferTo.ModuleID, SoltId = e.TranferTo.SlotID }); } e.TranferFrom.ClearDragDropStatus(); e.TranferTo.ClearDragDropStatus(); } /// <summary> /// 将所有页面设置成disable /// </summary> private void SetAllViewDisable() { _isAllViewUnable = true; for (int i = 0; i < MainMenu.Count; i++) { TabControl tabcontrol = centerTabViews[0]; VenusMenu item = MainMenu[i]; for (int j = 0; j < item.MenuItem.Count; j++) { SubItem subitem = item.MenuItem[j]; if (!item.IsShow) { continue; } if (string.IsNullOrEmpty(subitem.View)) { if (subitem.MenuItem != null) { for (int k = 0; k < subitem.MenuItem.Count; k++) { SubItem secSubItem = subitem.MenuItem[k]; if (!string.IsNullOrEmpty(secSubItem.View)) { TabItem tabItem = _multiMenuItemsDictionary[$"{secSubItem.Name}.{secSubItem.Id}"]; Control control = (tabItem.Content as Control); control.IsEnabled = false; } if (secSubItem.MultiItem != null) { for (int h = 0; h < secSubItem.MultiItem.Count; h++) { SubItem hideSubItem = secSubItem.MultiItem[h]; if (hideSubItem.View != null) { TabItem tabItem = _multiMenuItemsDictionary[$"{hideSubItem.ModuleName}.{hideSubItem.Id}"]; Control control = (tabItem.Content as Control); control.IsEnabled = false; } } } } } } else { TabItem tabItem = _multiMenuItemsDictionary[$"{subitem.Name}.{subitem.Id}"]; Control ctrl = (tabItem.Content as Control); ctrl.IsEnabled = false; } } } } /// <summary> /// 将所有页面根据角色权限设置为enable /// </summary> private void SetAllViewEnable() { _isAllViewUnable = false; for (int i = 0; i < MainMenu.Count; i++) { TabControl tabcontrol = centerTabViews[0]; VenusMenu item = MainMenu[i]; ObservableCollection<CyberX8_MainPages.Roles.Menu> menus = _currentRole.Menus[i].Menus; for (int j = 0; j < item.MenuItem.Count; j++) { SubItem subitem = item.MenuItem[j]; if (!item.IsShow) { continue; } if (string.IsNullOrEmpty(subitem.View)) { if (subitem.MenuItem != null) { ObservableCollection<CyberX8_MainPages.Roles.Menu> submenus = menus[j].Menus; for (int k = 0; k < subitem.MenuItem.Count; k++) { SubItem secSubItem = subitem.MenuItem[k]; if (!string.IsNullOrEmpty(secSubItem.View)) { TabItem tabItem = _multiMenuItemsDictionary[$"{secSubItem.Name}.{secSubItem.Id}"]; Control control = (tabItem.Content as Control); if (submenus[k] != null && submenus[k].Permission == MenuPermission.ReadWrite) { control.IsEnabled = true; } } if (secSubItem.MultiItem != null) { ObservableCollection<CyberX8_MainPages.Roles.Menu> secSubmenus = submenus[k].Menus; for (int h = 0; h < secSubItem.MultiItem.Count; h++) { SubItem hideSubItem = secSubItem.MultiItem[h]; if (hideSubItem.View != null) { TabItem tabItem = _multiMenuItemsDictionary[$"{hideSubItem.ModuleName}.{hideSubItem.Id}"]; Control control = (tabItem.Content as Control); if (secSubmenus[h] != null && secSubmenus[h].Permission == MenuPermission.ReadWrite) { control.IsEnabled = true; } } } } } } } else { if (menus[j] != null && menus[j].Permission == MenuPermission.None) { continue; } TabItem tabItem = _multiMenuItemsDictionary[$"{subitem.Name}.{subitem.Id}"]; Control ctrl = (tabItem.Content as Control); if (menus[j] != null && menus[j].Permission == MenuPermission.ReadWrite) { ctrl.IsEnabled = true; } } } } } private void CustomWnd_Loaded(object sender, RoutedEventArgs e) { var h1 = SystemParameters.WorkArea.Height; var h2 = SystemParameters.PrimaryScreenHeight; //this.ResizeMode = ResizeMode.CanResize; //System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth MainMenu = SerializeHelper.Instance.ReadFromJsonFile<List<VenusMenu>>($"Config/UIMenu.json"); _roles = SerializeHelper.Instance.ReadFromJsonFile<ObservableCollection<RoleDefine>>($"Config/UIMenu_permission.json"); int role = (int)_currentUser.Role; _currentRole = _roles[role]; int index = 0; for (int i = 0; i < MainMenu.Count; i++) { if (MainMenu[i].IsShow == false) { continue; } AduRadioButtonIcon aduRadioButtonIcon = new AduRadioButtonIcon(); if (i == 0) { aduRadioButtonIcon.IsChecked = true; } IconElement.SetPathData(aduRadioButtonIcon, (Geometry)aduRadioButtonIcon.FindResource($"Icon_{MainMenu[i].Id}")); aduRadioButtonIcon.Content = MainMenu[i].Name; aduRadioButtonIcon.Click += AduRadioButtonIcon_Click; aduRadioButtonIcon.SelectBackground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#6AD7FF")); aduRadioButtonIcon.SelectColor = new SolidColorBrush((Colors.Black)); aduRadioButtonIcon.DefaultBackground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#94BCD7")); //aduRadioButtonIcon.DefaultBackground = new SolidColorBrush(Colors.DarkGray); aduRadioButtonIcon.Width = 180; aduRadioButtonIcon.Height = 40; //aduRadioButtonIcon.Foreground=Brushes.White; aduRadioButtonIcon.Tag = index; index += 1; Bottom_Frame.Children.Add(aduRadioButtonIcon); _aduRadioButtons.Add(aduRadioButtonIcon); TabControl tabControl = new TabControl(); tabControl.TabIndex = index; _rootTabDic[MainMenu[i].Id] = index; AddSubItem(tabControl, MainMenu[i].MenuItem,index, _currentRole.Menus[i].Menus); centerTabViews.Add(tabControl); } Main_Frame.Content = centerTabViews[0]; ModuleManager.Initialize(); //用户锁 if (_currentRole.IsLocked == true) { _logoutStopWatch = new Stopwatch(); _logoutStopWatch.Start(); _logoutTime = _currentRole.LockTime; } } private void AddSubItem(TabControl tabControl,List<SubItem> subItems,int parentIndex, ObservableCollection<CyberX8_MainPages.Roles.Menu> menus) { int index = parentIndex*100; for(int i=0;i<subItems.Count;i++) { object obj = null; SubItem item= subItems[i]; if(!item.IsShow) { continue; } if(string.IsNullOrEmpty(item.View)) { if (item.MenuItem != null) { obj = new TabControl(); ((TabControl)obj).Name = item.Id; AddSubItem((TabControl)obj, item.MenuItem, index, menus[i].Menus); _parentTabDic[item.Id] = index; } else if (item.MultiItem != null) { //把reservoir主页也加入子页面字典,用于从主页跳转到reservoir页面 _childrenTabDic[item.MultiItem[0].Id.ToString()] = index; TabItem mainTabItem = InitializeMultiItem(item.ModuleName, item.MultiItem, menus[i].Menus); if (mainTabItem != null) { mainTabItem.TabIndex = index; index++; tabControl.Items.Add(mainTabItem); } continue; } } else { //None权限 if (menus[i]!= null && menus[i].Permission == MenuPermission.None) { continue; } string viewClassName = $"CyberX8_MainPages.Views.{item.View}"; Type viewType = Type.GetType($"{viewClassName},CyberX8_MainPages"); obj = System.Activator.CreateInstance(viewType); _childrenTabDic[item.Id] = index; } TabItem tabItem = new TabItem() { Header = item.Name, Content = obj }; Control ctrl = (tabItem.Content as Control); ctrl.Name = item.ModuleName; ctrl.IsVisibleChanged += TabItem_IsVisibleChanged; //登录进去无控制权限 if (_isAllViewUnable) { ctrl.IsEnabled = false; } //只读权限 if (menus[i] != null && menus[i].Permission == MenuPermission.ReadOnly) { ctrl.IsEnabled = false; } tabItem.TabIndex=index; index++; tabControl.Items.Add(tabItem); _multiMenuItemsDictionary.Add($"{item.Name}.{item.Id}", tabItem); //一级标题module某块本身也有一个item对象,任何时刻都要使其可用,确保module二级标题可以点 for (int j = 0; j < subItems.Count; j++) { SubItem item1 = subItems[i]; if (string.IsNullOrEmpty(item1.View)) { TabItem selfItem = _multiMenuItemsDictionary[$"{item1.Name}.{item1.Id}"]; Control selfControl = (selfItem.Content as Control); selfControl.IsEnabled = true; } } } if(tabControl.Items.Count!=0) { tabControl.SelectedIndex = 0; } } private TabItem InitializeMultiItem(string moduleName, List<SubItem> subItems, ObservableCollection<CyberX8_MainPages.Roles.Menu> menus) { TabItem mainTabItem = null; foreach(SubItem item in subItems) { int menusIndex = subItems.IndexOf(item); //None权限 if (menus[menusIndex] != null & menus[menusIndex].Permission == MenuPermission.None) { continue; } string viewClassName = $"CyberX8_MainPages.Views.{item.View}"; Type viewType = Type.GetType($"{viewClassName},CyberX8_MainPages"); Object obj = System.Activator.CreateInstance(viewType); TabItem tabItem = new TabItem() { Header = moduleName, Content = obj }; Control ctrl = (tabItem.Content as Control); ctrl.Name = item.ModuleName; ctrl.IsVisibleChanged += TabItem_IsVisibleChanged; //登录进去无控制权限 if (_isAllViewUnable) { ctrl.IsEnabled = false; } //只读权限 if (menus[menusIndex] != null && menus[menusIndex].Permission == MenuPermission.ReadOnly) { ctrl.IsEnabled = false; } _multiMenuItemsDictionary[$"{moduleName}.{item.Id}"] = tabItem; if (mainTabItem == null&&item.IsShow) { mainTabItem = tabItem; } } return mainTabItem; } /// <summary> /// 重启UI /// </summary> private void RestartUI() { // 获取当前执行的程序集 Assembly assembly = Assembly.GetExecutingAssembly(); // 获取当前执行的程序集的全名 AssemblyName assemblyName = assembly.GetName(); // 构建一个新的进程启动信息,以便重新启动当前应用程序 ProcessStartInfo startInfo = new ProcessStartInfo { FileName = assembly.Location, UseShellExecute = true }; // 关闭当前应用程序 Application.Current.Shutdown(); // 创建一个新的进程来运行当前应用程序 Process.Start(startInfo); } /// <summary> /// 所有页面可见性发生变化事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void TabItem_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) { //TabItem control = sender as TabItem; Control control = sender as Control; var viewmodel = control.DataContext; if (viewmodel != null) { Type t = viewmodel.GetType(); if (e.NewValue != null) { bool isShow = (bool)e.NewValue; if (isShow) { MethodInfo methodInfo = t.GetMethod("LoadData"); methodInfo?.Invoke(viewmodel, new object[] { control.Name }); } else { MethodInfo methodInfo = t.GetMethod("Hide"); methodInfo?.Invoke(viewmodel, null); } } else { MethodInfo methodInfo = t.GetMethod("Hide"); methodInfo?.Invoke(viewmodel, null); } } } public void Anystationchange(string menuviewItem, WaferHistoryWafer queryFilter) { UserControl address = new ProcessHistoryView(); ProcessHistoryViewModel vm = new ProcessHistoryViewModel() { }; vm.searchlot(queryFilter.WaferGuid); //vm.OnDataGridSelectionChanged(vm.Recipes[0]); address.DataContext = vm; int s = 0; for (int i = 0; i < centerTabViews.Count; i++) { var item = centerTabViews[i]; foreach (TabItem v in item.Items) { if (v.Header.ToString() == "Process History") { s = i; } } } if (s != 0) { centerTabViews[s].Items[2] = new TabItem() { Header = menuviewItem, Content = address }; centerTabViews[s].SelectedIndex = 2; Main_Frame.Content = centerTabViews[s]; } } private void AduRadioButtonIcon_Click(object sender, RoutedEventArgs e) { var currentButton = sender as AduRadioButtonIcon; Main_Frame.Content = centerTabViews[Convert.ToInt32(currentButton.Tag)]; } /// <summary> /// 手动切换菜单 /// </summary> /// <param name="root"></param> /// <param name="parent"></param> /// <param name="children"></param> private void GlobalEvents_SwitchFixedTabItem(string root, string parent, string children) { if (_rootTabDic.ContainsKey(root)) { int rootIndex = _rootTabDic[root]; if (rootIndex-1 < centerTabViews.Count) { Main_Frame.Content = centerTabViews[rootIndex-1]; TabControl rootTab = centerTabViews[rootIndex-1]; _aduRadioButtons[rootIndex-1].IsChecked=true; if (!string.IsNullOrEmpty(parent)) { if (_parentTabDic.ContainsKey(parent)) { int parentIndex = _parentTabDic[parent]; rootTab.SelectedIndex = parentIndex-rootIndex*100; TabItem parentTabItem = rootTab.Items[rootTab.SelectedIndex] as TabItem; if (_childrenTabDic.ContainsKey(children)) { TabControl parentTab=parentTabItem.Content as TabControl; int childrenIndex = _childrenTabDic[children]; parentTab.SelectedIndex = childrenIndex-parentIndex*100; } } } else { if (_childrenTabDic.ContainsKey(children)) { int childeIndex = _childrenTabDic[children]; rootTab.SelectedIndex = childeIndex - rootTab.TabIndex * 100; } } } } } /// <summary> /// Reservoir切换页面 /// </summary> /// <param name="child"></param> /// <param name="subItem"></param> /// <exception cref="NotImplementedException"></exception> private void GlobalEvents_SwitchFixedChildSubItem(string child, string subItem) { if (_multiMenuItemsDictionary.ContainsKey($"{child}.{subItem}")) { TabItem tabItem = _multiMenuItemsDictionary[$"{child}.{subItem}"]; TabControl rootTabControl = (TabControl)Main_Frame.Content; if (rootTabControl == null) { return; } if (rootTabControl.SelectedIndex == -1 || rootTabControl.SelectedIndex > rootTabControl.Items.Count - 1) { return; } TabItem parentTab = rootTabControl.Items[rootTabControl.SelectedIndex] as TabItem; if(parentTab == null) { return; } TabControl parentContentTab= parentTab.Content as TabControl; if(parentContentTab == null) { return; } if(parentContentTab.SelectedIndex==-1|| parentContentTab.SelectedIndex > parentContentTab.Items.Count - 1) { return; } int selectedIndex=parentContentTab.SelectedIndex; parentContentTab.SelectedIndex = -1; parentContentTab.Items[selectedIndex] = tabItem; parentContentTab.SelectedIndex = selectedIndex; } } private void CustomWnd_Closed(object sender, EventArgs e) { string ipConfigFilter = ""; if (_isAllViewUnable == false) { var ipconfig = QueryDataClient.Instance.Service.GetConfig($"System.ControlIPFilter"); if (ipconfig != null) { ipConfigFilter = ipconfig.ToString(); } List<string> localIPs = new List<string>(); string hostName = Dns.GetHostName(); IPHostEntry host = Dns.GetHostEntry(hostName); foreach (IPAddress ip in host.AddressList) { if (ip.AddressFamily == AddressFamily.InterNetwork && ip.ToString().Trim().StartsWith($"{ipConfigFilter}")) { localIPs.Add(ip.ToString()); } } if (localIPs.Count > 0) { InvokeClient.Instance.Service.DoOperation($"ReleaseSystemControl", localIPs[0]); } } System.Diagnostics.Process.GetCurrentProcess().Kill(); } private void UIEvents_ChamberCreateDeleteWaferEvent(WaferOperation obj) { if (obj.IsCreate == true) { InvokeClient.Instance.Service.DoOperation("CreateWafer", obj.ModuleName, 0); } else { InvokeClient.Instance.Service.DoOperation("DeleteWafer", obj.ModuleName, 0); } } private void UIEvents_PMDoorRaiseChangedEvent(DoorPara obj) { //InvokeClient.Instance.Service.DoOperation($"{obj?.ModuleName}.SlitDoor.{obj?.IsOpen}"); InvokeClient.Instance.Service.DoOperation($"{obj?.ModuleName}.SetSlitDoor", obj.IsOpen == "Open" ? true : false); } private void UIEvents_LLTDoorRaiseChangedEvent(DoorPara obj) { InvokeClient.Instance.Service.DoOperation($"TM.SetMFSlitDoor", obj.ModuleName, obj.IsOpen == "Open" ? true : false); } private void UIEvents_LLEDoorRaiseChangedEvent(DoorPara obj) { InvokeClient.Instance.Service.DoOperation($"TM.SetEFEMSlitDoor", obj.ModuleName, obj.IsOpen == "Open" ? true : false); } #region 调用api功能部分 void win_SourceInitialized(object sender, EventArgs e) { System.IntPtr handle = (new WinInterop.WindowInteropHelper(this)).Handle; WinInterop.HwndSource.FromHwnd(handle).AddHook(new WinInterop.HwndSourceHook(WindowProc)); } private static System.IntPtr WindowProc( System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) { switch (msg) { case 0x0024: WmGetMinMaxInfo(hwnd, lParam); handled = true; break; } return (System.IntPtr)0; } private static void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam) { MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); // Adjust the maximized size and position to fit the work area of the correct monitor int MONITOR_DEFAULTTONEAREST = 0x00000002; System.IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (monitor != System.IntPtr.Zero) { MONITORINFO monitorInfo = new MONITORINFO(); GetMonitorInfo(monitor, monitorInfo); RECT rcWorkArea = monitorInfo.rcWork; RECT rcMonitorArea = monitorInfo.rcMonitor; mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left); mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top); mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left); mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top); } Marshal.StructureToPtr(mmi, lParam, true); } /// <summary> /// POINT aka POINTAPI /// </summary> [StructLayout(LayoutKind.Sequential)] public struct POINT { /// <summary> /// x coordinate of point. /// </summary> public int x; /// <summary> /// y coordinate of point. /// </summary> public int y; /// <summary> /// Construct a point of coordinates (x,y). /// </summary> public POINT(int x, int y) { this.x = x; this.y = y; } } [StructLayout(LayoutKind.Sequential)] public struct MINMAXINFO { public POINT ptReserved; public POINT ptMaxSize; public POINT ptMaxPosition; public POINT ptMinTrackSize; public POINT ptMaxTrackSize; }; /// <summary> /// </summary> [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public class MONITORINFO { /// <summary> /// </summary> public int cbSize = Marshal.SizeOf(typeof(MONITORINFO)); /// <summary> /// </summary> public RECT rcMonitor = new RECT(); /// <summary> /// </summary> public RECT rcWork = new RECT(); /// <summary> /// </summary> public int dwFlags = 0; } /// <summary> Win32 </summary> [StructLayout(LayoutKind.Sequential, Pack = 0)] public struct RECT { /// <summary> Win32 </summary> public int left; /// <summary> Win32 </summary> public int top; /// <summary> Win32 </summary> public int right; /// <summary> Win32 </summary> public int bottom; /// <summary> Win32 </summary> public static readonly RECT Empty = new RECT(); /// <summary> Win32 </summary> public int Width { get { return Math.Abs(right - left); } // Abs needed for BIDI OS } /// <summary> Win32 </summary> public int Height { get { return bottom - top; } } /// <summary> Win32 </summary> public RECT(int left, int top, int right, int bottom) { this.left = left; this.top = top; this.right = right; this.bottom = bottom; } /// <summary> Win32 </summary> public RECT(RECT rcSrc) { this.left = rcSrc.left; this.top = rcSrc.top; this.right = rcSrc.right; this.bottom = rcSrc.bottom; } /// <summary> Win32 </summary> public bool IsEmpty { get { // BUGBUG : On Bidi OS (hebrew arabic) left > right return left >= right || top >= bottom; } } /// <summary> Return a user friendly representation of this struct </summary> public override string ToString() { if (this == RECT.Empty) { return "RECT {Empty}"; } return "RECT { left : " + left + " / top : " + top + " / right : " + right + " / bottom : " + bottom + " }"; } /// <summary> Determine if 2 RECT are equal (deep compare) </summary> public override bool Equals(object obj) { if (!(obj is Rect)) { return false; } return (this == (RECT)obj); } /// <summary>Return the HashCode for this struct (not garanteed to be unique)</summary> public override int GetHashCode() { return left.GetHashCode() + top.GetHashCode() + right.GetHashCode() + bottom.GetHashCode(); } /// <summary> Determine if 2 RECT are equal (deep compare)</summary> public static bool operator ==(RECT rect1, RECT rect2) { return (rect1.left == rect2.left && rect1.top == rect2.top && rect1.right == rect2.right && rect1.bottom == rect2.bottom); } /// <summary> Determine if 2 RECT are different(deep compare)</summary> public static bool operator !=(RECT rect1, RECT rect2) { return !(rect1 == rect2); } } [DllImport("user32")] internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi); /// <summary> /// /// </summary> [DllImport("User32")] internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags); #endregion } }