using CMM.Library.Method; using CMM.Library.ViewModel; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace DellMonitorControl; public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); PositionWindowNearTray(); Loaded += async (s, e) => await LoadMonitors(); } private void PositionWindowNearTray() { var workArea = SystemParameters.WorkArea; Left = workArea.Right - Width - 10; Top = workArea.Bottom - Height - 10; } private static readonly string LogFile = System.IO.Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "MonitorControl.log"); private static void Log(string msg) { try { System.IO.File.AppendAllText(LogFile, $"{DateTime.Now:HH:mm:ss.fff} {msg}\n"); } catch { } } private async Task LoadMonitors() { var newChildren = new List(); Log("LoadMonitors started"); try { Log("Calling ScanMonitor..."); await CMMCommand.ScanMonitor(); Log("ScanMonitor complete"); Log("Calling ReadMonitorsData..."); var monitors = (await CMMCommand.ReadMonitorsData()).ToList(); Log($"ReadMonitorsData complete, found {monitors.Count} monitors"); if (!monitors.Any()) { Log("No monitors found"); newChildren.Add(new TextBlock { Text = "No DDC/CI monitors detected", Foreground = Brushes.White, FontSize = 14 }); } else { foreach (var m in monitors) { Log($"Processing monitor: {m.MonitorName} ({m.SerialNumber})"); var brightness = await CMMCommand.GetBrightness(m.SerialNumber) ?? 50; Log($" Brightness: {brightness}"); var contrast = await CMMCommand.GetContrast(m.SerialNumber) ?? 50; Log($" Contrast: {contrast}"); var inputSource = await CMMCommand.GetInputSource(m.SerialNumber); Log($" InputSource: {inputSource}"); var inputOptions = await CMMCommand.GetInputSourceOptions(m.SerialNumber); Log($" InputOptions count: {inputOptions.Count}"); var powerStatus = await CMMCommand.GetMonPowerStatus(m.SerialNumber) ?? "Unknown"; Log($" PowerStatus: {powerStatus}"); newChildren.Add(new TextBlock { Text = m.MonitorName, Foreground = Brushes.White, FontSize = 14, FontWeight = FontWeights.Bold, Margin = new Thickness(0, 10, 0, 5) }); newChildren.Add(CreateSliderRow("Brightness", brightness, m.SerialNumber, CMMCommand.SetBrightness)); newChildren.Add(CreateSliderRow("Contrast", contrast, m.SerialNumber, CMMCommand.SetContrast)); if (inputOptions.Count > 0) newChildren.Add(CreateInputRow(inputSource, inputOptions, m.SerialNumber)); newChildren.Add(CreatePowerRow(powerStatus, m.SerialNumber)); } } Log($"Built {newChildren.Count} UI elements"); } catch (Exception ex) { Log($"ERROR: {ex.GetType().Name}: {ex.Message}\n{ex.StackTrace}"); newChildren.Clear(); newChildren.Add(new TextBlock { Text = $"Error: {ex.Message}", Foreground = Brushes.Red, FontSize = 12, TextWrapping = TextWrapping.Wrap }); } Log("Updating UI..."); sp.Children.Clear(); foreach (var child in newChildren) sp.Children.Add(child); Log($"UI updated with {sp.Children.Count} children"); } private StackPanel CreateSliderRow(string label, int value, string serialNumber, Func setCommand) { var row = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0, 3, 0, 3) }; row.Children.Add(new TextBlock { Text = label, Foreground = Brushes.LightGray, Width = 70, FontSize = 12, VerticalAlignment = VerticalAlignment.Center }); var slider = new Slider { Minimum = 0, Maximum = 100, Value = value, Width = 140, Tag = serialNumber }; var valueText = new TextBlock { Text = value.ToString(), Foreground = Brushes.White, Width = 30, FontSize = 12, Margin = new Thickness(5, 0, 0, 0) }; slider.ValueChanged += (s, e) => valueText.Text = ((int)e.NewValue).ToString(); slider.PreviewMouseUp += async (s, e) => { if (s is Slider sl && sl.Tag is string sn) await setCommand(sn, (int)sl.Value); }; row.Children.Add(slider); row.Children.Add(valueText); return row; } private StackPanel CreateInputRow(int? currentInput, List options, string serialNumber) { var row = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0, 3, 0, 3) }; row.Children.Add(new TextBlock { Text = "Input", Foreground = Brushes.LightGray, Width = 70, FontSize = 12, VerticalAlignment = VerticalAlignment.Center }); var combo = new ComboBox { Width = 170, ItemsSource = options, DisplayMemberPath = "Name", Tag = serialNumber }; if (currentInput.HasValue) combo.SelectedItem = options.Find(o => o.Value == currentInput.Value); combo.SelectionChanged += async (s, e) => { if (s is ComboBox cb && cb.Tag is string sn && cb.SelectedItem is InputSourceOption opt) await CMMCommand.SetInputSource(sn, opt.Value); }; row.Children.Add(combo); return row; } private StackPanel CreatePowerRow(string status, string serialNumber) { var row = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0, 3, 0, 3) }; row.Children.Add(new TextBlock { Text = "Power", Foreground = Brushes.LightGray, Width = 70, FontSize = 12, VerticalAlignment = VerticalAlignment.Center }); var btn = new Button { Content = status, Width = 170, Tag = serialNumber }; btn.Click += async (s, e) => { if (s is Button b && b.Tag is string sn) { var current = await CMMCommand.GetMonPowerStatus(sn); if (current == "Sleep" || current == "PowerOff") await CMMCommand.PowerOn(sn); else await CMMCommand.Sleep(sn); await Task.Delay(1000); b.Content = await CMMCommand.GetMonPowerStatus(sn); } }; row.Children.Add(btn); return row; } }