Ошибки форм Windows Aero

Итак, я следил за документацией вплоть до мельчайших деталей, и она продолжает выдавать мне следующую ошибку, когда я пытаюсь отлаживать и запускать (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);
        }
    }
}

person Community    schedule 19.02.2011    source источник
comment
Похоже, он говорит вам, что что-то не так с определением P/Invoke для функции DwmExtendFrameIntoClientArea, но вам нужно опубликовать определение, которое у вас есть в настоящее время, чтобы кто-нибудь сказал, что вы должны его исправить. Мое обоснованное предположение состоит в том, что вместо IntPtr используется int.   -  person Cody Gray    schedule 19.02.2011
comment
@Коди Грей; Теперь проблема решена, но я все равно опубликую свой код внизу своего вопроса. Спасибо.   -  person    schedule 19.02.2011


Ответы (2)


Вернувшись к .NET 3.5, вы просто скрыли проблему: дисбаланс стека все еще присутствует, вы просто не получаете никаких исключений от помощника управляемой отладки, который отвечает за обнаружение правильных вызовов P/Invoke, по неизвестной мне причине.

Неверная подпись DwmExtendFrameIntoClientArea в библиотеке Windows Forms Aero.

Вот исходная неуправляемая подпись:

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 и автоматически создавать исключение, если оно соответствует ошибке (см. PreserveSig в MSDN). Тип возвращаемого значения функции должен быть void, а не int, так как результат уже получен из стека средой выполнения.

Измените код библиотеки на PreserveSig = true, и дисбаланс стека исчезнет.

person Julien Lebosquain    schedule 19.02.2011
comment
PreserveSig = false здесь неплохая идея, она автоматически генерирует исключение при сбое функции. Но сделайте изменение возвращаемого типа на void. В противном случае обязательно создайте исключение самостоятельно. - person Hans Passant; 19.02.2011
comment
Вы абсолютно правы, Ганс, но библиотека уже проверяет возвращаемое значение и выдает пользовательское исключение, поэтому PreserveSig = true здесь должно быть достаточно, даже если обычно лучше установить для него значение false. - person Julien Lebosquain; 21.02.2011

Не берите в голову. Я понял. Очень жаль, что это не работает с .NET 4!

Вам нужно перейти в свойства проекта и изменить его с .NET Framework 4 на 3.5 или ниже*.

person Community    schedule 19.02.2011