Windows Aero 表单错误

4
好的,我已经按照文档的最小细节进行了操作,但是在尝试调试和运行(F5)时,它仍然给出以下错误提示:
PInvokeStackImbalance被检测到 消息:对PInvoke函数'VistaControls!VistaControls.Dwm.NativeMethods :: DwmExtendFrameIntoClientArea'的调用已经使堆栈不平衡。这很可能是因为托管的PInvoke签名与目标非托管签名不匹配。请检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。
我不知道这是什么意思,也不知道如何解决!有人可以帮忙吗?有什么建议吗?
我以前用过这个,但这次却不起作用。我正在使用VS2010 Express C# WinForms,.NET 4(就像我很久以前第一次使用它时一样)。
谢谢
链接:http://windowsformsaero.codeplex.com/wikipage?title=Glass%20on%20WinForms&referringTitle=Documentation 是的,我注意到页面底部一个人做出的更正,并且我已经修复了它,但它仍然无法工作!
代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using VistaControls.Dwm;

namespace One_Stop_Management
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

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

            e.Graphics.FillRectangles(Brushes.Black, new Rectangle[] {
        new Rectangle(0, 0, this.ClientSize.Width, 30),
        new Rectangle(this.ClientSize.Width - 30, 0, 30, this.ClientSize.Height),
        new Rectangle(0, this.ClientSize.Height - 30, this.ClientSize.Width, 30),
        new Rectangle(0, 0, 30, this.ClientSize.Height)
    });
        }

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

            VistaControls.Dwm.DwmManager.EnableGlassSheet(this);
        }
    }
}

1
它似乎在告诉你 DwmExtendFrameIntoClientArea 函数的 P/Invoke 定义有问题,但是你需要发布你目前拥有的定义,以便任何人能够告诉你如何修复它。我的猜测是当应该使用 IntPtr 时使用了 int - Cody Gray
@Cody Gray;问题现在已经解决,但我仍会在我的问题底部发布我的代码。谢谢。 - anon271334
2个回答

6
通过回退到.NET 3.5,您只是隐藏了问题:堆栈不平衡仍然存在,只是没有从负责检测正确的P / Invoke调用的托管调试助手中获得任何异常,原因我不知道。
“Windows Forms Aero”库中的DwmExtendFrameIntoClientArea签名是错误的。
这是原始的非托管签名:
HRESULT WINAPI DwmExtendFrameIntoClientArea(HWND hWnd, __in  const MARGINS *pMarInset);

这里是库中的签名:

[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMarInset);

虽然看起来与未经管理的代码匹配,但实际上并不相同。当 PreserveSig = false 时,告诉CLR解释返回的HRESULT值,如果对应错误则自动抛出异常 (请参见MSDN上的PreserveSig)。函数返回类型现在必须是 void,而不是 int,因为结果已经被运行时从堆栈中消耗掉了。
在库代码中更改为 PreserveSig = true,就可以消除堆栈不平衡的问题。

2
将 PreserveSig = false 设置在这里并不是一个坏主意,它会在函数失败时自动生成异常。但是,请将返回类型更改为“void”。否则,请确保自己抛出异常。 - Hans Passant
你说得没错,Hans。但是这个库已经在检查返回值并抛出自定义异常了,所以即使通常最好将 PreserveSig 设置为 false,但在这里设置为 true 应该就足够了。 - Julien Lebosquain

-1

没关系,我明白了。很遗憾这不能与.NET 4一起使用!

你需要进入项目属性,将它从.NET Framework 4更改为3.5或更低版本*。


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