在文本框上绘制矩形

时间:2019-06-03 12:50:06

标签: c# winforms

我的问题是,我想在现有的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);
}


这里的问题是,文本框闪烁,并且完成拖动后,矩形未设置在文本框的前面。

我该如何解决?

1 个答案:

答案 0 :(得分:0)

您正在关闭WS_CLIPCHILDREN中的WndProc标志。

WS_CLIPCHILDREN的值为0x02000000,您正在代码中将其关闭:

cp.Style &= 0x7DFFFFFF; //WS_CLIPCHILDREN

WS_CLIPCHILDREN标志是默认设置的,它防止子控件闪烁。如果您不关闭该标志,则闪烁将停止。

根据WS_CLIPCHILDREN上的文档:当在父窗口中进行绘制时,不包括子窗口占用的区域。创建父窗口时使用此样式。

旁注:关闭标志时,使用要关闭的标志值更加清晰:

cp.Style &= ~0x02000000; //WS_CLIPCHILDREN