using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.ComponentModel;
namespace ControlExs.ControlExs.TextBoxEx
{
public class QCTextBox : TextBox
{
#region Field
private QQControlState _state = QQControlState.Normal;
private Font _defaultFont = new Font("微软雅黑", );
//当Text属性为空时编辑框内出现的提示文本
private string _emptyTextTip;
private Color _emptyTextTipColor = Color.DarkGray;
#endregion
#region Constructor
public QCTextBox()
{
SetStyles();
this.Font = _defaultFont;
//this.AutoSize = true;
this.BorderStyle = BorderStyle.None;
}
#endregion
#region Properites
[Description("当Text属性为空时编辑框内出现的提示文本")]
public String EmptyTextTip
{
get { return _emptyTextTip; }
set
{
if (_emptyTextTip != value)
{
_emptyTextTip = value;
base.Invalidate();
}
}
}
[Description("获取或设置EmptyTextTip的颜色")]
public Color EmptyTextTipColor
{
get { return _emptyTextTipColor; }
set
{
if (_emptyTextTipColor != value)
{
_emptyTextTipColor = value;
base.Invalidate();
}
}
}
private int _radius = ;
[Description("获取或设置圆角弧度")]
public int Radius
{
get { return _radius; }
set {
_radius = value;
this.Invalidate();
}
}
[Description("获取或设置是否可自定义改变大小")]
public bool CustomAutoSize
{
get { return this.AutoSize; }
set { this.AutoSize = value; }
}
#endregion
#region Override
protected override void OnMouseEnter(EventArgs e)
{
_state = QQControlState.Highlight;
base.OnMouseEnter(e);
}
protected override void OnMouseLeave(EventArgs e)
{
if (_state == QQControlState.Highlight && Focused)
{
_state = QQControlState.Focus;
}
else if (_state == QQControlState.Focus)
{
_state = QQControlState.Focus;
}
else
{
_state = QQControlState.Normal;
}
base.OnMouseLeave(e);
}
protected override void OnMouseDown(MouseEventArgs mevent)
{
if (mevent.Button == MouseButtons.Left)
{
_state = QQControlState.Highlight;
}
base.OnMouseDown(mevent);
}
protected override void OnMouseUp(MouseEventArgs mevent)
{
if (mevent.Button == MouseButtons.Left)
{
if (ClientRectangle.Contains(mevent.Location))
{
_state = QQControlState.Highlight;
}
else
{
_state = QQControlState.Focus;
}
}
base.OnMouseUp(mevent);
}
protected override void OnLostFocus(EventArgs e)
{
_state = QQControlState.Normal;
base.OnLostFocus(e);
}
protected override void OnEnabledChanged(EventArgs e)
{
if (Enabled)
{
_state = QQControlState.Normal;
}
else
{
_state = QQControlState.Disabled;
}
base.OnEnabledChanged(e);
}
protected override void WndProc(ref Message m)
{//TextBox是由系统进程绘制,重载OnPaint方法将不起作用
base.WndProc(ref m);
if (m.Msg == Win32.WM_PAINT || m.Msg == Win32.WM_CTLCOLOREDIT)
{
WmPaint(ref m);
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (_defaultFont != null)
{
_defaultFont.Dispose();
}
}
_defaultFont = null;
base.Dispose(disposing);
}
#endregion
#region Private
private void SetStyles()
{
// TextBox由系统绘制,不能设置 ControlStyles.UserPaint样式
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
UpdateStyles();
}
private void WmPaint(ref Message m)
{
Graphics g = Graphics.FromHwnd(base.Handle);
//g.SmoothingMode = SmoothingMode.AntiAlias;
//去掉 TextBox 四个角
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.AntiAlias;
SetWindowRegion(this.Width, this.Height);
if (!Enabled)
{
_state = QQControlState.Disabled;
}
switch (_state)
{
case QQControlState.Normal:
DrawNormalTextBox(g);
break;
case QQControlState.Highlight:
DrawHighLightTextBox(g);
break;
case QQControlState.Focus:
DrawFocusTextBox(g);
break;
case QQControlState.Disabled:
DrawDisabledTextBox(g);
break;
default:
break;
}
if (Text.Length == && !string.IsNullOrEmpty(EmptyTextTip) && !Focused)
{
TextRenderer.DrawText(g, EmptyTextTip, Font, ClientRectangle, EmptyTextTipColor, GetTextFormatFlags(TextAlign, RightToLeft == RightToLeft.Yes));
}
}
private void DrawNormalTextBox(Graphics g)
{
using (Pen borderPen = new Pen(Color.LightGray))
{
//g.DrawRectangle(borderPen, new Rectangle(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - 1, ClientRectangle.Height - 1));
g.DrawPath(borderPen, DrawHelper.DrawRoundRect(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - , ClientRectangle.Height - , _radius));
}
}
private void DrawHighLightTextBox(Graphics g)
{
using (Pen highLightPen = new Pen(ColorTable.QQHighLightColor))
{
//Rectangle drawRect = new Rectangle(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - 1, ClientRectangle.Height - 1);
//g.DrawRectangle(highLightPen, drawRect);
g.DrawPath(highLightPen, DrawHelper.DrawRoundRect(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - , ClientRectangle.Height - , _radius));
//InnerRect
//drawRect.Inflate(-1, -1);
//highLightPen.Color = ColorTable.QQHighLightInnerColor;
//g.DrawRectangle(highLightPen, drawRect);
g.DrawPath(new Pen(ColorTable.QQHighLightInnerColor), DrawHelper.DrawRoundRect(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - , ClientRectangle.Height - , _radius));
}
}
private void DrawFocusTextBox(Graphics g)
{
using (Pen focusedBorderPen = new Pen(ColorTable.QQHighLightInnerColor))
{
//g.DrawRectangle(focusedBorderPen,new Rectangle(ClientRectangle.X,ClientRectangle.Y,ClientRectangle.Width - 1, ClientRectangle.Height - 1));
g.DrawPath(focusedBorderPen, DrawHelper.DrawRoundRect(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - , ClientRectangle.Height - , _radius));
}
}
private void DrawDownTextBox(Graphics g)
{
using (Pen focusedBorderPen = new Pen(ColorTable.QQHighLightInnerColor))
{
//g.DrawRectangle(focusedBorderPen,new Rectangle(ClientRectangle.X,ClientRectangle.Y,ClientRectangle.Width - 1, ClientRectangle.Height - 1));
g.DrawPath(focusedBorderPen, DrawHelper.DrawRoundRect(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - , ClientRectangle.Height - , _radius));
}
}
private void DrawDisabledTextBox(Graphics g)
{
using (Pen disabledPen = new Pen(SystemColors.ControlDark))
{
//g.DrawRectangle(disabledPen,new Rectangle( ClientRectangle.X,ClientRectangle.Y, ClientRectangle.Width - 1,ClientRectangle.Height - 1));
g.DrawPath(disabledPen, DrawHelper.DrawRoundRect(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - , ClientRectangle.Height - , _radius));
}
}
private static TextFormatFlags GetTextFormatFlags(HorizontalAlignment alignment, bool rightToleft)
{
TextFormatFlags flags = TextFormatFlags.WordBreak |
TextFormatFlags.SingleLine;
if (rightToleft)
{
flags |= TextFormatFlags.RightToLeft | TextFormatFlags.Right;
}
switch (alignment)
{
case HorizontalAlignment.Center:
flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter;
break;
case HorizontalAlignment.Left:
flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Left;
break;
case HorizontalAlignment.Right:
flags |= TextFormatFlags.VerticalCenter | TextFormatFlags.Right;
break;
}
return flags;
}
#endregion
public void SetWindowRegion(int width, int height)
{
System.Drawing.Drawing2D.GraphicsPath FormPath = new System.Drawing.Drawing2D.GraphicsPath();
Rectangle rect = new Rectangle(, , width, height);
FormPath = GetRoundedRectPath(rect, _radius);
this.Region = new Region(FormPath);
}
private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
{
int diameter = radius;
Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
GraphicsPath path = new GraphicsPath();
// 左上角
path.AddArc(arcRect, , );
// 右上角
arcRect.X = rect.Right - diameter;
path.AddArc(arcRect, , );
// 右下角
arcRect.Y = rect.Bottom - diameter;
path.AddArc(arcRect, , );
// 左下角
arcRect.X = rect.Left;
path.AddArc(arcRect, , );
path.CloseFigure();
return path;
}
}
}
internal class DrawHelper
{
public static GraphicsPath DrawRoundRect(int x, int y, int width, int height, int radius)
{
GraphicsPath gp = new GraphicsPath();
gp.AddArc(x, y, radius, radius, , );
gp.AddArc(width - radius, y, radius, radius, , );
gp.AddArc(width - radius, height - radius, radius, radius, , );
gp.AddArc(x, height - radius, radius, radius, , );
gp.CloseAllFigures();
return gp;
}
/// <summary>
/// 绘制圆角矩形
/// </summary>
/// <param name="rect">矩形</param>
/// <param name="radius">弯曲程度(0-10),越大越弯曲</param>
/// <returns></returns>
public static GraphicsPath DrawRoundRect(Rectangle rect, int radius)
{
int x = rect.X;
int y = rect.Y;
int width = rect.Width;
int height = rect.Height;
return DrawRoundRect(x, y, width - , height - , radius);
}
/// <summary>
/// 得到两种颜色的过渡色(1代表开始色,100表示结束色)
/// </summary>
/// <param name="c">开始色</param>
/// <param name="c2">结束色</param>
/// <param name="value">需要获得的度</param>
/// <returns></returns>
public static Color GetIntermediateColor(Color c, Color c2, int value)
{
float pc = value * 1.0F / ;
int ca = c.A, cr = c.R, cg = c.G, cb = c.B;
int c2a = c2.A, c2r = c2.R, c2g = c2.G, c2b = c2.B;
int a = (int)Math.Abs(ca + (ca - c2a) * pc);
int r = (int)Math.Abs(cr - ((cr - c2r) * pc));
int g = (int)Math.Abs(cg - ((cg - c2g) * pc));
int b = (int)Math.Abs(cb - ((cb - c2b) * pc));
if (a > ) { a = ; }
if (r > ) { r = ; }
if (g > ) { g = ; }
if (b > ) { b = ; }
return (Color.FromArgb(a, r, g, b));
}
public static StringFormat StringFormatAlignment(ContentAlignment textalign)
{
StringFormat sf = new StringFormat();
switch (textalign)
{
case ContentAlignment.TopLeft:
case ContentAlignment.TopCenter:
case ContentAlignment.TopRight:
sf.LineAlignment = StringAlignment.Near;
break;
case ContentAlignment.MiddleLeft:
case ContentAlignment.MiddleCenter:
case ContentAlignment.MiddleRight:
sf.LineAlignment = StringAlignment.Center;
break;
case ContentAlignment.BottomLeft:
case ContentAlignment.BottomCenter:
case ContentAlignment.BottomRight:
sf.LineAlignment = StringAlignment.Far;
break;
}
return sf;
}
/// <summary>
/// 绘图对像
/// </summary>
/// <param name="g">绘图对像</param>
/// <param name="img">图片</param>
/// <param name="r">绘置的图片大小、坐标</param>
/// <param name="lr">绘置的图片边界</param>
/// <param name="index">当前状态</param>
/// <param name="Totalindex">状态总数</param>
public static void DrawRect(Graphics g, Bitmap img, Rectangle r, Rectangle lr, int index, int Totalindex)
{
if (img == null) return;
Rectangle r1, r2;
int x = (index - ) * img.Width / Totalindex;
int y = ;
int x1 = r.Left;
int y1 = r.Top;
if (r.Height > img.Height && r.Width <= img.Width / Totalindex)
{
r1 = new Rectangle(x, y, img.Width / Totalindex, lr.Top);
r2 = new Rectangle(x1, y1, r.Width, lr.Top);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
r1 = new Rectangle(x, y + lr.Top, img.Width / Totalindex, img.Height - lr.Top - lr.Bottom);
r2 = new Rectangle(x1, y1 + lr.Top, r.Width, r.Height - lr.Top - lr.Bottom);
if ((lr.Top + lr.Bottom) == ) r1.Height = r1.Height - ;
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
r1 = new Rectangle(x, y + img.Height - lr.Bottom, img.Width / Totalindex, lr.Bottom);
r2 = new Rectangle(x1, y1 + r.Height - lr.Bottom, r.Width, lr.Bottom);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
}
else
if (r.Height <= img.Height && r.Width > img.Width / Totalindex)
{
r1 = new Rectangle(x, y, lr.Left, img.Height);
r2 = new Rectangle(x1, y1, lr.Left, r.Height);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
r1 = new Rectangle(x + lr.Left, y, img.Width / Totalindex - lr.Left - lr.Right, img.Height);
r2 = new Rectangle(x1 + lr.Left, y1, r.Width - lr.Left - lr.Right, r.Height);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y, lr.Right, img.Height);
r2 = new Rectangle(x1 + r.Width - lr.Right, y1, lr.Right, r.Height);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
}
else
if (r.Height <= img.Height && r.Width <= img.Width / Totalindex) { r1 = new Rectangle((index - ) * img.Width / Totalindex, , img.Width / Totalindex, img.Height); g.DrawImage(img, new Rectangle(x1, y1, r.Width, r.Height), r1, GraphicsUnit.Pixel); }
else if (r.Height > img.Height && r.Width > img.Width / Totalindex)
{
//top-left
r1 = new Rectangle(x, y, lr.Left, lr.Top);
r2 = new Rectangle(x1, y1, lr.Left, lr.Top);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
//top-bottom
r1 = new Rectangle(x, y + img.Height - lr.Bottom, lr.Left, lr.Bottom);
r2 = new Rectangle(x1, y1 + r.Height - lr.Bottom, lr.Left, lr.Bottom);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
//left
r1 = new Rectangle(x, y + lr.Top, lr.Left, img.Height - lr.Top - lr.Bottom);
r2 = new Rectangle(x1, y1 + lr.Top, lr.Left, r.Height - lr.Top - lr.Bottom);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
//top
r1 = new Rectangle(x + lr.Left, y,
img.Width / Totalindex - lr.Left - lr.Right, lr.Top);
r2 = new Rectangle(x1 + lr.Left, y1,
r.Width - lr.Left - lr.Right, lr.Top);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
//right-top
r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y, lr.Right, lr.Top);
r2 = new Rectangle(x1 + r.Width - lr.Right, y1, lr.Right, lr.Top);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
//Right
r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y + lr.Top,
lr.Right, img.Height - lr.Top - lr.Bottom);
r2 = new Rectangle(x1 + r.Width - lr.Right, y1 + lr.Top,
lr.Right, r.Height - lr.Top - lr.Bottom);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
//right-bottom
r1 = new Rectangle(x + img.Width / Totalindex - lr.Right, y + img.Height - lr.Bottom,
lr.Right, lr.Bottom);
r2 = new Rectangle(x1 + r.Width - lr.Right, y1 + r.Height - lr.Bottom,
lr.Right, lr.Bottom);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
//bottom
r1 = new Rectangle(x + lr.Left, y + img.Height - lr.Bottom,
img.Width / Totalindex - lr.Left - lr.Right, lr.Bottom);
r2 = new Rectangle(x1 + lr.Left, y1 + r.Height - lr.Bottom,
r.Width - lr.Left - lr.Right, lr.Bottom);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
//Center
r1 = new Rectangle(x + lr.Left, y + lr.Top,
img.Width / Totalindex - lr.Left - lr.Right, img.Height - lr.Top - lr.Bottom);
r2 = new Rectangle(x1 + lr.Left, y1 + lr.Top,
r.Width - lr.Left - lr.Right, r.Height - lr.Top - lr.Bottom);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
}
}
/// <summary>
/// 绘图对像
/// </summary>
/// <param name="g"> 绘图对像</param>
/// <param name="obj">图片对像</param>
/// <param name="r">绘置的图片大小、坐标</param>
/// <param name="index">当前状态</param>
/// <param name="Totalindex">状态总数</param>
public static void DrawRect(Graphics g, Bitmap img, Rectangle r, int index, int Totalindex)
{
if (img == null) return;
int width = img.Width / Totalindex;
int height = img.Height;
Rectangle r1, r2;
int x = (index - ) * width;
int y = ;
r1 = new Rectangle(x, y, width, height);
r2 = new Rectangle(r.Left, r.Top, r.Width, r.Height);
g.DrawImage(img, r2, r1, GraphicsUnit.Pixel);
}
/// <summary>
/// 得到要绘置的图片对像
/// </summary>
/// <param name="str">图像在程序集中的地址</param>
/// <returns></returns>
public static Bitmap GetResBitmap(string str)
{
Stream sm;
sm = FindStream(str);
if (sm == null) return null;
return new Bitmap(sm);
}
/// <summary>
/// 得到图程序集中的图片对像
/// </summary>
/// <param name="str">图像在程序集中的地址</param>
/// <returns></returns>
private static Stream FindStream(string str)
{
Assembly assembly = Assembly.GetExecutingAssembly();
string[] resNames = assembly.GetManifestResourceNames();
foreach (string s in resNames)
{
if (s == str)
{
return assembly.GetManifestResourceStream(s);
}
}
return null;
}
}