我的问题是,我想在现有的Textbox上绘制一个矩形。
我现在有一个解决方案,但是文本框始终在重绘,这是我不希望的行为。
这是代码
private bool isDragging = false;
void Form2_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
endPos = e.Location;
Rectangle rect;
if (endPos.Y > startPos.Y)
{
rect = new Rectangle(startPos.X, startPos.Y,
endPos.X - startPos.X, endPos.Y - startPos.Y);
}
else
{
rect = new Rectangle(endPos.X, endPos.Y,
startPos.X - endPos.X, startPos.Y - endPos.Y);
}
Region dragRegion = new Region(rect);
this.Invalidate();
}
}
void Form2_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
this.Invalidate();
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp;
cp = base.CreateParams;
cp.Style &= 0x7DFFFFFF; //WS_CLIPCHILDREN
return cp;
}
}
void Form2_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true;
startPos = e.Location;
}
// this is where we intercept the Paint event for the TextBox at the OS level
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case 15: // this is the WM_PAINT message
// invalidate the TextBox so that it gets refreshed properly
Input.Invalidate();
// call the default win32 Paint method for the TextBox first
base.WndProc(ref m);
// now use our code to draw extra stuff over the TextBox
break;
default:
base.WndProc(ref m);
break;
}
}
protected override void OnPaint(PaintEventArgs e)
{
if (isDragging)
{
using (Pen p = new Pen(Color.Gray))
{
p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
e.Graphics.DrawRectangle(p,
startPos.X, startPos.Y,
endPos.X - startPos.X, endPos.Y - startPos.Y);
}
}
base.OnPaint(e);
}
这里的问题是,文本框闪烁,并且完成拖动后,矩形未设置在文本框的前面。
我该如何解决?
答案 0 :(得分:0)
您正在关闭WS_CLIPCHILDREN
中的WndProc
标志。
WS_CLIPCHILDREN
的值为0x02000000
,您正在代码中将其关闭:
cp.Style &= 0x7DFFFFFF; //WS_CLIPCHILDREN
WS_CLIPCHILDREN
标志是默认设置的,它防止子控件闪烁。如果您不关闭该标志,则闪烁将停止。
根据WS_CLIPCHILDREN上的文档:当在父窗口中进行绘制时,不包括子窗口占用的区域。创建父窗口时使用此样式。
旁注:关闭标志时,使用要关闭的标志值更加清晰:
cp.Style &= ~0x02000000; //WS_CLIPCHILDREN