0

I have customized winform-design using region property as follows,

Region = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(0, 0, varPassedInConstructor * 9, Height, 10, 10));

And here calling winform through following code in a new thread

new Thread(new ThreadStart(() => {
            toast toast = new toast(message);
            toast.Show(nativeWindow);
            toast.Refresh();

            Thread.Sleep(3000);

            while (toast.Opacity > 0)
            {
                toast.Opacity -= 0.04;
                Thread.Sleep(100);
            }

            toast.Close();
            toast.Dispose();
        })).Start();

Everything goes well, form is displayed properly initially, but before closing all of sudden, changes applied via Region gets disappeared and form appears like the one that is at design time.

Image one, When initially form displayed, enter image description here

Image two, just before form is getting closed, enter image description here

I tried lots of diff thing, I am not getting what exactly problem is, so all help will be appreciated.

Aniket Bhansali
  • 630
  • 12
  • 33
  • Maybe you just forgot to re-apply the Region when the Form is resized. Overriding `OnLayout` should also work. – Jimi Mar 11 '19 at 11:33
  • 1
    It is the kind of mishap that occurs in a program that leaks operating system handles. The OS does not allow a program to create too many of them, it pulls the plug after 10,000. We don't have to look too far to see such a leak, CreateRoundRectRgn() returns a handle that needs to be released with a DeleteObject() call. No check either so this fails silently. Use Task Manager, Processes tab and add the GDI Objects column to see it leaking. Also get out of the habit of creating Form objects on a worker thread, that rarely comes to a good end. Use a Timer. – Hans Passant Mar 11 '19 at 13:32
  • @Jimi I tried solution suggested by you, but no luck, I handled the event of layout, but it has no impact. – Aniket Bhansali Mar 12 '19 at 04:39
  • @HansPassant Thanks for the info, I realized mistake I made so, I had rectified that, now I release that handle on form close event, but yet it doesn't solve my problem, and that form distorts even on the first run itself, so any other thing that I am doing wrongly. – Aniket Bhansali Mar 12 '19 at 04:40

1 Answers1

1

Finally, I got the fix, instead of using CreateRoundRectRgn from GDI32 used a GraphicsPath approach as follows,

private void SetRegion()
{
    var GP = RoundedRect(this.ClientRectangle, 5);
    this.Region = new Region(GP);
}

And here is code for RoundRect function (Credit goes to https://stackoverflow.com/a/33853557/3531672),

public static GraphicsPath RoundedRect(Rectangle bounds, int radius)
{
    int diameter = radius * 2;
    Size size = new Size(diameter, diameter);
    Rectangle arc = new Rectangle(bounds.Location, size);
    GraphicsPath path = new GraphicsPath();

    if (radius == 0)
    {
        path.AddRectangle(bounds);
        return path;
    }

    // top left arc  
    path.AddArc(arc, 180, 90);

    // top right arc  
    arc.X = bounds.Right - diameter;
    path.AddArc(arc, 270, 90);

    // bottom right arc  
    arc.Y = bounds.Bottom - diameter;
    path.AddArc(arc, 0, 90);

    // bottom left arc 
    arc.X = bounds.Left;
    path.AddArc(arc, 90, 90);

    path.CloseFigure();
    return path;
}

then in constructor simply had set size of form itself and called SetRegion defined above,

this.Width = toastMessage.Length * 9;
SetRegion();

Please note additionally, I would recommend to override OnSizeChanged and simply call SetRegion in it.

Aniket Bhansali
  • 630
  • 12
  • 33