* UITabControl:重绘了页面左右控制按钮
This commit is contained in:
parent
1ed77fed88
commit
cd8db8cdf7
BIN
Bin/SunnyUI.dll
BIN
Bin/SunnyUI.dll
Binary file not shown.
BIN
Bin/SunnyUI.pdb
BIN
Bin/SunnyUI.pdb
Binary file not shown.
Binary file not shown.
Binary file not shown.
2
SunnyUI.Demo/Controls/FTabControl.Designer.cs
generated
2
SunnyUI.Demo/Controls/FTabControl.Designer.cs
generated
@ -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;
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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()
|
||||
|
@ -1,5 +1,8 @@
|
||||
+ 增加; - 删除; * 修改
|
||||
|
||||
2020.06.07
|
||||
* UITabControl:重绘了页面左右控制按钮
|
||||
|
||||
2020.06.06
|
||||
+ UIPieChart:新增
|
||||
* UITextBox:修复设置为MultiLine时刷新问题
|
||||
|
Loading…
x
Reference in New Issue
Block a user