我尝试使用下面的代码
为我的自定义控件绘制边框 protected override void WndProc(ref Message msg)
{
switch (msg.Msg)
{
case NativeMethods.WM_NCPAINT:
case NativeMethods.WM_SIZE:
base.WndProc(ref msg);
this.WmNcPaint(ref msg);
break;
default:
base.WndProc(ref msg);
break;
}
}
/// <summary></summary>
/// <param name="msg"/>
private void WmNcPaint(ref Message msg)
{
this.DrawThemedBorderColor(this, ref msg);
}
private IntPtr cachedRgn = IntPtr.Zero;
public void DrawThemedBorderColor(Control control, ref Message msg)
{
this.cachedRgn = NCPaintHelper(control, ref msg);
}
public IntPtr NCPaintHelper(Control control, ref Message m)
{
IntPtr hdc = IntPtr.Zero;
Graphics g = null;
IntPtr hwnd = m.HWnd;
IntPtr remainingClipRegion = IntPtr.Zero;
try
{
Rectangle clipRect;
Rectangle desktopBounds = GetDesktopBounds(control);
Rectangle bounds = desktopBounds;
bounds.X = bounds.Y = 0;
hdc = NativeMethods.GetWindowDC(m.HWnd);
if (hdc != IntPtr.Zero)
{
if (m.WParam.ToInt64() == 1 || m.WParam == IntPtr.Zero)
{
// Since we will be painting the client rect.
clipRect = bounds;
}
else
{
Rectangle rect = desktopBounds;
Point pt = new Point(rect.Left, rect.Top);
NativeMethods.RECT r = new NativeMethods.RECT();
NativeMethods.GetRgnBox(m.WParam, ref r);
clipRect = new Rectangle(r.left, r.top, r.Width, r.Height);
clipRect.Intersect(rect);
clipRect.Offset(-pt.X, -pt.Y);
}
g = Graphics.FromHdc(hdc);
g.SetClip(clipRect, System.Drawing.Drawing2D.CombineMode.Replace);
g.Clip = new Region(clipRect);
PaintEventArgs pe = new PaintEventArgs(g, clipRect);
remainingClipRegion = NonClientPaint(pe, bounds, desktopBounds);
// When wParam is 1, the entire window frame needs to be updated.
if (m.WParam.ToInt64() == 1 || m.WParam == IntPtr.Zero)
{
// No existing clipping region, just replace it.
m.WParam = IntPtr.Add(IntPtr.Zero, 2);// remainingClipRegion;
}
}
}
finally
{
if (g != null)
{
g.Dispose();
}
if (hdc != IntPtr.Zero)
{
NativeMethods.ReleaseDC(hwnd, hdc);
}
}
return IntPtr.Zero;
}
IntPtr NonClientPaint( PaintEventArgs e, Rectangle displayRect, Rectangle windowRectInScreen )
{
Graphics g = e.Graphics;
Rectangle bounds = displayRect;
// Draw border with themed border color.
// Draw lines, don't fill a rectangle.
using( Pen pen = new Pen( Color.Red ) )
{
g.DrawLine(pen, bounds.Location, new Point(bounds.Right, bounds.Y));
g.DrawLine(pen, bounds.Location, new Point(bounds.X, bounds.Height));
g.DrawLine(pen, new Point(bounds.X, bounds.Height - 1), new Point(bounds.Right - 1, bounds.Height - 1));
g.DrawLine(pen, new Point(bounds.Right - 1, bounds.Y), new Point(bounds.Right - 1, bounds.Height - 1));
}
return NativeMethods.CreateRectRgn(0, 0, 0, 0); //windowRectInScreen.Left + 1, windowRectInScreen.Top + 1, windowRectInScreen.Right - 1, windowRectInScreen.Bottom - 1 );
}
protected override CreateParams CreateParams
{
get
{
var cp = base.CreateParams;
switch (this.borderStyle)
{
case BorderStyle.Fixed3D:
cp.ExStyle |= 0x200; // WS_EX_DLGFRAME
break;
case BorderStyle.FixedSingle:
cp.Style |= 0x800000; // WS_BORDER
break;
}
return cp;
}
}
此代码在除Windows-XP OS之外的所有操作系统中都能正常运行。在XP os中,边界已经部分绘制。请参阅下面附带的屏幕截图和示例链接,
示例链接: https://drive.google.com/open?id=0B6mYuvHmZAe-ay01ZTlvaGxSODA
请告诉我们,我为自定义控件绘制自定义边框时缺少什么。
谢谢,
答案 0 :(得分:0)
看起来你在绘制边框时遇到了很多麻烦。我不肯定这会对你的Win XP问题有所帮助,但它值得一试。当我想在自定义UserControls
的外边缘绘制边框时,我会这样做public partial class MyUserControl : UserControl
{
public MyUserControl()
{
InitializeComponent();
MyInitializeComponent();
}
private void MyInitializeComponent()
{
this.Paint += MyUserControl_Paint;
}
private void MyUserControl_Paint(object sender, PaintEventArgs e)
{
// Draw a border around the outside border of the control
var pen = new Pen(Color.Black, 2f);
e.Graphics.DrawRectangle(pen, this.ClientRectangle);
}
}