TKK_E32230371/UPSNet/NotificationIcon.cs

242 lines
8.2 KiB
C#

/*
* Created by SharpDevelop.
* User: EVXIO
* Date: 4/3/2025
* Time: 10:01 PM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using System.Text;
namespace UPSNet {
public sealed class NotificationIcon {
private NotifyIcon notifyIcon;
private ContextMenu notificationMenu;
private readonly BackgroundTimer _monitoringTimer;
//UPSApp upsApp = new UPSApp();
private static NotificationIcon _instance;
private static int lastState = -1; //for save cpu by checking state
// Changed to .NET 4.0 compatible property
public static NotifyIcon NotifyIconInstance {
get { return _instance != null ? _instance.notifyIcon : null; }
}
#region Initialize icon and menu
public NotificationIcon() {
_instance = this;
notifyIcon = new NotifyIcon();
notificationMenu = new ContextMenu(InitializeMenu());
notifyIcon.BalloonTipText = "Application is running in the background";
notifyIcon.BalloonTipTitle = "UPS Net v1.0";
notifyIcon.BalloonTipIcon = ToolTipIcon.Info;
notifyIcon.Text = "UPS Net \nBattery: - "; // This is the regular tooltip
notifyIcon.DoubleClick += IconDoubleClick;
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NotificationIcon));
notifyIcon.Icon = (Icon)resources.GetObject("$this.Icon");
notifyIcon.ContextMenu = notificationMenu;
_monitoringTimer = new BackgroundTimer(CheckUPSStatus, 1000);
}
private MenuItem[] InitializeMenu() {
MenuItem[] menu = new MenuItem[]
{
new MenuItem("Show", menuShowClick),
new MenuItem("-"), // Separator
new MenuItem("About", menuAboutClick),
new MenuItem("Exit", menuExitClick)
};
// Enable OwnerDraw for each MenuItem (except separators)
foreach (MenuItem item in menu) {
if (item.Text != "-")
{
item.OwnerDraw = true;
// Attach events to EACH MenuItem (not ContextMenu)
item.DrawItem += MenuItem_DrawItem;
item.MeasureItem += MenuItem_MeasureItem;
}
}
return menu;
}
// Handle drawing for EACH MenuItem
private void MenuItem_DrawItem(object sender, DrawItemEventArgs e){
MenuItem menuItem = (MenuItem)sender;
// Draw background
e.DrawBackground();
// Draw icon (if available)
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NotificationIcon));
Image icon = null;
switch (menuItem.Text) {
case "Show": icon = (Image) resources.GetObject("dashboard16"); break;
case "About": icon = (Image) resources.GetObject("info16"); break;
case "Exit": icon = (Image) resources.GetObject("close16"); break;
//case "About": icon = Properties.Resources.AboutIcon; break;
//case "Exit": icon = Properties.Resources.ExitIcon; break;
}
if (icon != null){
e.Graphics.DrawImage(
icon,
new Rectangle(
e.Bounds.X + 2,
e.Bounds.Y + (e.Bounds.Height - 16) / 2,
16,
16
)
);
}
// Draw text
TextRenderer.DrawText(
e.Graphics,
menuItem.Text,
SystemFonts.MenuFont,
new Rectangle(e.Bounds.X + 20, e.Bounds.Y, e.Bounds.Width - 20, e.Bounds.Height),
e.ForeColor,
TextFormatFlags.VerticalCenter | TextFormatFlags.Left
);
}
// Measure each MenuItem
private void MenuItem_MeasureItem(object sender, MeasureItemEventArgs e){
MenuItem menuItem = (MenuItem)sender;
SizeF textSize = e.Graphics.MeasureString(menuItem.Text, SystemFonts.MenuFont);
e.ItemHeight = Math.Max(16, (int)textSize.Height) + 4;
e.ItemWidth = (int)textSize.Width + 20; // 16 (icon) + 4 (padding)
}
#endregion
#region Main - Program entry point
/// <summary>Program entry point.</summary>
/// <param name="args">Command Line Arguments</param>
[STAThread]
public static void Main(string[] args) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
bool isFirstInstance;
// Please use a unique name for the mutex to prevent conflicts with other programs
using (Mutex mtx = new Mutex(true, "UPSNet", out isFirstInstance)) {
if (isFirstInstance) {
UPSApp.Init();
NotificationIcon notificationIcon = new NotificationIcon();
notificationIcon.notifyIcon.Visible = true;
if (SynchronizationContext.Current == null) {
SynchronizationContext.SetSynchronizationContext(new System.Windows.Forms.WindowsFormsSynchronizationContext());
}
UPSApp.uiContext = SynchronizationContext.Current;
Application.Run();
notificationIcon.notifyIcon.Dispose();
} else {
// The application is already running
// TODO: Display message box or change focus to existing application instance
}
} // releases the Mutex
}
#endregion
#region Event Handlers
private void menuAboutClick(object sender, EventArgs e) {
MessageBox.Show(
"EVXIO UPS Net \nVersion 1.0.0 - Portable Edition \n\nCopyright ©2025 Victor Phoa. All Rights Reserved.",
"About - EVXIO UPS Net",
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
}
private void menuExitClick(object sender, EventArgs e) {
Application.Exit();
}
private void IconDoubleClick(object sender, EventArgs e) {
UPSApp.ShowOrHideForm();
//MessageBox.Show("The icon was double clicked");
}
private void menuShowClick(object sender, EventArgs e) {
UPSApp.ShowForm();
//MessageBox.Show("The icon was double clicked");
}
#endregion
public static string RepeatString(string str, int count){
if (count <= 0) return "";//string.Empty;
if (count == 1) return str;
var sb = new StringBuilder(str.Length * count);
for (int i = 0; i < count; i++) {
sb.Append(str);
}
return sb.ToString();
}
private static void CheckUPSStatus() {
//string s = "";
if (UPSApp.fetcher.IsReachable) {
//s += "OnShut=" + UPSApp.fetcher.OnTimedShutdown + " Remaining=" + UPSApp.fetcher.TimedShutdownRemaining;
if (NotifyIconInstance != null) { // Explicit null check
if (UPSApp.fetcher.OnState){
int maxBars = 4;
int barCount = 0;
if (UPSApp.fetcher.BattMaxLevel > 0) {
barCount = (int)Math.Round((double)UPSApp.fetcher.ChargeLevel * maxBars / UPSApp.fetcher.BattMaxLevel);
} else {
barCount = UPSApp.fetcher.ChargeLevel > 4 ? (int)Math.Round(UPSApp.fetcher.ChargeLevel / 25.0) : UPSApp.fetcher.ChargeLevel;
}
barCount = Math.Max(0, Math.Min(maxBars, barCount));
if (lastState != (100 + barCount)){
lastState = 100 + barCount;
NotifyIconInstance.Text = "UPS Net \nBattery: " +
RepeatString("■", barCount) +
RepeatString(" ", maxBars - barCount);
}
}else{
if (lastState!=200){
lastState = 200;
NotifyIconInstance.Text = "UPS Net \nUPS OFF";
}
}
}
}else{
//s = "Unreachable";
if (NotifyIconInstance != null){
if (lastState!=300){
lastState = 300;
NotifyIconInstance.Text = "UPS Net \nNot Connected";
}
}
}
//Debug.WriteLine("CheckUPSStatus: " + s);
//UPSApp.ManageShutdownRoutine(); //this now managed from OnStatusChanged ata UPSApp
}
}
}