玻璃未正确渲染

9

我制作了一个表单,并像下面的图像一样扩展了其中的玻璃。但是当我移动窗口以使其屏幕上不全部可见时,移回后,玻璃渲染显示错误:

enter image description here

我该如何处理才能使窗口正确地呈现?

这是我的代码:

[DllImport( "dwmapi.dll" )]
private static extern void DwmExtendFrameIntoClientArea( IntPtr hWnd, ref Margins mg );

[DllImport( "dwmapi.dll" )]
private static extern void DwmIsCompositionEnabled( out bool enabled );

public struct Margins{
    public int Left;
    public int Right;
    public int Top;
    public int Bottom;
}

private void Form1_Shown( object sender, EventArgs e ) {
    this.CreateGraphics().FillRectangle( new SolidBrush( Color.Black ), new Rectangle( 0, this.ClientSize.Height - 32, this.ClientSize.Width, 32 ) );
    bool isGlassEnabled = false;
    Margins margin;
    margin.Top = 0;
    margin.Left = 0;
    margin.Bottom = 32;
    margin.Right = 0;
        DwmIsCompositionEnabled( out isGlassEnabled );

    if (isGlassEnabled) {

            DwmExtendFrameIntoClientArea( this.Handle, ref margin );
        }
}

如果它不可见,你怎么知道渲染了什么? - Gabe
1
不确定您的意思...您是在说如果将窗口移动到屏幕边缘并再次返回,则玻璃在窗口与屏幕边缘相交的部分消失了吗? - Matthew Layton
1
我以前多次尝试过使用Glass。在Google中搜索Daniel Moth和Glass...他似乎是Glass效果的大师!! - Matthew Layton
1
@activwerx,是的,这就是我想说的。 - Victor
需要看一些代码。另外,这是WinForms还是WPF? - BoltClock
2个回答

11

我认为CreateGraphics在这里引起了一些问题。

尝试重写OnPaint方法并使用来自PaintEventArgs的Graphic对象:

protected override void OnShown(EventArgs e) {
  base.OnShown(e);

  bool isGlassEnabled = false;
  Margins margin;
  margin.Top = 0;
  margin.Left = 0;
  margin.Bottom = 32;
  margin.Right = 0;
  DwmIsCompositionEnabled(out isGlassEnabled);

  if (isGlassEnabled) {
    DwmExtendFrameIntoClientArea(this.Handle, ref margin);
  }
}

protected override void OnPaint(PaintEventArgs e) {
  base.OnPaint(e);

  e.Graphics.FillRectangle(Pens.Black, 
       new Rectangle(0, this.ClientSize.Height - 32, this.ClientSize.Width, 32));
}

如果要调整窗体大小,可以将以下内容添加到构造函数中:

public Form1() {
  InitializeComponent();
  this.ResizeRedraw = true;
}

或者重写 Resize 事件:

protected override void OnResize(EventArgs e) {
  base.OnResize(e);
  this.Invalidate();
}

我也在做同样的事情,但我仍然有一些调整大小的问题。你试试看? - Alan

4
以下调用必须在您的OnPaint方法中进行。
FillRectangle( new SolidBrush( Color.Black ), new Rectangle( 0, this.ClientSize.Height - 32, this.ClientSize.Width, 32 ) );

其余部分只需完成一次。不要调用CreateGraphics(),而是使用OnPaint(e.Graphics)的参数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接