5

I want to disable Aero Peek in my WPF application (my application must be visible when user placed the mouse over the button "Show desktop"). I use this PInvoke signature:

[Flags]
public enum DwmWindowAttribute : uint
{
    DWMWA_NCRENDERING_ENABLED = 1,
    DWMWA_NCRENDERING_POLICY,
    DWMWA_TRANSITIONS_FORCEDISABLED,
    DWMWA_ALLOW_NCPAINT,
    DWMWA_CAPTION_BUTTON_BOUNDS,
    DWMWA_NONCLIENT_RTL_LAYOUT,
    DWMWA_FORCE_ICONIC_REPRESENTATION,
    DWMWA_FLIP3D_POLICY,
    DWMWA_EXTENDED_FRAME_BOUNDS,
    DWMWA_HAS_ICONIC_BITMAP,
    DWMWA_DISALLOW_PEEK,
    DWMWA_EXCLUDED_FROM_PEEK,
    DWMWA_LAST
}

[Flags]
public enum DWMNCRenderingPolicy : uint
{
    UseWindowStyle,
    Disabled,
    Enabled,
    Last
}

[DllImport("dwmapi.dll", PreserveSig=false)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DwmIsCompositionEnabled();

[DllImport("dwmapi.dll", PreserveSig=false)]
public static extern Int32 DwmSetWindowAttribute(IntPtr hwnd,
                                                 DwmWindowAttribute dwmAttribute,
                                                 IntPtr pvAttribute,
                                                 uint cbAttribute);

and this usage:

    var helper = new WindowInteropHelper(this);
    helper.EnsureHandle();

    if (API.DwmIsCompositionEnabled())
    {
        var status = Marshal.AllocCoTaskMem(sizeof(uint));
        Marshal.Copy(new[] {(int) API.DWMNCRenderingPolicy.Enabled}, 0, status, 1);
        API.DwmSetWindowAttribute(helper.Handle,
                                  API.DwmWindowAttribute.DWMWA_EXCLUDED_FROM_PEEK,
                                  status,
                                  sizeof (uint));
    }

In my 64-bit system (Windows 7 Professional), it's work only if I run 64-bit application. If I run 32-bit application in WOW64 mode, I receive exception:

"A call to PInvoke function 'XXX::DwmSetWindowAttribute' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature."

What do you think about this? What is the solution?

Aleksandr Vishnyakov
  • 1,872
  • 5
  • 23
  • 39
  • possible duplicate of [Unbalanced Stack!](http://stackoverflow.com/questions/4171790/unbalanced-stack) – ChrisWue May 28 '11 at 06:54
  • This is not a solution. When I use any of calling conventions I get exception or function doesn't work. – Aleksandr Vishnyakov May 28 '11 at 07:05
  • @Alexander can you add to your question what you have tried and how it failed? – ChrisWue May 28 '11 at 07:20
  • @ChrisWue I don't understand. I already described a problem in detail. – Aleksandr Vishnyakov May 28 '11 at 07:36
  • Your problem is that you receive an "unbalanced stack" exception. The reason for that is that you need to use Cdecl calling convention. Now you have said you already tried that and the function does not work then. Well, how does it not work? Do you still receive the "unbalanced stack" exeption after adding Cdecl to the dllimport? – ChrisWue May 28 '11 at 07:41
  • @ChrisWue Yes, I receive the "unbalanced stack" exception after adding Cdecl to the DllImport. – Aleksandr Vishnyakov May 28 '11 at 07:51

1 Answers1

6

I change the signature:

[DllImport("dwmapi.dll", PreserveSig = true)]
public static extern int DwmSetWindowAttribute(IntPtr hwnd,
                                               DwmWindowAttribute dwmAttribute,
                                               IntPtr pvAttribute,
                                               uint cbAttribute);

and usage:

if (API.DwmIsCompositionEnabled())
{
    var status = Marshal.AllocHGlobal(sizeof(int));
    Marshal.WriteInt32(status, 1); // true
    API.DwmSetWindowAttribute(helper.Handle,
                              API.DwmWindowAttribute.DWMWA_EXCLUDED_FROM_PEEK,
                              status,
                              sizeof(int));
}
GSerg
  • 76,472
  • 17
  • 159
  • 346
Aleksandr Vishnyakov
  • 1,872
  • 5
  • 23
  • 39