using ivf_tl_Operate.View; using ivf_tl_Operate.ViewModel; using ivf_tl_Operate.Windows; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace ivf_tl_Operate { /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); //DisableWPFTabletSupport(); Loaded += MainWindow_Loaded; // M4-01-1:自适应竖屏框架。原仅 #if DEBUG 才用 Viewbox 等比缩放, // 导致 Release 无缩放、换分辨率必错位。此处去掉条件编译,让 Viewbox // 在所有配置(含 Release)生效:MainGrid → Viewbox(Stretch=Uniform,等比保竖屏比例) → 窗口内容。 // 窗口尺寸由 WindowState=Maximized 铺满实际屏幕,不再硬编码 1824×2736(已删 .xaml 写死 Width/Height)。 // [D6] 最终是否需 Stretch=Fill 或切真弹性布局、设计基准分辨率取值依赖 Surface 真机,登记待验证。 Grid originalCanvas = MainGrid; this.Content = null; Viewbox viewbox = new Viewbox { Child = originalCanvas, Stretch = Stretch.Uniform }; this.Content = viewbox; } private void MainWindow_Loaded(object sender, RoutedEventArgs e) { var a = new LoginWindow(this).ShowDialog(); if (a != true) { this.Close(); return; } AppData.Instance.MainWindow = this; MainPageViewModel mainPageViewModel = new MainPageViewModel(AppData.Instance.TlSn); MainPageView mainPageView = new MainPageView(); mainPageView.DataContext = mainPageViewModel; AppData.Instance.MainPageView = mainPageView; LoadPage(mainPageView); // 双进程改造:control 已剥离为独立进程 ivf_tl_ControlHost.exe。 // operate 登录后只负责"确保 control 在跑"(探活→不在则拉起→轮询就绪), // 不再在本进程内跑 StartRun。operate 关闭后 control 继续驱动机器。 System.Threading.Tasks.Task.Run(() => { try { string account = AppData.Instance.CurrentUserInfo.account; string password = AppData.Instance.CurrentUserInfo.password; string cacheDisk = System.Configuration.ConfigurationManager.AppSettings["cacheDisk"] ?? "C"; if (string.IsNullOrEmpty(account) || string.IsNullOrEmpty(password)) { ivf_tl_Services.Log4netHelper.WriteLog("跳过拉起 control:operate 登录账号/密码为空"); return; } bool ok = ivf_tl_Operate.Helpers.ControlProcessLauncher.EnsureRunning( account, password, cacheDisk, msg => ivf_tl_Services.Log4netHelper.WriteLog(msg)); ivf_tl_Services.Log4netHelper.WriteLog(ok ? "control 进程就绪" : "control 进程未就绪(降级:operate 仍可用)"); } catch (Exception ex) { ivf_tl_Services.Log4netHelper.WriteLog("确保 control 运行异常", ex); } }); } public void LoadPage(UserControl t) { _container.Content = t; } /// /// 显示与隐藏遮罩层 /// /// public void Mark(bool v) { Application.Current.Dispatcher.Invoke(() => { if (v == true) { this._mask.Visibility = Visibility.Visible; } else { this._mask.Visibility = Visibility.Hidden; } }); } public void DisableWPFTabletSupport() { TabletDeviceCollection devices = System.Windows.Input.Tablet.TabletDevices; if (devices.Count > 0) { Type inputManagerType = typeof(System.Windows.Input.InputManager); object stylusLogic = inputManagerType.InvokeMember("StylusLogic", BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic, null, InputManager.Current, null); if (stylusLogic != null) { Type stylusLogicType = stylusLogic.GetType(); while (devices.Count > 0) { stylusLogicType.InvokeMember("OnTabletRemoved", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic, null, stylusLogic, new object[] { (uint)0 }); } } } } } }