164 أسطر
5.1 KiB
C#
164 أسطر
5.1 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Runtime.InteropServices;
|
|
using System.Windows.Forms;
|
|
|
|
namespace Pingerino.Utilities
|
|
{
|
|
public static class UIHelper
|
|
{
|
|
// Windows API constants and imports for form dragging
|
|
public const int WM_NCLBUTTONDOWN = 0xA1;
|
|
public const int HT_CAPTION = 0x2;
|
|
|
|
[DllImport("user32.dll")]
|
|
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
|
|
|
|
[DllImport("user32.dll")]
|
|
public static extern bool ReleaseCapture();
|
|
|
|
[DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
|
|
public static extern IntPtr CreateRoundRectRgn(
|
|
int nLeftRect, int nTopRect, int nRightRect, int nBottomRect,
|
|
int nWidthEllipse, int nHeightEllipse);
|
|
|
|
/// <summary>
|
|
/// Enables form dragging by mouse
|
|
/// </summary>
|
|
public static void EnableFormDragging(Form form, Control dragControl)
|
|
{
|
|
dragControl.MouseDown += (sender, e) =>
|
|
{
|
|
if (e.Button == MouseButtons.Left)
|
|
{
|
|
ReleaseCapture();
|
|
SendMessage(form.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
|
|
}
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Applies rounded corners to a form
|
|
/// </summary>
|
|
public static void ApplyRoundedCorners(Form form, int radius = 30)
|
|
{
|
|
form.Region = Region.FromHrgn(CreateRoundRectRgn(0, 0, form.Width, form.Height, radius, radius));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Safely updates UI control from any thread
|
|
/// </summary>
|
|
public static void SafeInvoke(Control control, Action action)
|
|
{
|
|
if (control == null || control.IsDisposed)
|
|
return;
|
|
|
|
if (control.InvokeRequired)
|
|
{
|
|
try
|
|
{
|
|
control.Invoke(action);
|
|
}
|
|
catch (ObjectDisposedException)
|
|
{
|
|
// Control was disposed while trying to invoke
|
|
}
|
|
catch (InvalidOperationException)
|
|
{
|
|
// Control handle was not created or is being destroyed
|
|
}
|
|
}
|
|
else
|
|
{
|
|
action();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Safely updates UI control from any thread with return value
|
|
/// </summary>
|
|
public static T SafeInvoke<T>(Control control, Func<T> func)
|
|
{
|
|
if (control == null || control.IsDisposed)
|
|
return default(T);
|
|
|
|
if (control.InvokeRequired)
|
|
{
|
|
try
|
|
{
|
|
return (T)control.Invoke(func);
|
|
}
|
|
catch (ObjectDisposedException)
|
|
{
|
|
return default(T);
|
|
}
|
|
catch (InvalidOperationException)
|
|
{
|
|
return default(T);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return func();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Shows an error message with consistent styling
|
|
/// </summary>
|
|
public static void ShowError(string message, string title = "Error")
|
|
{
|
|
MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Shows an information message with consistent styling
|
|
/// </summary>
|
|
public static void ShowInformation(string message, string title = "Information")
|
|
{
|
|
MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Shows a confirmation dialog
|
|
/// </summary>
|
|
public static bool ShowConfirmation(string message, string title = "Confirm")
|
|
{
|
|
return MessageBox.Show(message, title, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Formats time span for display
|
|
/// </summary>
|
|
public static string FormatTimeSpan(TimeSpan timeSpan)
|
|
{
|
|
if (timeSpan.TotalDays >= 1)
|
|
return $"{timeSpan.Days}d {timeSpan.Hours}h {timeSpan.Minutes}m";
|
|
if (timeSpan.TotalHours >= 1)
|
|
return $"{timeSpan.Hours}h {timeSpan.Minutes}m {timeSpan.Seconds}s";
|
|
if (timeSpan.TotalMinutes >= 1)
|
|
return $"{timeSpan.Minutes}m {timeSpan.Seconds}s";
|
|
|
|
return $"{timeSpan.Seconds}.{timeSpan.Milliseconds:000}s";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Formats bytes for display
|
|
/// </summary>
|
|
public static string FormatBytes(long bytes)
|
|
{
|
|
string[] suffixes = { "B", "KB", "MB", "GB", "TB" };
|
|
int counter = 0;
|
|
decimal number = bytes;
|
|
|
|
while (Math.Round(number / 1024) >= 1)
|
|
{
|
|
number /= 1024;
|
|
counter++;
|
|
}
|
|
|
|
return $"{number:n1} {suffixes[counter]}";
|
|
}
|
|
}
|
|
}
|