Skip to content

Commit 6ceb7f6

Browse files
committed
Add minimise to system tray and confirm before closing capabilities.
1 parent dc0faeb commit 6ceb7f6

5 files changed

Lines changed: 2603 additions & 230 deletions

File tree

Remote Server/ServerForm.Designer.cs

Lines changed: 108 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Remote Server/ServerForm.cs

Lines changed: 115 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ public partial class ServerForm : Form
147147
internal const string ROLLOVER_LOGS_ENABLED_PROFILENAME = "Rollover Logs Enabled"; public const bool ROLLOVER_LOGS_ENABLED_DEFAULT = false;
148148
internal const string ROLLOVER_TIME_PROFILENAME = "Rollover Time"; public static DateTime ROLLOVER_TIME_DEFAULT = DateTime.Now.Date; // Default value can't be const because it's a date-time type
149149
internal const string USE_UTC_TIME_IN_LOGS_PROFILENAME = "Use UTC Time In Logs"; public const bool USE_UTC_TIME_IN_LOGS_ENABLED_DEFAULT = false;
150+
internal const string MINIMISE_TO_SYSTEM_TRAY_PROFILENAME = "Minimise To System Tray"; public const bool MINIMISE_TO_SYSTEM_TRAY_DEFAULT = false;
151+
internal const string CONFIRM_EXIT_PROFILENAME = "Confirm Exit"; public const bool CONFIRM_EXIT_DEFAULT = false;
152+
153+
// Minimise behaviour strings
154+
internal const string MINIMISE_TO_SYSTEM_TRAY_TEXT = "Minimise to system tray";
155+
internal const string MINIMISE_TO_TASK_BAR_TEXT = "Minimise to task bar";
150156

151157
//Device profile persistence constants
152158
internal const string DEVICE_SUBFOLDER_NAME = "Device";
@@ -252,6 +258,8 @@ public partial class ServerForm : Form
252258
internal static bool RolloverLogsEnabled;
253259
internal static DateTime RolloverTime;
254260
internal static bool UseUtcTimeInLogs;
261+
internal static bool MinimiseToSystemTray;
262+
internal static bool ConfirmExit;
255263

256264
#endregion
257265

@@ -274,6 +282,7 @@ public partial class ServerForm : Form
274282

275283
private static readonly object logLockObject = new object(); // Lock object to ensure that midnight log change overs happen smoothly
276284
private static TraceLoggerPlus TL; // Variable to hold the trace logger
285+
private static FormWindowState formWindowState; // Holds the server form window state in use before the application is minimised to the system tray so that this state can be restored when required
277286

278287
#endregion
279288

@@ -344,6 +353,10 @@ public ServerForm()
344353
this.MinimumSize = new Size(FORM_MINIMUM_WIDTH, FORM_MINIMUM_HEIGHT); // Set the form's minimum size
345354
this.FormClosed += Form1_FormClosed;
346355
this.Resize += ServerForm_Resize;
356+
notifyIcon.MouseDoubleClick += NotifyIcon_MouseDoubleClick;
357+
notifyIcon.Click += NotifyIcon_Click;
358+
systemTrayMenuItems.Items["exit"].Click += SystemTrayCloseServer_Click;
359+
systemTrayMenuItems.Items["Title"].Click += SystemTrayTitle_Click; ;
347360
ServerForm_Resize(this, new EventArgs()); // Move controls to their correct positions
348361

349362
// Check whether this device already has an Alpaca unique ID, if not, create one
@@ -387,6 +400,9 @@ private void ServerForm_Load(object sender, EventArgs e)
387400
this.WindowState = FormWindowState.Minimized;
388401
this.Show();
389402
this.WindowState = FormWindowState.Normal;
403+
404+
// Ensure that the system tray icon is not visible when the application starts
405+
notifyIcon.Visible = false;
390406
}
391407
catch (Exception ex)
392408
{
@@ -415,6 +431,24 @@ private void Form1_FormClosed(object sender, FormClosedEventArgs e)
415431

416432
#region Utility methods
417433

434+
private void CloseServer()
435+
{
436+
// Check whether the server is configured to ask for shutdown confirmation
437+
if (ConfirmExit) // Confirmation is required
438+
{
439+
// Ask the user whether they want to close the remote server
440+
DialogResult result = MessageBox.Show("Are you sure you want to close the Remote Server?", "ASCOM Remote Server", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
441+
442+
// An OK result means the user wants to shut down the Remote Server so close the server form, otherwise do nothing
443+
if (result == DialogResult.OK)
444+
this.Close();
445+
}
446+
else // No confirmation is required so go ahead and shut down the application.
447+
{
448+
this.Close();
449+
}
450+
}
451+
418452
private uint GetServerTransactionID()
419453
{
420454
// Increment the server transaction number in a thread safe way
@@ -1498,6 +1532,8 @@ public static void ReadProfile()
14981532
RolloverLogsEnabled = driverProfile.GetValue<bool>(ROLLOVER_LOGS_ENABLED_PROFILENAME, string.Empty, ROLLOVER_LOGS_ENABLED_DEFAULT);
14991533
RolloverTime = driverProfile.GetValue<DateTime>(ROLLOVER_TIME_PROFILENAME, string.Empty, ROLLOVER_TIME_DEFAULT);
15001534
UseUtcTimeInLogs = driverProfile.GetValue<bool>(USE_UTC_TIME_IN_LOGS_PROFILENAME, string.Empty, USE_UTC_TIME_IN_LOGS_ENABLED_DEFAULT);
1535+
MinimiseToSystemTray = driverProfile.GetValue<bool>(MINIMISE_TO_SYSTEM_TRAY_PROFILENAME, string.Empty, MINIMISE_TO_SYSTEM_TRAY_DEFAULT);
1536+
ConfirmExit = driverProfile.GetValue<bool>(CONFIRM_EXIT_PROFILENAME, string.Empty, CONFIRM_EXIT_DEFAULT);
15011537

15021538
// Set the next log roll-over time using the persisted roll-over time value
15031539
SetNextRolloverTime();
@@ -1614,8 +1650,10 @@ public static void WriteProfile()
16141650
driverProfile.SetValueInvariant<bool>(ROLLOVER_LOGS_ENABLED_PROFILENAME, string.Empty, RolloverLogsEnabled);
16151651
driverProfile.SetValueInvariant<DateTime>(ROLLOVER_TIME_PROFILENAME, string.Empty, RolloverTime);
16161652
driverProfile.SetValueInvariant<bool>(USE_UTC_TIME_IN_LOGS_PROFILENAME, string.Empty, UseUtcTimeInLogs);
1653+
driverProfile.SetValueInvariant<bool>(MINIMISE_TO_SYSTEM_TRAY_PROFILENAME, string.Empty, MinimiseToSystemTray);
1654+
driverProfile.SetValueInvariant<bool>(CONFIRM_EXIT_PROFILENAME, string.Empty, ConfirmExit);
16171655

1618-
// Update the next rollover time in case the time has changed
1656+
// Update the next roll-over time in case the time has changed
16191657
//TL.LogMessage("WriteProfile", $"NextRolloverTime Before: {NextRolloverTime}");
16201658
SetNextRolloverTime();
16211659
//TL.LogMessage("WriteProfile", $"NextRolloverTime After: {NextRolloverTime}");
@@ -1654,6 +1692,26 @@ public static void WriteProfile()
16541692

16551693
#region Form Event handlers
16561694

1695+
/// <summary>
1696+
/// Handle a click to the system tray context menu title
1697+
/// </summary>
1698+
/// <param name="sender"></param>
1699+
/// <param name="e"></param>
1700+
private void SystemTrayTitle_Click(object sender, EventArgs e)
1701+
{
1702+
RestoreForm();
1703+
}
1704+
1705+
/// <summary>
1706+
/// Handle click on the system tray exit menu item
1707+
/// </summary>
1708+
/// <param name="sender"></param>
1709+
/// <param name="e"></param>
1710+
private void SystemTrayCloseServer_Click(object sender, EventArgs e)
1711+
{
1712+
CloseServer();
1713+
}
1714+
16571715
private void BtnSetup_Click(object sender, EventArgs e)
16581716
{
16591717
bool apiEnabled; // Local variables to hold the current server state
@@ -1707,9 +1765,14 @@ private void BtnSetup_Click(object sender, EventArgs e)
17071765
}
17081766
}
17091767

1768+
/// <summary>
1769+
/// Handle server form exit button click
1770+
/// </summary>
1771+
/// <param name="sender"></param>
1772+
/// <param name="e"></param>
17101773
private void BtnExit_Click(object sender, EventArgs e)
17111774
{
1712-
this.Close();
1775+
CloseServer();
17131776
}
17141777

17151778
private void BtnConnectDevices_Click(object sender, EventArgs e)
@@ -1751,7 +1814,7 @@ private void ServerForm_Resize(object sender, EventArgs e)
17511814
{
17521815
Form form = (Form)sender; // Get the supplied control as a Form
17531816

1754-
if (WindowState != FormWindowState.Minimized) // No need to change anything if the window is minimised
1817+
if (WindowState != FormWindowState.Minimized) // Window is visible so update control positions
17551818
{
17561819
int formWidth = form.Width;
17571820
int controlLeftPosition = formWidth - CONTROL_LEFT_OFFSET;
@@ -1814,7 +1877,54 @@ private void ServerForm_Resize(object sender, EventArgs e)
18141877

18151878
// Control Group 6 - Exit button
18161879
BtnExit.Location = new Point(controlCentrePosition, BtnSetup.Top + controlSpacing + 2);
1880+
1881+
formWindowState = this.WindowState; // Save the current form state for restoration later
18171882
}
1883+
else // WIndow is minimised so minimise to system tray if configured to do so
1884+
{
1885+
// Test whether the application should minimise to the task bar or to the system tray
1886+
if (MinimiseToSystemTray) // Minimise to system tray
1887+
{
1888+
Hide(); // Hide the application
1889+
notifyIcon.Visible = true; // Make the system tray icon visible
1890+
}
1891+
else // Minimise to task bar
1892+
{
1893+
// This is normal application behaviour so no action required
1894+
}
1895+
}
1896+
}
1897+
1898+
/// <summary>
1899+
/// Event handler for a double click on the system tray icon that appears when the application is minimised to the system tray
1900+
/// </summary>
1901+
/// <param name="sender">Notifying object</param>
1902+
/// <param name="e">Event arguments</param>
1903+
private void NotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
1904+
{
1905+
RestoreForm();
1906+
}
1907+
private void RestoreForm()
1908+
{
1909+
Show(); // Show the form
1910+
this.WindowState = formWindowState; // Restore to the window state in use before the application was minimised
1911+
notifyIcon.Visible = false; // Hide the system tray icon
1912+
//this.BringToFront();
1913+
}
1914+
1915+
1916+
/// <summary>
1917+
/// System tray icon single so update context menu
1918+
/// </summary>
1919+
/// <param name="sender"></param>
1920+
/// <param name="e"></param>
1921+
private void NotifyIcon_Click(object sender, EventArgs e)
1922+
{
1923+
systemTrayMenuItems.Items["NumberOfDevices"].Text = $"Number of devices: {ConfiguredDevices.Count}";
1924+
systemTrayMenuItems.Items["Ipv4"].Text = $"IP v4 enabled: {IpV4Enabled}";
1925+
systemTrayMenuItems.Items["IPv6"].Text = $"IP v6 enabled: {IpV6Enabled}";
1926+
systemTrayMenuItems.Items["IPAddress"].Text = $"IP Address: {(ServerIPAddressString == "+" ? "All IP addresses" : ServerIPAddressString)}";
1927+
systemTrayMenuItems.Items["Port"].Text = $"Listening on port: {ServerPortNumber}";
18181928
}
18191929

18201930
#endregion
@@ -2101,7 +2211,7 @@ private void ProcessRestRequest(HttpListenerContext context)
21012211

21022212
if (ScreenLogRequests) // Incoming requests are logged to the screen
21032213
{
2104-
if (LogClientIPAddress) LogToScreen($"{clientIpAddress} { request.HttpMethod} {request.Url.AbsolutePath}"); // Include the client IP address if required
2214+
if (LogClientIPAddress) LogToScreen($"{clientIpAddress} {request.HttpMethod} {request.Url.AbsolutePath}"); // Include the client IP address if required
21052215
else LogToScreen($"{request.HttpMethod} {request.Url.AbsolutePath}"); // Otherwise log the request without client IP address
21062216
}
21072217
requestData.ClientIpAddress = clientIpAddress;
@@ -2197,7 +2307,7 @@ private void ProcessRestRequest(HttpListenerContext context)
21972307
if (request.HttpMethod.ToUpperInvariant() == "OPTIONS") // This is a CORS pre-flight request so we need to set some specific headers
21982308
{
21992309
// Set the Access-Control-Allow-Methods and Access-Control-Max-Age headers
2200-
if (DebugTraceState) LogMessage1(requestData, SharedConstants.REQUEST_RECEIVED_STRING, $"OPTIONS method found - This is a CORS PRE_FLIGHT request: {CORS_ALLOWED_METHODS_HEADER} = {CORS_ALLOWED_METHODS}, {CORS_MAX_AGE_HEADER} = { CorsMaxAge}");
2310+
if (DebugTraceState) LogMessage1(requestData, SharedConstants.REQUEST_RECEIVED_STRING, $"OPTIONS method found - This is a CORS PRE_FLIGHT request: {CORS_ALLOWED_METHODS_HEADER} = {CORS_ALLOWED_METHODS}, {CORS_MAX_AGE_HEADER} = {CorsMaxAge}");
22012311
response.Headers.Add(CORS_ALLOWED_METHODS_HEADER, CORS_ALLOWED_METHODS);
22022312
response.Headers.Add(CORS_MAX_AGE_HEADER, CorsMaxAge.ToString());
22032313
ReturnEmpty200Success(requestData);

0 commit comments

Comments
 (0)