mirror of
https://github.com/jkocon/g-helper.git
synced 2026-02-23 13:00:52 +01:00
397 lines
13 KiB
C#
397 lines
13 KiB
C#
using Microsoft.Win32;
|
|
using System.ComponentModel;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace CustomControls
|
|
{
|
|
|
|
public class RForm : Form
|
|
{
|
|
|
|
public static Color colorEco = Color.FromArgb(255, 6, 180, 138);
|
|
public static Color colorStandard = Color.FromArgb(255, 58, 174, 239);
|
|
public static Color colorTurbo = Color.FromArgb(255, 255, 32, 32);
|
|
|
|
public static Color buttonMain;
|
|
public static Color buttonSecond;
|
|
|
|
public static Color formBack;
|
|
public static Color foreMain;
|
|
public static Color borderMain;
|
|
public static Color chartMain;
|
|
public static Color chartGrid;
|
|
|
|
[DllImport("UXTheme.dll", SetLastError = true, EntryPoint = "#138")]
|
|
public static extern bool CheckSystemDarkModeStatus();
|
|
|
|
[DllImport("DwmApi")] //System.Runtime.InteropServices
|
|
private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, int[] attrValue, int attrSize);
|
|
|
|
public bool darkTheme = false;
|
|
|
|
public static void InitColors(bool darkTheme)
|
|
{
|
|
if (darkTheme)
|
|
{
|
|
buttonMain = Color.FromArgb(255, 55, 55, 55);
|
|
buttonSecond = Color.FromArgb(255, 38, 38, 38);
|
|
|
|
formBack = Color.FromArgb(255, 28, 28, 28);
|
|
foreMain = Color.FromArgb(255, 240, 240, 240);
|
|
borderMain = Color.FromArgb(255, 50, 50, 50);
|
|
|
|
chartMain = Color.FromArgb(255, 35, 35, 35);
|
|
chartGrid = Color.FromArgb(255, 70, 70, 70);
|
|
}
|
|
else
|
|
{
|
|
buttonMain = SystemColors.ControlLightLight;
|
|
buttonSecond = SystemColors.ControlLight;
|
|
|
|
formBack = SystemColors.Control;
|
|
foreMain = SystemColors.ControlText;
|
|
borderMain = Color.LightGray;
|
|
|
|
chartMain = SystemColors.ControlLightLight;
|
|
chartGrid = Color.LightGray;
|
|
}
|
|
}
|
|
|
|
private static bool IsDarkTheme()
|
|
{
|
|
using var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
|
|
var registryValueObject = key?.GetValue("AppsUseLightTheme");
|
|
|
|
if (registryValueObject == null) return false;
|
|
return (int)registryValueObject <= 0;
|
|
}
|
|
|
|
public bool InitTheme(bool setDPI = false)
|
|
{
|
|
bool newDarkTheme = CheckSystemDarkModeStatus();
|
|
bool changed = (darkTheme != newDarkTheme);
|
|
darkTheme = newDarkTheme;
|
|
|
|
InitColors(darkTheme);
|
|
|
|
if (setDPI)
|
|
ControlHelper.Resize(this);
|
|
|
|
if (changed)
|
|
{
|
|
DwmSetWindowAttribute(this.Handle, 20, new[] { darkTheme ? 1 : 0 }, 4);
|
|
ControlHelper.Adjust(this, changed);
|
|
}
|
|
|
|
return changed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
public class RCheckBox : CheckBox
|
|
{
|
|
|
|
}
|
|
|
|
|
|
public class RComboBox : ComboBox
|
|
{
|
|
private Color borderColor = Color.Gray;
|
|
[DefaultValue(typeof(Color), "Gray")]
|
|
public Color BorderColor
|
|
{
|
|
get { return borderColor; }
|
|
set
|
|
{
|
|
if (borderColor != value)
|
|
{
|
|
borderColor = value;
|
|
Invalidate();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private Color buttonColor = Color.FromArgb(255, 255, 255, 255);
|
|
[DefaultValue(typeof(Color), "255, 255, 255")]
|
|
public Color ButtonColor
|
|
{
|
|
get { return buttonColor; }
|
|
set
|
|
{
|
|
if (buttonColor != value)
|
|
{
|
|
buttonColor = value;
|
|
Invalidate();
|
|
}
|
|
}
|
|
}
|
|
|
|
private Color arrowColor = Color.Black;
|
|
[DefaultValue(typeof(Color), "Black")]
|
|
public Color ArrowColor
|
|
{
|
|
get { return arrowColor; }
|
|
set
|
|
{
|
|
if (arrowColor != value)
|
|
{
|
|
arrowColor = value;
|
|
Invalidate();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
protected override void WndProc(ref Message m)
|
|
{
|
|
if (m.Msg == WM_PAINT && DropDownStyle != ComboBoxStyle.Simple)
|
|
{
|
|
var clientRect = ClientRectangle;
|
|
var dropDownButtonWidth = SystemInformation.HorizontalScrollBarArrowWidth;
|
|
var outerBorder = new Rectangle(clientRect.Location,
|
|
new Size(clientRect.Width - 1, clientRect.Height - 1));
|
|
var innerBorder = new Rectangle(outerBorder.X + 1, outerBorder.Y + 1,
|
|
outerBorder.Width - dropDownButtonWidth - 2, outerBorder.Height - 2);
|
|
var innerInnerBorder = new Rectangle(innerBorder.X + 1, innerBorder.Y + 1,
|
|
innerBorder.Width - 2, innerBorder.Height - 2);
|
|
var dropDownRect = new Rectangle(innerBorder.Right + 1, innerBorder.Y,
|
|
dropDownButtonWidth, innerBorder.Height + 1);
|
|
if (RightToLeft == RightToLeft.Yes)
|
|
{
|
|
innerBorder.X = clientRect.Width - innerBorder.Right;
|
|
innerInnerBorder.X = clientRect.Width - innerInnerBorder.Right;
|
|
dropDownRect.X = clientRect.Width - dropDownRect.Right;
|
|
dropDownRect.Width += 1;
|
|
}
|
|
var innerBorderColor = Enabled ? BackColor : SystemColors.Control;
|
|
var outerBorderColor = Enabled ? BorderColor : SystemColors.ControlDark;
|
|
var buttonColor = Enabled ? ButtonColor : SystemColors.Control;
|
|
var middle = new Point(dropDownRect.Left + dropDownRect.Width / 2,
|
|
dropDownRect.Top + dropDownRect.Height / 2);
|
|
var arrow = new Point[]
|
|
{
|
|
new Point(middle.X - 3, middle.Y - 2),
|
|
new Point(middle.X + 4, middle.Y - 2),
|
|
new Point(middle.X, middle.Y + 2)
|
|
};
|
|
var ps = new PAINTSTRUCT();
|
|
bool shoulEndPaint = false;
|
|
IntPtr dc;
|
|
if (m.WParam == IntPtr.Zero)
|
|
{
|
|
dc = BeginPaint(Handle, ref ps);
|
|
m.WParam = dc;
|
|
shoulEndPaint = true;
|
|
}
|
|
else
|
|
{
|
|
dc = m.WParam;
|
|
}
|
|
|
|
var rgn = CreateRectRgn(innerInnerBorder.Left, innerInnerBorder.Top,
|
|
innerInnerBorder.Right, innerInnerBorder.Bottom);
|
|
|
|
SelectClipRgn(dc, rgn);
|
|
DefWndProc(ref m);
|
|
DeleteObject(rgn);
|
|
rgn = CreateRectRgn(clientRect.Left, clientRect.Top,
|
|
clientRect.Right, clientRect.Bottom);
|
|
SelectClipRgn(dc, rgn);
|
|
using (var g = Graphics.FromHdc(dc))
|
|
{
|
|
using (var b = new SolidBrush(buttonColor))
|
|
{
|
|
g.FillRectangle(b, dropDownRect);
|
|
}
|
|
using (var b = new SolidBrush(arrowColor))
|
|
{
|
|
g.FillPolygon(b, arrow);
|
|
}
|
|
using (var p = new Pen(innerBorderColor))
|
|
{
|
|
g.DrawRectangle(p, innerBorder);
|
|
g.DrawRectangle(p, innerInnerBorder);
|
|
}
|
|
using (var p = new Pen(outerBorderColor))
|
|
{
|
|
g.DrawRectangle(p, outerBorder);
|
|
}
|
|
}
|
|
if (shoulEndPaint)
|
|
EndPaint(Handle, ref ps);
|
|
DeleteObject(rgn);
|
|
}
|
|
else
|
|
base.WndProc(ref m);
|
|
}
|
|
|
|
private const int WM_PAINT = 0xF;
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct RECT
|
|
{
|
|
public int L, T, R, B;
|
|
}
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct PAINTSTRUCT
|
|
{
|
|
public IntPtr hdc;
|
|
public bool fErase;
|
|
public int rcPaint_left;
|
|
public int rcPaint_top;
|
|
public int rcPaint_right;
|
|
public int rcPaint_bottom;
|
|
public bool fRestore;
|
|
public bool fIncUpdate;
|
|
public int reserved1;
|
|
public int reserved2;
|
|
public int reserved3;
|
|
public int reserved4;
|
|
public int reserved5;
|
|
public int reserved6;
|
|
public int reserved7;
|
|
public int reserved8;
|
|
}
|
|
[DllImport("user32.dll")]
|
|
private static extern IntPtr BeginPaint(IntPtr hWnd,
|
|
[In, Out] ref PAINTSTRUCT lpPaint);
|
|
|
|
[DllImport("user32.dll")]
|
|
private static extern bool EndPaint(IntPtr hWnd, ref PAINTSTRUCT lpPaint);
|
|
|
|
[DllImport("gdi32.dll")]
|
|
public static extern int SelectClipRgn(IntPtr hDC, IntPtr hRgn);
|
|
|
|
[DllImport("user32.dll")]
|
|
public static extern int GetUpdateRgn(IntPtr hwnd, IntPtr hrgn, bool fErase);
|
|
public enum RegionFlags
|
|
{
|
|
ERROR = 0,
|
|
NULLREGION = 1,
|
|
SIMPLEREGION = 2,
|
|
COMPLEXREGION = 3,
|
|
}
|
|
[DllImport("gdi32.dll")]
|
|
internal static extern bool DeleteObject(IntPtr hObject);
|
|
|
|
[DllImport("gdi32.dll")]
|
|
private static extern IntPtr CreateRectRgn(int x1, int y1, int x2, int y2);
|
|
}
|
|
|
|
public class RButton : Button
|
|
{
|
|
//Fields
|
|
private int borderSize = 5;
|
|
|
|
private int borderRadius = 5;
|
|
public int BorderRadius
|
|
{
|
|
get { return borderRadius; }
|
|
set
|
|
{
|
|
borderRadius = value;
|
|
}
|
|
}
|
|
|
|
private Color borderColor = Color.Transparent;
|
|
public Color BorderColor
|
|
{
|
|
get { return borderColor; }
|
|
set
|
|
{
|
|
borderColor = value;
|
|
}
|
|
}
|
|
|
|
|
|
private bool activated = false;
|
|
public bool Activated
|
|
{
|
|
get { return activated; }
|
|
set
|
|
{
|
|
if (activated != value)
|
|
this.Invalidate();
|
|
activated = value;
|
|
|
|
}
|
|
}
|
|
|
|
private bool secondary = false;
|
|
public bool Secondary
|
|
{
|
|
get { return secondary; }
|
|
set
|
|
{
|
|
secondary = value;
|
|
}
|
|
}
|
|
|
|
public RButton()
|
|
{
|
|
DoubleBuffered = true;
|
|
FlatStyle = FlatStyle.Flat;
|
|
FlatAppearance.BorderSize = 0;
|
|
}
|
|
|
|
private GraphicsPath GetFigurePath(Rectangle rect, int radius)
|
|
{
|
|
GraphicsPath path = new GraphicsPath();
|
|
float curveSize = radius * 2F;
|
|
|
|
path.StartFigure();
|
|
path.AddArc(rect.X, rect.Y, curveSize, curveSize, 180, 90);
|
|
path.AddArc(rect.Right - curveSize, rect.Y, curveSize, curveSize, 270, 90);
|
|
path.AddArc(rect.Right - curveSize, rect.Bottom - curveSize, curveSize, curveSize, 0, 90);
|
|
path.AddArc(rect.X, rect.Bottom - curveSize, curveSize, curveSize, 90, 90);
|
|
path.CloseFigure();
|
|
return path;
|
|
}
|
|
|
|
|
|
protected override void OnPaint(PaintEventArgs pevent)
|
|
{
|
|
|
|
base.OnPaint(pevent);
|
|
|
|
float ratio = pevent.Graphics.DpiX / 192.0f;
|
|
int border = (int)(ratio * borderSize);
|
|
|
|
Rectangle rectSurface = this.ClientRectangle;
|
|
Rectangle rectBorder = Rectangle.Inflate(rectSurface, -border, -border);
|
|
|
|
Color borderDrawColor = activated ? borderColor : Color.Transparent;
|
|
|
|
using (GraphicsPath pathSurface = GetFigurePath(rectSurface, borderRadius + border))
|
|
using (GraphicsPath pathBorder = GetFigurePath(rectBorder, borderRadius))
|
|
using (Pen penSurface = new Pen(this.Parent.BackColor, border))
|
|
using (Pen penBorder = new Pen(borderDrawColor, border))
|
|
{
|
|
penBorder.Alignment = PenAlignment.Outset;
|
|
pevent.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
|
this.Region = new Region(pathSurface);
|
|
pevent.Graphics.DrawPath(penSurface, pathSurface);
|
|
pevent.Graphics.DrawPath(penBorder, pathBorder);
|
|
}
|
|
|
|
if (!Enabled && ForeColor != SystemColors.ControlText)
|
|
{
|
|
var rect = pevent.ClipRectangle;
|
|
if (Image is not null)
|
|
{
|
|
rect.Y += Image.Height;
|
|
rect.Height -= Image.Height;
|
|
}
|
|
TextFormatFlags flags = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak;
|
|
TextRenderer.DrawText(pevent.Graphics, this.Text, this.Font, rect, Color.Gray, flags);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|
|
}
|