* UITabControl:重绘了页面左右控制按钮

This commit is contained in:
Sunny 2020-06-07 10:53:56 +08:00
parent 1ed77fed88
commit cd8db8cdf7
8 changed files with 449 additions and 13 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -68,9 +68,11 @@
this.uiTabControl1.Font = new System.Drawing.Font("微软雅黑", 12F);
this.uiTabControl1.ItemSize = new System.Drawing.Size(150, 40);
this.uiTabControl1.Location = new System.Drawing.Point(30, 52);
this.uiTabControl1.MenuStyle = Sunny.UI.UIMenuStyle.Custom;
this.uiTabControl1.Name = "uiTabControl1";
this.uiTabControl1.SelectedIndex = 0;
this.uiTabControl1.ShowActiveCloseButton = true;
this.uiTabControl1.ShowCloseButton = true;
this.uiTabControl1.Size = new System.Drawing.Size(670, 183);
this.uiTabControl1.SizeMode = System.Windows.Forms.TabSizeMode.Fixed;
this.uiTabControl1.TabIndex = 0;

View File

@ -23,6 +23,8 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Sunny.UI
@ -159,13 +161,13 @@ namespace Sunny.UI
}
}
private Color tabUnSelectedForeColor = Color.Silver;
private Color tabUnSelectedForeColor = Color.FromArgb(240, 240, 240);
/// <summary>
/// 边框颜色
/// </summary>
[Description("未选中Tab页字体色"), Category("自定义")]
[DefaultValue(typeof(Color), "Silver")]
[DefaultValue(typeof(Color), "240, 240, 240")]
public Color TabUnSelectedForeColor
{
get => tabUnSelectedForeColor;
@ -278,16 +280,6 @@ namespace Sunny.UI
Alignment = TabAlignment.Top;
}
protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);
if (e.Control is TabPage)
{
//e.Control.BackColor = FillColor;
e.Control.Padding = new Padding(0);
}
}
private bool showCloseButton;
[DefaultValue(false)]
@ -304,6 +296,7 @@ namespace Sunny.UI
private bool showActiveCloseButton;
[DefaultValue(false)]
[Browsable(false)]
public bool ShowActiveCloseButton
{
get => showActiveCloseButton;
@ -405,9 +398,11 @@ namespace Sunny.UI
}
public delegate bool OnBeforeRemoveTabPage(object sender, int index);
public delegate void OnAfterRemoveTabPage(object sender, int index);
public event OnBeforeRemoveTabPage BeforeRemoveTabPage;
public event OnAfterRemoveTabPage AfterRemoveTabPage;
internal void RemoveTabPage(int index)
@ -478,5 +473,441 @@ namespace Sunny.UI
tabControl.Init();
}
}
internal IntPtr UpDownButtonHandle => FindUpDownButton();
private IntPtr FindUpDownButton()
{
return NativeMethods.FindWindowEx(Handle, IntPtr.Zero, UpDownButtonClassName, null);
}
public void OnPaintUpDownButton(UpDownButtonPaintEventArgs e)
{
Graphics g = e.Graphics;
Rectangle rect = e.ClipRectangle;
Color upButtonBaseColor = tabBackColor;
Color upButtonBorderColor = tabBackColor;
Color upButtonArrowColor = tabUnSelectedForeColor;
Color downButtonBaseColor = tabBackColor;
Color downButtonBorderColor = tabBackColor;
Color downButtonArrowColor = tabUnSelectedForeColor;
Rectangle upButtonRect = rect;
upButtonRect.X += 0;
upButtonRect.Y += 0;
upButtonRect.Width = rect.Width / 2 - 1;
upButtonRect.Height -= 1;
Rectangle downButtonRect = rect;
downButtonRect.X = upButtonRect.Right + 1;
downButtonRect.Y += 0;
downButtonRect.Width = rect.Width / 2 - 1;
downButtonRect.Height -= 1;
if (Enabled)
{
if (e.MouseOver)
{
if (e.MousePress)
{
if (e.MouseInUpButton)
{
upButtonBaseColor = GetColor(tabBackColor, 0, -35, -24, -9);
}
else
{
downButtonBaseColor = GetColor(tabBackColor, 0, -35, -24, -9);
}
}
else
{
if (e.MouseInUpButton)
{
upButtonBaseColor = GetColor(tabBackColor, 0, 35, 24, 9);
}
else
{
downButtonBaseColor = GetColor(tabBackColor, 0, 35, 24, 9);
}
}
}
}
else
{
upButtonBaseColor = SystemColors.Control;
upButtonBorderColor = SystemColors.ControlDark;
upButtonArrowColor = SystemColors.ControlDark;
downButtonBaseColor = SystemColors.Control;
downButtonBorderColor = SystemColors.ControlDark;
downButtonArrowColor = SystemColors.ControlDark;
}
g.SmoothingMode = SmoothingMode.AntiAlias;
Color color = Enabled ? BackColor : SystemColors.Control;
using (SolidBrush brush = new SolidBrush(color))
{
rect.Inflate(1, 1);
g.FillRectangle(brush, rect);
}
RenderButton(g, upButtonRect, upButtonBaseColor, upButtonBorderColor, upButtonArrowColor, ArrowDirection.Left);
RenderButton(g, downButtonRect, downButtonBaseColor, downButtonBorderColor, downButtonArrowColor, ArrowDirection.Right);
UpDownButtonPaintEventHandler handler = Events[EventPaintUpDownButton] as UpDownButtonPaintEventHandler;
handler?.Invoke(this, e);
}
internal void RenderButton(Graphics g, Rectangle rect, Color baseColor, Color borderColor, Color arrowColor, ArrowDirection direction)
{
RenderBackgroundInternal(g, rect, baseColor, borderColor, 0.45f, true, LinearGradientMode.Vertical);
switch (direction)
{
case ArrowDirection.Left:
g.DrawFontImage(61700, 24, arrowColor, rect);
break;
case ArrowDirection.Right:
g.DrawFontImage(61701, 24, arrowColor, rect,1);
break;
}
}
private Color GetColor(Color colorBase, int a, int r, int g, int b)
{
int a0 = colorBase.A;
int r0 = colorBase.R;
int g0 = colorBase.G;
int b0 = colorBase.B;
if (a + a0 > 255) { a = 255; } else { a = Math.Max(a + a0, 0); }
if (r + r0 > 255) { r = 255; } else { r = Math.Max(r + r0, 0); }
if (g + g0 > 255) { g = 255; } else { g = Math.Max(g + g0, 0); }
if (b + b0 > 255) { b = 255; } else { b = Math.Max(b + b0, 0); }
return Color.FromArgb(a, r, g, b);
}
internal void RenderBackgroundInternal(Graphics g, Rectangle rect, Color baseColor, Color borderColor, float basePosition, bool drawBorder, LinearGradientMode mode)
{
using (LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, mode))
{
Color[] colors = new Color[4];
colors[0] = GetColor(baseColor, 0, 35, 24, 9);
colors[1] = GetColor(baseColor, 0, 13, 8, 3);
colors[2] = baseColor;
colors[3] = GetColor(baseColor, 0, 68, 69, 54);
ColorBlend blend = new ColorBlend();
blend.Positions = new[] { 0.0f, basePosition, basePosition + 0.05f, 1.0f };
blend.Colors = colors;
brush.InterpolationColors = blend;
g.FillRectangle(brush, rect);
}
if (baseColor.A > 80)
{
Rectangle rectTop = rect;
if (mode == LinearGradientMode.Vertical)
{
rectTop.Height = (int)(rectTop.Height * basePosition);
}
else
{
rectTop.Width = (int)(rect.Width * basePosition);
}
using (SolidBrush brushAlpha = new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
{
g.FillRectangle(brushAlpha, rectTop);
}
}
if (drawBorder)
{
using (Pen pen = new Pen(borderColor))
{
g.DrawRectangle(pen, rect);
}
}
}
private static readonly object EventPaintUpDownButton = new object();
private const string UpDownButtonClassName = "msctls_updown32";
private UpDownButtonNativeWindow _upDownButtonNativeWindow;
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (UpDownButtonHandle != IntPtr.Zero)
{
if (_upDownButtonNativeWindow == null)
{
_upDownButtonNativeWindow = new UpDownButtonNativeWindow(this);
}
}
}
protected override void OnCreateControl()
{
base.OnCreateControl();
if (UpDownButtonHandle != IntPtr.Zero)
{
if (_upDownButtonNativeWindow == null)
{
_upDownButtonNativeWindow = new UpDownButtonNativeWindow(this);
}
}
}
protected override void OnHandleDestroyed(EventArgs e)
{
base.OnHandleDestroyed(e);
if (_upDownButtonNativeWindow != null)
{
_upDownButtonNativeWindow.Dispose();
_upDownButtonNativeWindow = null;
}
}
protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);
if (UpDownButtonHandle != IntPtr.Zero)
{
if (_upDownButtonNativeWindow == null)
{
_upDownButtonNativeWindow = new UpDownButtonNativeWindow(this);
}
}
if (e.Control is TabPage)
{
e.Control.Padding = new Padding(0);
}
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
if (UpDownButtonHandle != IntPtr.Zero)
{
if (_upDownButtonNativeWindow == null)
{
_upDownButtonNativeWindow = new UpDownButtonNativeWindow(this);
}
}
}
private class UpDownButtonNativeWindow : NativeWindow, IDisposable
{
private UITabControl _owner;
private bool _bPainting;
public UpDownButtonNativeWindow(UITabControl owner)
{
_owner = owner;
AssignHandle(owner.UpDownButtonHandle);
}
private bool LeftKeyPressed()
{
if (SystemInformation.MouseButtonsSwapped)
{
return (NativeMethods.GetKeyState(NativeMethods.VK_RBUTTON) < 0);
}
else
{
return (NativeMethods.GetKeyState(NativeMethods.VK_LBUTTON) < 0);
}
}
private void DrawUpDownButton()
{
bool mousePress = LeftKeyPressed();
NativeMethods.RECT rect = new NativeMethods.RECT();
NativeMethods.GetClientRect(Handle, ref rect);
Rectangle clipRect = Rectangle.FromLTRB(rect.Top, rect.Left, rect.Right, rect.Bottom);
Point cursorPoint = new Point();
NativeMethods.GetCursorPos(ref cursorPoint);
NativeMethods.GetWindowRect(Handle, ref rect);
var mouseOver = NativeMethods.PtInRect(ref rect, cursorPoint);
cursorPoint.X -= rect.Left;
cursorPoint.Y -= rect.Top;
var mouseInUpButton = cursorPoint.X < clipRect.Width / 2;
using (Graphics g = Graphics.FromHwnd(Handle))
{
UpDownButtonPaintEventArgs e = new UpDownButtonPaintEventArgs(g, clipRect, mouseOver, mousePress, mouseInUpButton);
_owner.OnPaintUpDownButton(e);
}
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case NativeMethods.WM_PAINT:
if (!_bPainting)
{
NativeMethods.PAINTSTRUCT ps = new NativeMethods.PAINTSTRUCT();
_bPainting = true;
NativeMethods.BeginPaint(m.HWnd, ref ps);
DrawUpDownButton();
NativeMethods.EndPaint(m.HWnd, ref ps);
_bPainting = false;
m.Result = NativeMethods.TRUE;
}
else
{
base.WndProc(ref m);
}
break;
default:
base.WndProc(ref m);
break;
}
}
#region IDisposable
public void Dispose()
{
_owner = null;
base.ReleaseHandle();
}
#endregion IDisposable
}
internal class NativeMethods
{
public const int WM_PAINT = 0xF;
public const int VK_LBUTTON = 0x1;
public const int VK_RBUTTON = 0x2;
private const int TCM_FIRST = 0x1300;
public const int TCM_GETITEMRECT = (TCM_FIRST + 10);
public static readonly IntPtr TRUE = new IntPtr(1);
[StructLayout(LayoutKind.Sequential)]
public struct PAINTSTRUCT
{
internal IntPtr hdc;
internal int fErase;
internal RECT rcPaint;
internal int fRestore;
internal int fIncUpdate;
internal int Reserved1;
internal int Reserved2;
internal int Reserved3;
internal int Reserved4;
internal int Reserved5;
internal int Reserved6;
internal int Reserved7;
internal int Reserved8;
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
internal RECT(int X, int Y, int Width, int Height)
{
this.Left = X;
this.Top = Y;
this.Right = Width;
this.Bottom = Height;
}
internal int Left;
internal int Top;
internal int Right;
internal int Bottom;
}
[DllImport("user32.dll")]
public static extern IntPtr FindWindowEx(
IntPtr hwndParent,
IntPtr hwndChildAfter,
string lpszClass,
string lpszWindow);
[DllImport("user32.dll")]
public static extern IntPtr BeginPaint(IntPtr hWnd, ref PAINTSTRUCT ps);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EndPaint(IntPtr hWnd, ref PAINTSTRUCT ps);
[DllImport("user32.dll")]
public static extern short GetKeyState(int nVirtKey);
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, ref RECT lParam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetCursorPos(ref Point lpPoint);
[DllImport("user32.dll")]
public extern static int OffsetRect(ref RECT lpRect, int x, int y);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool PtInRect([In] ref RECT lprc, Point pt);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetClientRect(IntPtr hWnd, ref RECT r);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern bool IsWindowVisible(IntPtr hwnd);
}
public delegate void UpDownButtonPaintEventHandler(object sender, UpDownButtonPaintEventArgs e);
public class UpDownButtonPaintEventArgs : PaintEventArgs
{
private bool _mouseOver;
private bool _mousePress;
private bool _mouseInUpButton;
public UpDownButtonPaintEventArgs(
Graphics graphics,
Rectangle clipRect,
bool mouseOver,
bool mousePress,
bool mouseInUpButton)
: base(graphics, clipRect)
{
_mouseOver = mouseOver;
_mousePress = mousePress;
_mouseInUpButton = mouseInUpButton;
}
public bool MouseOver
{
get { return _mouseOver; }
}
public bool MousePress
{
get { return _mousePress; }
}
public bool MouseInUpButton
{
get { return _mouseInUpButton; }
}
}
}
}

View File

@ -52,7 +52,7 @@ namespace Sunny.UI
public abstract UIMenuStyle Style { get; }
public virtual Color BackColor => Color.FromArgb(56, 56, 56);
public virtual Color SelectedColor => Color.FromArgb(36, 36, 36);
public virtual Color UnSelectedForeColor => Color.Silver;
public virtual Color UnSelectedForeColor => Color.FromArgb(240, 240, 240);
public virtual Color HoverColor => Color.FromArgb(76, 76, 76);
public override string ToString()

View File

@ -1,5 +1,8 @@
+ 增加; - 删除; * 修改
2020.06.07
* UITabControl重绘了页面左右控制按钮
2020.06.06
+ UIPieChart新增
* UITextBox修复设置为MultiLine时刷新问题