8

私がやろうとしているのは、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 - Vista で DwmExtendFrameIntoClientArea メソッドを使用して Glass をレンダリングしています。

4

3 に答える 3

5

私はなんとかそれを機能させることができました。私が話していたその濃い灰色の領域は、フォームのOnPaintメソッドで発生していました。明らかに、MdiContainerが存在する場合、フォームは、ガラスを遮っていた濃い灰色の領域をペイントするように事前にプログラムされています。

したがって、ベースを呼び出さずにOnPaintメソッドをオーバーライドしてから、通常の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がガラスの邪魔にならず、完全に描画されることを確認します。

于 2009-07-27T21:56:42.857 に答える
0

これでうまくいくはずです

Controls.OfType<MdiClient>().FirstOrDefault().BackColor = Color.FromArgb(14, 16, 62);
于 2020-03-09T18:38:04.997 に答える