using System; using System.Windows.Forms; using Microsoft.Win32; namespace Decal.DenAgent { /// /// Options/settings dialog for Decal configuration. /// Manages registry settings under HKLM\SOFTWARE\Decal. /// Replaces the MFC cOptionsDlg class. /// internal sealed class OptionsForm : Form { private readonly NumericUpDown _nudBarAlpha; private readonly NumericUpDown _nudViewAlpha; private readonly ComboBox _cbDockPos; private readonly CheckBox _chkTimestamp; private readonly TextBox _txtTimestampFormat; private readonly CheckBox _chkWindowed; private readonly CheckBox _chkDualLog; private readonly CheckBox _chkNoMovies; private readonly CheckBox _chkNoSplash; public OptionsForm() { Text = "Decal Options"; Size = new System.Drawing.Size(380, 340); FormBorderStyle = FormBorderStyle.FixedDialog; MaximizeBox = false; MinimizeBox = false; StartPosition = FormStartPosition.CenterParent; int y = 15; // View Options group var grpView = new GroupBox { Text = "View Options", Location = new System.Drawing.Point(10, y), Size = new System.Drawing.Size(350, 90) }; Controls.Add(grpView); grpView.Controls.Add(new Label { Text = "Bar Alpha:", Location = new System.Drawing.Point(10, 25), AutoSize = true }); _nudBarAlpha = new NumericUpDown { Location = new System.Drawing.Point(100, 22), Size = new System.Drawing.Size(60, 23), Minimum = 0, Maximum = 255, Value = 255 }; grpView.Controls.Add(_nudBarAlpha); grpView.Controls.Add(new Label { Text = "View Alpha:", Location = new System.Drawing.Point(180, 25), AutoSize = true }); _nudViewAlpha = new NumericUpDown { Location = new System.Drawing.Point(270, 22), Size = new System.Drawing.Size(60, 23), Minimum = 0, Maximum = 255, Value = 255 }; grpView.Controls.Add(_nudViewAlpha); grpView.Controls.Add(new Label { Text = "Dock Position:", Location = new System.Drawing.Point(10, 58), AutoSize = true }); _cbDockPos = new ComboBox { Location = new System.Drawing.Point(100, 55), Size = new System.Drawing.Size(100, 23), DropDownStyle = ComboBoxStyle.DropDownList }; _cbDockPos.Items.AddRange(new object[] { "Top", "Left", "Right" }); _cbDockPos.SelectedIndex = 0; grpView.Controls.Add(_cbDockPos); y += 100; // Timestamp group var grpTS = new GroupBox { Text = "Time Stamping", Location = new System.Drawing.Point(10, y), Size = new System.Drawing.Size(350, 55) }; Controls.Add(grpTS); _chkTimestamp = new CheckBox { Text = "Enable Timestamps", Location = new System.Drawing.Point(10, 22), AutoSize = true }; _chkTimestamp.CheckedChanged += (s, e) => _txtTimestampFormat.Enabled = _chkTimestamp.Checked; grpTS.Controls.Add(_chkTimestamp); grpTS.Controls.Add(new Label { Text = "Format:", Location = new System.Drawing.Point(170, 24), AutoSize = true }); _txtTimestampFormat = new TextBox { Location = new System.Drawing.Point(220, 21), Size = new System.Drawing.Size(110, 23), Text = "[%H:%M]", Enabled = false }; grpTS.Controls.Add(_txtTimestampFormat); y += 65; // Client Patches group var grpPatches = new GroupBox { Text = "Client Patches", Location = new System.Drawing.Point(10, y), Size = new System.Drawing.Size(350, 90) }; Controls.Add(grpPatches); _chkWindowed = new CheckBox { Text = "Allow Windowed Mode", Location = new System.Drawing.Point(10, 20), AutoSize = true }; grpPatches.Controls.Add(_chkWindowed); _chkDualLog = new CheckBox { Text = "Allow Dual Logging", Location = new System.Drawing.Point(10, 42), AutoSize = true }; grpPatches.Controls.Add(_chkDualLog); _chkNoMovies = new CheckBox { Text = "Disable Movies", Location = new System.Drawing.Point(190, 20), AutoSize = true }; grpPatches.Controls.Add(_chkNoMovies); _chkNoSplash = new CheckBox { Text = "Disable Splash Screen", Location = new System.Drawing.Point(190, 42), AutoSize = true }; grpPatches.Controls.Add(_chkNoSplash); y += 100; // OK / Cancel buttons var btnOK = new Button { Text = "OK", DialogResult = DialogResult.OK, Location = new System.Drawing.Point(200, y), Size = new System.Drawing.Size(75, 25) }; btnOK.Click += OnOK; Controls.Add(btnOK); var btnCancel = new Button { Text = "Cancel", DialogResult = DialogResult.Cancel, Location = new System.Drawing.Point(285, y), Size = new System.Drawing.Size(75, 25) }; Controls.Add(btnCancel); AcceptButton = btnOK; CancelButton = btnCancel; LoadSettings(); } private void LoadSettings() { try { using var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Decal"); if (key == null) return; _nudBarAlpha.Value = Math.Min(255, Math.Max(0, (int)(key.GetValue("BarAlpha") ?? 255))); _nudViewAlpha.Value = Math.Min(255, Math.Max(0, (int)(key.GetValue("ViewAlpha") ?? 255))); int dockPos = (int)(key.GetValue("BarDock") ?? 0); if (dockPos >= 0 && dockPos < _cbDockPos.Items.Count) _cbDockPos.SelectedIndex = dockPos; _chkTimestamp.Checked = ((int)(key.GetValue("Timestamp") ?? 0)) != 0; _txtTimestampFormat.Text = key.GetValue("TimestampFormat") as string ?? "[%H:%M]"; _txtTimestampFormat.Enabled = _chkTimestamp.Checked; _chkWindowed.Checked = ((int)(key.GetValue("AllowWindowed") ?? 0)) != 0; _chkDualLog.Checked = ((int)(key.GetValue("AllowDualLog") ?? 0)) != 0; _chkNoMovies.Checked = ((int)(key.GetValue("NoMovies") ?? 0)) != 0; _chkNoSplash.Checked = ((int)(key.GetValue("NoSplash") ?? 0)) != 0; } catch { /* Default values are fine */ } } private void OnOK(object sender, EventArgs e) { try { using var key = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Decal"); if (key == null) return; key.SetValue("BarAlpha", (int)_nudBarAlpha.Value, RegistryValueKind.DWord); key.SetValue("ViewAlpha", (int)_nudViewAlpha.Value, RegistryValueKind.DWord); key.SetValue("BarDock", _cbDockPos.SelectedIndex, RegistryValueKind.DWord); key.SetValue("Timestamp", _chkTimestamp.Checked ? 1 : 0, RegistryValueKind.DWord); key.SetValue("TimestampFormat", _txtTimestampFormat.Text); key.SetValue("AllowWindowed", _chkWindowed.Checked ? 1 : 0, RegistryValueKind.DWord); key.SetValue("AllowDualLog", _chkDualLog.Checked ? 1 : 0, RegistryValueKind.DWord); key.SetValue("NoMovies", _chkNoMovies.Checked ? 1 : 0, RegistryValueKind.DWord); key.SetValue("NoSplash", _chkNoSplash.Checked ? 1 : 0, RegistryValueKind.DWord); } catch (Exception ex) { MessageBox.Show($"Failed to save settings: {ex.Message}\n\nYou may need to run as Administrator.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } }