简体   繁体   中英

Drawing rectangle over a textbox

my Problem is, that i want to draw a rectangle over an existing Textbox.

I have a solution now, but the Textbox is always redrawing, which is a behavior i do not want.

here is the code

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);
}


the problem here is, the textbox is flickering, and the Rectangle is not set in front of the textbox after finish dragging.

How do i solve this ?

You are turning off the flag: WS_CLIPCHILDREN in WndProc .

WS_CLIPCHILDREN value is 0x02000000 and you are turning it off in your code:

cp.Style &= 0x7DFFFFFF; //WS_CLIPCHILDREN

WS_CLIPCHILDREN flag is set by default, it prevents flickering of child controls. If you will not turn off the flag, the flickering will stop.

According to the documentation on WS_CLIPCHILDREN : Excludes the area occupied by child windows when drawing occurs within the parent window. This style is used when creating the parent window.

Side Note : when turning off a flag, it is more clear to use the flag value you want to turn off:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM