Я пытаюсь нарисовать стакан на форме, помеченной как контейнер mdi. Однако как только IsMdiContainer установлен, форма добавляет MdiClient в свой список элементов управления. В этот момент что-то происходит с родительской формой - почти как темно-серая панель пристыковывается ко всей форме, на которой размещается MdiClient.

Затем я делаю следующее, чтобы немного отодвинуть элемент управления MdiClient:

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

Это затем делает фактическую область MdiClient меньше, чтобы мы могли видеть, что за ней (бит, который содержит дочерние формы), и совершенно очевидно, что родительская форма не рисует или что-то в этом роде.

Как видно здесь: http://img525.imageshack.us/img525/8605/mdiglassproblem .png

Теперь мне нужно как-то убрать область за MdiClient (темно-серая часть, которая становится белой на стеклянной части).

Любые идеи?

PS - Glass визуализируется с помощью метода DwmExtendFrameIntoClientArea в Vista.

8
Dylan 28 Июл 2009 в 00:20
Просто примечание стороны; строка «if (c - MdiClient)» избыточна. Оператор as выполняет ту же проверку и возвращает значение null, если оно ложно. Итак, просто используйте оператор «as», а затем проверьте вместо него значение null.
 – 
Ed S.
28 Июл 2009 в 00:39
... или придерживайтесь принципа «есть» и используйте приведение в стиле C, но лично я предпочитаю другой подход.
 – 
Ed S.
28 Июл 2009 в 00:39
Хорошо, но теперь я запутался - зачем вам нужно, чтобы «серая часть» ушла? Это всегда позади ht MDIClient. Просто не перемещайте / не сжимайте клиента?
 – 
Henk Holterman
28 Июл 2009 в 01:02

3 ответа

Лучший ответ

Мне удалось заставить его работать. Та темно-серая область, о которой я говорил, которая закрашивается поверх всего, что происходило в методе формы OnPaint. Очевидно, что когда присутствует MdiContainer, форма предварительно запрограммирована для закрашивания темно-серой области, которая закрывала стекло.

Поэтому просто переопределите метод OnPaint, не вызывая его base, а затем возьмите код, который использовался для рисования стекла в обычном методе Paint, и вставьте его в метод OnPaint.

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

Затем просто убедитесь, что контейнер MdiContainer не мешает стеклу и должен идеально рисоваться.

5
Dylan 28 Июл 2009 в 01:56

Думаю, этого достаточно.

foreach (Control ctrl in this.Controls)  
{    
    if (ctrl is MdiClient)  
    {  
        ctrl.BackColor = Color.LightGray;  
    }
}
9
Wolverine 11 Авг 2018 в 20:27

Это должно сработать

Controls.OfType<MdiClient>().FirstOrDefault().BackColor = Color.FromArgb(14, 16, 62);
0
Alp Altunel 9 Мар 2020 в 21:38