How to remove gray background on MDI parent form?
Asked Answered
J

3

8

What I'm trying to do is draw some glass on a form marked as an mdi container. However as soon as the IsMdiContainer is set, the form adds an MdiClient to it's list of Controls. At this point something happens to the parent form - almost like a dark gray panel is being docked to the entire form onto which the MdiClient is being placed on.

I then do is the following to move the MdiClient control out of the way a bit:

    foreach(var c in Controls)
    {
        if(c is MdiClient)
        {
            var client = (MdiClient)c;
            client.BackColor = Color.Red;
            client.Dock = DockStyle.None;
            client.Size = new Size(this.Width-100, this.Height);
            break;
        }
    }

This then makes the actual MdiClient area smaller so we can see what is behind it (the bit which hosts the children forms) and it is blatantly obvious that the parent form is not painting or something.

As can be seen here: http://img525.imageshack.us/img525/8605/mdiglassproblem.png

I now need to somehow get the area behind the MdiClient (dark gray part which is rendered white on the glass section) to go away.

Any ideas?

PS - Glass is being rendered using DwmExtendFrameIntoClientArea method in Vista.

Jernigan answered 27/7, 2009 at 20:20 Comment(3)
Just a side note; the "if (c is MdiClient)" line is redundant. The 'as' operator performs the same check and returns null if it is false. So, just use the 'as' operator and then check for null instead.Swiftlet
... or stick with the 'is' and use a C style cast, but I personally prefer the other approach.Swiftlet
OK, but now I am confused - why do you need the 'grey part' to go away? It's always behind ht MDIClient. Just don't move/shrink the Client?Aggiornamento
J
5

I managed to get it working. That dark gray area I was talking about, which gets painted over everything was occuring in the OnPaint method of the form. Obviously when there is an MdiContainer present the form is preprogrammed to paint the dark gray area which was obstructing the glass.

So just override the OnPaint method without calling it's base and then take the code that was used to draw the glass in the normal Paint method and stick it in the OnPaint method.

protected override void OnPaint(PaintEventArgs e)
    {
        //base.OnPaint(e);
        bool glassEnabled = IsGlassEnabled();
        if (glassEnabled) // draw glass if enabled
        {
            Rectangle rc = picPlaceHolder.ClientRectangle;

            IntPtr destdc = e.Graphics.GetHdc(); // hwnd must be the handle of form, not control
            IntPtr Memdc = CreateCompatibleDC(destdc);
            IntPtr bitmapOld = IntPtr.Zero;

            BITMAPINFO dib = new BITMAPINFO();
            dib.bmiHeader.biHeight = -(rc.Bottom - rc.Top);
            dib.bmiHeader.biWidth = rc.Right - rc.Left;
            dib.bmiHeader.biPlanes = 1;
            dib.bmiHeader.biSize = Marshal.SizeOf(typeof(BITMAPINFOHEADER));
            dib.bmiHeader.biBitCount = 32;
            dib.bmiHeader.biCompression = BI_RGB;
            if (!(SaveDC(Memdc) == 0))
            {
                IntPtr bitmap = CreateDIBSection(Memdc, ref dib, DIB_RGB_COLORS, 0, IntPtr.Zero, 0);
                if (!(bitmap == IntPtr.Zero))
                {
                    bitmapOld = SelectObject(Memdc, bitmap);
                    BitBlt(destdc, rc.Left, rc.Top, rc.Right - rc.Left, rc.Bottom - rc.Top, Memdc, 0, 0, SRCCOPY);
                }

                // remember to clean up
                SelectObject(Memdc, bitmapOld);

                DeleteObject(bitmap);
                ReleaseDC(Memdc, -1);
                DeleteDC(Memdc);
            }
            e.Graphics.ReleaseHdc();
        }
    }

Then just ensure that the MdiContainer is not in the way of the glass and it should draw perfectly.

Jernigan answered 27/7, 2009 at 21:56 Comment(0)
L
9

I think this is perfect enough.

foreach (Control ctrl in this.Controls)  
{    
    if (ctrl is MdiClient)  
    {  
        ctrl.BackColor = Color.LightGray;  
    }
}
Leahleahey answered 21/11, 2013 at 12:35 Comment(0)
J
5

I managed to get it working. That dark gray area I was talking about, which gets painted over everything was occuring in the OnPaint method of the form. Obviously when there is an MdiContainer present the form is preprogrammed to paint the dark gray area which was obstructing the glass.

So just override the OnPaint method without calling it's base and then take the code that was used to draw the glass in the normal Paint method and stick it in the OnPaint method.

protected override void OnPaint(PaintEventArgs e)
    {
        //base.OnPaint(e);
        bool glassEnabled = IsGlassEnabled();
        if (glassEnabled) // draw glass if enabled
        {
            Rectangle rc = picPlaceHolder.ClientRectangle;

            IntPtr destdc = e.Graphics.GetHdc(); // hwnd must be the handle of form, not control
            IntPtr Memdc = CreateCompatibleDC(destdc);
            IntPtr bitmapOld = IntPtr.Zero;

            BITMAPINFO dib = new BITMAPINFO();
            dib.bmiHeader.biHeight = -(rc.Bottom - rc.Top);
            dib.bmiHeader.biWidth = rc.Right - rc.Left;
            dib.bmiHeader.biPlanes = 1;
            dib.bmiHeader.biSize = Marshal.SizeOf(typeof(BITMAPINFOHEADER));
            dib.bmiHeader.biBitCount = 32;
            dib.bmiHeader.biCompression = BI_RGB;
            if (!(SaveDC(Memdc) == 0))
            {
                IntPtr bitmap = CreateDIBSection(Memdc, ref dib, DIB_RGB_COLORS, 0, IntPtr.Zero, 0);
                if (!(bitmap == IntPtr.Zero))
                {
                    bitmapOld = SelectObject(Memdc, bitmap);
                    BitBlt(destdc, rc.Left, rc.Top, rc.Right - rc.Left, rc.Bottom - rc.Top, Memdc, 0, 0, SRCCOPY);
                }

                // remember to clean up
                SelectObject(Memdc, bitmapOld);

                DeleteObject(bitmap);
                ReleaseDC(Memdc, -1);
                DeleteDC(Memdc);
            }
            e.Graphics.ReleaseHdc();
        }
    }

Then just ensure that the MdiContainer is not in the way of the glass and it should draw perfectly.

Jernigan answered 27/7, 2009 at 21:56 Comment(0)
M
0

This should do the trick

Controls.OfType<MdiClient>().FirstOrDefault().BackColor = Color.FromArgb(14, 16, 62);
Meehan answered 9/3, 2020 at 18:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.