自定义窗口在c#中只需重写OnPaint方法就行了,不过有几处关键之处要设置
下面给出重会的方法,具体你只要修改下就行了
protected override void OnPaint(PaintEventArgs e)
...{
ResourceManager rm = new ResourceManager("SafeBox.Resources.Skin", Assembly.GetExecutingAssembly());
Image TopLeft = (Image)(rm.GetObject("TopLeft"));
Graphics g = e.Graphics;
//画标题栏左边
Brush brush = new TextureBrush(TopLeft, new Rectangle(0, 0, TopLeft.Width, TopLeft.Height));
g.FillRectangle(brush, 0, 0, TopLeft.Width, TopLeft.Height);
//画标题栏中间
Brush MidBrush = new SolidBrush(Color.FromArgb(0, 163, 227));
g.FillRectangle(MidBrush, 1, TopLeft.Height - 1, DrawForm.ClientSize.Width, 1);
//画左边框
Brush BoardBrush = new SolidBrush(Color.FromArgb(78, 205, 255));
g.FillRectangle(BoardBrush, 0, 0, 2, DrawForm.ClientSize.Height);
//画右边框
g.FillRectangle(BoardBrush, DrawForm.ClientSize.Width - 2, 0, 2, DrawForm.ClientSize.Height);
//画上边框
g.FillRectangle(BoardBrush, 0, 0, DrawForm.ClientSize.Width, 2);
//画下边框
g.FillRectangle(BoardBrush, 0, DrawForm.ClientSize.Height - 2, DrawForm.ClientSize.Width, 2);
base.OnPaint(e);
} 这样写好后窗口样式变了,不过你首先得把窗口的 FormBoardStyle 设为None,但光这样无法拖动窗口,
下面是拖动和改变窗口的方法:重写WndProc
switch (Msg.Msg)
{
case 0x0084: //WM_NCHITTEST改变窗口大小
{
// 分解当前鼠标的坐标
int nPosX = (Msg.LParam.ToInt32() & 65535);
int nPosY = (Msg.LParam.ToInt32() >> 16);
if (nPosX >= this.Left + this.Width - 6 && nPosY >= this.Top + this.Height - 6)
{
// 鼠标位置在窗体的右下角附近
Msg.Result = new IntPtr(HTBOTTOMRIGHT);
return;
}
else if (nPosX >= this.Left + this.Width - 2)
{
// 鼠标位置在窗体右侧
Msg.Result = new IntPtr(HTRIGHT);
return;
}
else if (nPosY >= this.Top + this.Height - 2)
{
// 鼠标位置在窗体下方
Msg.Result = new IntPtr(HTBOTTOM);
return;
}
else if (nPosX <= this.Left + 2)
{
// 鼠标位置在窗体左侧
Msg.Result = new IntPtr(HTLEFT);
return;
}
else if (nPosY <= this.Top + 2)
{
// 鼠标位置在窗体上侧
Msg.Result = new IntPtr(HTTOP);
return;
}
// 以上只判断鼠标位置是否在右侧,右下角,下方,所以仅仅当鼠标指针在这三个位置时才会改动成改动大小的形状,拖动后可改动大小。
break;
}
case 0x0201://移动窗口
{
m.Msg = 0x00A1;//更改消息为非客户区按下鼠标
m.LParam = IntPtr.Zero;//默认值
m.WParam = new IntPtr(2);//鼠标放在标题栏内
}
default:
break;
}
使用以上方法时别忘了加入自定义常数哦:
const int HTERROR = -2;
const int HTTRANSPARENT = -1;
const int HTNOWHERE = 0;
const int HTCLIENT = 1;
const int HTCAPTION = 2;
const int HTSYSMENU = 3;
const int HTGROWBOX = 4;
const int HTSIZE = HTGROWBOX;
const int HTMENU = 5;
const int HTHSCROLL = 6;
const int HTVSCROLL = 7;
const int HTMINBUTTON = 8;
const int HTMAXBUTTON = 9;
const int HTLEFT = 10;
const int HTRIGHT = 11;
const int HTTOP = 12;
const int HTTOPLEFT = 13;
const int HTTOPRIGHT = 14;
const int HTBOTTOM = 15;
const int HTBOTTOMLEFT = 16;
const int HTBOTTOMRIGHT = 17;
const int HTBORDER = 18;
const int HTREDUCE = HTMINBUTTON;
const int HTZOOM = HTMAXBUTTON;
const int HTSIZEFIRST = HTLEFT;
const int HTSIZELAST = HTBOTTOMRIGHT;
好了,OK了吧,能拖动,能改变大小,而且外观也自定义了,你移动看看,出问题了吧,窗口的残留画面去不了,不用急,在窗口的构造函数中加入:
this.SetStyle(ControlStyles.ResizeRedraw, true);行了吧,又出问题了,窗口会闪,再设置下窗口的属性:DoubleBuffered=true,ok了吧,,这个对控件双缓存处理,这样一个完美的自定义外观并可拖动和改变大小的窗口就搞定了,,当然这不是标准的解决方法,标准的应该重绘标题栏等吧,等有时间有贴啦
效果如下: