diff --git a/DD2Switcher/DD2Switcher.csproj b/DD2Switcher/DD2Switcher.csproj index 24f1ef7..2d22f56 100644 --- a/DD2Switcher/DD2Switcher.csproj +++ b/DD2Switcher/DD2Switcher.csproj @@ -56,6 +56,9 @@ Form1.cs + + Form + @@ -84,6 +87,9 @@ + + PreserveNewest + \ No newline at end of file diff --git a/DD2Switcher/Form1.Designer.cs b/DD2Switcher/Form1.Designer.cs index e327d81..be3104b 100644 --- a/DD2Switcher/Form1.Designer.cs +++ b/DD2Switcher/Form1.Designer.cs @@ -26,11 +26,67 @@ /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); + this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components); + this.trayMenu = new System.Windows.Forms.ContextMenuStrip(this.components); + this.settingsMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.separatorMenuItem = new System.Windows.Forms.ToolStripSeparator(); + this.exitMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.trayMenu.SuspendLayout(); + this.SuspendLayout(); + // + // notifyIcon + // + this.notifyIcon.ContextMenuStrip = this.trayMenu; + this.notifyIcon.Text = "DD2Switcher"; + this.notifyIcon.Visible = true; + this.notifyIcon.MouseDoubleClick += + new System.Windows.Forms.MouseEventHandler(this.notifyIcon_MouseDoubleClick); + // + // trayMenu + // + this.trayMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.settingsMenuItem, this.separatorMenuItem, this.exitMenuItem + }); + this.trayMenu.Name = "trayMenu"; + this.trayMenu.Size = new System.Drawing.Size(120, 54); + // + // settingsMenuItem + // + this.settingsMenuItem.Name = "settingsMenuItem"; + this.settingsMenuItem.Size = new System.Drawing.Size(119, 22); + this.settingsMenuItem.Text = "Settings"; + this.settingsMenuItem.Click += new System.EventHandler(this.settingsMenuItem_Click); + // + // separatorMenuItem + // + this.separatorMenuItem.Name = "separatorMenuItem"; + this.separatorMenuItem.Size = new System.Drawing.Size(116, 6); + // + // exitMenuItem + // + this.exitMenuItem.Name = "exitMenuItem"; + this.exitMenuItem.Size = new System.Drawing.Size(119, 22); + this.exitMenuItem.Text = "Exit"; + this.exitMenuItem.Click += new System.EventHandler(this.exitMenuItem_Click); + // + // Form1 + // this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(800, 450); - this.Text = "Form1"; + this.Text = "DD2Switcher"; + this.WindowState = System.Windows.Forms.FormWindowState.Minimized; + this.ShowInTaskbar = false; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); + this.trayMenu.ResumeLayout(false); + this.ResumeLayout(false); } #endregion + + private System.Windows.Forms.NotifyIcon notifyIcon; + private System.Windows.Forms.ContextMenuStrip trayMenu; + private System.Windows.Forms.ToolStripMenuItem settingsMenuItem; + private System.Windows.Forms.ToolStripSeparator separatorMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitMenuItem; } } \ No newline at end of file diff --git a/DD2Switcher/Form1.cs b/DD2Switcher/Form1.cs index 4595d64..eb8d2c3 100644 --- a/DD2Switcher/Form1.cs +++ b/DD2Switcher/Form1.cs @@ -1,9 +1,60 @@ -using System.Windows.Forms; +using System; +using System.Windows.Forms; namespace DD2Switcher { public partial class Form1 : Form { + private SettingsForm settingsForm; + public Form1() { InitializeComponent(); + LoadIcons(); + this.Load += Form1_Load; + } + + private void Form1_Load(object sender, EventArgs e) { + // Hide the form initially since we're running in system tray + this.Hide(); + } + + private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e) { + ShowSettings(); + } + + private void settingsMenuItem_Click(object sender, EventArgs e) { + ShowSettings(); + } + + private void exitMenuItem_Click(object sender, EventArgs e) { + Application.Exit(); + } + + private void Form1_FormClosing(object sender, FormClosingEventArgs e) { + // Prevent the form from closing, just hide it + if (e.CloseReason == CloseReason.UserClosing) { + e.Cancel = true; + this.Hide(); + } + } + + private void ShowSettings() { + if (settingsForm == null || settingsForm.IsDisposed) { + settingsForm = new SettingsForm(); + } + + settingsForm.Show(); + settingsForm.BringToFront(); + } + + private void LoadIcons() { + try { + string iconPath = System.IO.Path.Combine( + System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), + "app.ico"); + this.Icon = new System.Drawing.Icon(iconPath); + this.notifyIcon.Icon = new System.Drawing.Icon(iconPath); + } catch { + // Use default icon if custom icon not found + } } } } \ No newline at end of file diff --git a/DD2Switcher/Program.cs b/DD2Switcher/Program.cs index fe88640..a4ba468 100644 --- a/DD2Switcher/Program.cs +++ b/DD2Switcher/Program.cs @@ -10,6 +10,29 @@ namespace DD2Switcher { internal static class Program { private static int NumProc = 19; private static Process[] windows = new Process[NumProc]; + + // Public access to tracked windows for the settings form + public static Process[] GetTrackedWindows() { + return windows; + } + + public static void UntrackWindow(int index) { + if (index >= 0 && index < NumProc) { + windows[index] = null; + // Compact the array by shifting non-null elements to the left + for (int i = index; i < NumProc - 1; i++) { + windows[i] = windows[i + 1]; + } + windows[NumProc - 1] = null; + + // Update ActiveIndex if needed + if (ActiveIndex == index) { + ActiveIndex = -1; + } else if (ActiveIndex > index) { + ActiveIndex--; + } + } + } private static int ActiveIndex = -1; private static bool AltPressed = false; @@ -246,6 +269,7 @@ namespace DD2Switcher { } private static void TabToPrevious() { + return; try { var foreground = GetForegroundProcess(); if (!ProcessTracked(foreground.Id)) { @@ -288,7 +312,8 @@ namespace DD2Switcher { [STAThread] private static void Main() { - // AllocConsole(); + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); var processes = Process.GetProcesses(); var currentProcess = Process.GetCurrentProcess(); @@ -356,8 +381,8 @@ namespace DD2Switcher { } } - // Console.CancelKeyPress += (sender, e) => { Process.GetCurrentProcess().Kill(); }; - Application.Run(); + // Run the WinForms application with Form1 as the main form + Application.Run(new Form1()); KeyboardHook.Stop(); } } diff --git a/DD2Switcher/SettingsForm.cs b/DD2Switcher/SettingsForm.cs new file mode 100644 index 0000000..b90415b --- /dev/null +++ b/DD2Switcher/SettingsForm.cs @@ -0,0 +1,274 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Linq; +using System.Windows.Forms; + +namespace DD2Switcher { + public partial class SettingsForm : Form { + private Label titleLabel; + private FlowLayoutPanel windowsPanel; + private Label statusLabel; + private Button refreshButton; + private Button closeButton; + private int firstIndex = -1; + private int lastIndex = -1; + + public SettingsForm() { + InitializeComponent(); + LoadIcon(); + RefreshWindowsList(); + } + + private void InitializeComponent() { + this.titleLabel = new Label(); + this.windowsPanel = new FlowLayoutPanel(); + this.statusLabel = new Label(); + this.refreshButton = new Button(); + this.closeButton = new Button(); + this.SuspendLayout(); + // + // titleLabel + // + this.titleLabel.AutoSize = true; + this.titleLabel.Font = new Font("Segoe UI", 14F, FontStyle.Bold); + this.titleLabel.Location = new Point(20, 20); + this.titleLabel.Name = "titleLabel"; + this.titleLabel.Size = new Size(200, 25); + this.titleLabel.Text = "DD2Switcher Settings"; + // + // windowsPanel + // + this.windowsPanel.AutoScroll = true; + this.windowsPanel.BorderStyle = BorderStyle.FixedSingle; + this.windowsPanel.Location = new Point(20, 60); + this.windowsPanel.Name = "windowsPanel"; + this.windowsPanel.Size = new Size(560, 300); + this.windowsPanel.Padding = new Padding(10); + this.windowsPanel.BackColor = Color.White; + // + // statusLabel + // + this.statusLabel.AutoSize = true; + this.statusLabel.Location = new Point(20, 380); + this.statusLabel.Name = "statusLabel"; + this.statusLabel.Size = new Size(400, 15); + this.statusLabel.Text = "DD2Switcher is running in the system tray."; + // + // refreshButton + // + this.refreshButton.Location = new Point(450, 375); + this.refreshButton.Name = "refreshButton"; + this.refreshButton.Size = new Size(75, 23); + this.refreshButton.Text = "Refresh"; + this.refreshButton.Click += new EventHandler(this.refreshButton_Click); + // + // closeButton + // + this.closeButton.Location = new Point(530, 375); + this.closeButton.Name = "closeButton"; + this.closeButton.Size = new Size(75, 23); + this.closeButton.Text = "Close"; + this.closeButton.Click += new EventHandler(this.closeButton_Click); + // + // SettingsForm + // + this.AutoScaleDimensions = new SizeF(6F, 13F); + this.AutoScaleMode = AutoScaleMode.Font; + this.ClientSize = new Size(600, 420); + this.Controls.Add(this.titleLabel); + this.Controls.Add(this.windowsPanel); + this.Controls.Add(this.statusLabel); + this.Controls.Add(this.refreshButton); + this.Controls.Add(this.closeButton); + this.Name = "SettingsForm"; + this.Text = "DD2Switcher Settings"; + this.StartPosition = FormStartPosition.CenterScreen; + this.FormBorderStyle = FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.ResumeLayout(false); + this.PerformLayout(); + } + + private void closeButton_Click(object sender, EventArgs e) { + this.Close(); + } + + private void refreshButton_Click(object sender, EventArgs e) { + RefreshWindowsList(); + } + + private void RefreshWindowsList() { + windowsPanel.Controls.Clear(); + + // Get tracked windows from Program + var trackedWindows = GetTrackedWindows(); + + if (trackedWindows.Count == 0) { + var noWindowsLabel = new Label(); + noWindowsLabel.Text = "No windows currently tracked"; + noWindowsLabel.AutoSize = true; + noWindowsLabel.ForeColor = Color.Gray; + noWindowsLabel.Font = new Font("Segoe UI", 10F); + windowsPanel.Controls.Add(noWindowsLabel); + return; + } + + for (int i = 0; i < trackedWindows.Count; i++) { + var window = trackedWindows[i]; + if (window == null) + continue; + + var windowPanel = CreateWindowPanel(i, window); + windowsPanel.Controls.Add(windowPanel); + } + } + + private Panel CreateWindowPanel(int index, Process window) { + var panel = new Panel(); + panel.Width = 520; + panel.Height = 80; + panel.BorderStyle = BorderStyle.FixedSingle; + panel.Margin = new Padding(5); + panel.BackColor = Color.LightGray; + + // Index label + var indexLabel = new Label(); + indexLabel.Text = $"Index: {index}"; + indexLabel.Location = new Point(10, 5); + indexLabel.AutoSize = true; + indexLabel.Font = new Font("Segoe UI", 9F, FontStyle.Bold); + panel.Controls.Add(indexLabel); + + // Process name + var nameLabel = new Label(); + nameLabel.Text = $"Name: {window.ProcessName}"; + nameLabel.Location = new Point(10, 25); + nameLabel.AutoSize = true; + nameLabel.Font = new Font("Segoe UI", 9F); + panel.Controls.Add(nameLabel); + + // PID + var pidLabel = new Label(); + pidLabel.Text = $"PID: {window.Id}"; + pidLabel.Location = new Point(10, 45); + pidLabel.AutoSize = true; + pidLabel.Font = new Font("Segoe UI", 9F); + panel.Controls.Add(pidLabel); + + // Window title + var titleLabel = new Label(); + titleLabel.Text = $"Title: {window.MainWindowTitle}"; + titleLabel.Location = new Point(200, 25); + titleLabel.AutoSize = true; + titleLabel.Font = new Font("Segoe UI", 9F); + titleLabel.MaximumSize = new Size(200, 0); + panel.Controls.Add(titleLabel); + + // First/Last indicator + var firstLastLabel = new Label(); + firstLastLabel.Text = GetFirstLastText(index); + firstLastLabel.Location = new Point(200, 45); + firstLastLabel.AutoSize = true; + firstLastLabel.Font = new Font("Segoe UI", 9F, FontStyle.Bold); + firstLastLabel.ForeColor = Color.DarkBlue; + panel.Controls.Add(firstLastLabel); + + // Pick button + var pickButton = new Button(); + pickButton.Text = "Pick"; + pickButton.Location = new Point(420, 10); + pickButton.Size = new Size(50, 25); + pickButton.Tag = index; + pickButton.Click += PickButton_Click; + panel.Controls.Add(pickButton); + + // Untrack button + var untrackButton = new Button(); + untrackButton.Text = "Untrack"; + untrackButton.Location = new Point(420, 45); + untrackButton.Size = new Size(50, 25); + untrackButton.Tag = index; + untrackButton.Click += UntrackButton_Click; + panel.Controls.Add(untrackButton); + + return panel; + } + + private string GetFirstLastText(int index) { + if (index == firstIndex && index == lastIndex) { + return "First & Last"; + } else if (index == firstIndex) { + return "First"; + } else if (index == lastIndex) { + return "Last"; + } + return ""; + } + + private void PickButton_Click(object sender, EventArgs e) { + var button = (Button)sender; + int index = (int)button.Tag; + + if (firstIndex == -1) { + // First pick - set both first and last + firstIndex = index; + lastIndex = index; + } else if (lastIndex == -1) { + // Second pick - set last + lastIndex = index; + } else { + // Subsequent picks - determine which becomes first + if (index < firstIndex) { + // New index is lower, so it becomes first + lastIndex = firstIndex; + firstIndex = index; + } else { + // New index is higher, so it becomes last + lastIndex = index; + } + } + + RefreshWindowsList(); + } + + private void UntrackButton_Click(object sender, EventArgs e) { + var button = (Button)sender; + int index = (int)button.Tag; + + // Remove from tracked windows + UntrackWindow(index); + + // Update first/last indices if needed + if (index == firstIndex) { + firstIndex = -1; + } + if (index == lastIndex) { + lastIndex = -1; + } + + RefreshWindowsList(); + } + + private List GetTrackedWindows() { + var windows = Program.GetTrackedWindows(); + return windows.ToList(); + } + + private void UntrackWindow(int index) { + Program.UntrackWindow(index); + } + + private void LoadIcon() { + try { + this.Icon = new Icon(System.IO.Path.Combine( + System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), + "app.ico")); + } catch { + // Use default icon if custom icon not found + } + } + } +} \ No newline at end of file diff --git a/DD2Switcher/app.ico b/DD2Switcher/app.ico new file mode 100644 index 0000000..b0e639d Binary files /dev/null and b/DD2Switcher/app.ico differ