locked
minimal C# not working for Windows API DwmGetWindowAttribute / DWMWA_CLOAKED RRS feed

  • Question

  • I'm trying to get working my minimal C# code for Windows API DwmGetWindowAttribute / DWMWA_CLOAKED. I'm running it in PowerShell but I suspect the issue is far more likely to be the C# code than the tiny bit of PowerShell code. The code runs but DwmGetWindowAttribute always returns hresult -2147024809, "One or more arguments are invalid." Using uint instead of int for all the DWORD types made it more complicated but it didn't help. Does anybody know why this doesn't work?

    API references:

    https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmgetwindowattribute

    https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute

    Add-Type API -Namespace Win32 -MemberDefinition @'
    [DllImport("dwmapi.dll")]
    private static extern int DwmGetWindowAttribute(
    	IntPtr hwnd,
    	int dwAttribute,
    	IntPtr pvAttribute,
    	int cbAttribute
    );
    public static int[] GetWndCloak(IntPtr hwnd)
    {
    	const int DWMWA_CLOAKED = 13;
    	// Get mem for return value (4 bytes)
    	IntPtr pcloak = Marshal.AllocHGlobal(4);
    	int hresult = DwmGetWindowAttribute(
    		hwnd,
    		DWMWA_CLOAKED,
    		pcloak,
    		4
    	);
    	int cloak = Marshal.ReadInt32(pcloak);
    	Marshal.FreeHGlobal(pcloak);
    	return new[] {hresult, cloak};
    }
    '@
    $proc = Get-Process -Id $pid
    $proc.MainWindowHandle.GetType()
    $hresult,$cloak = [Win32.API]::GetWndCloak($proc.MainWindowHandle)
    $hresult,$cloak
    



    Monday, September 14, 2020 5:25 PM

All replies

  • The value of DWMWA_CLOAKED is 14, not 13.

    From a Windows 10 SDK header file -

    // Window attributes
    enum DWMWINDOWATTRIBUTE
    {
        DWMWA_NCRENDERING_ENABLED = 1,      // [get] Is non-client rendering enabled/disabled
        DWMWA_NCRENDERING_POLICY,           // [set] Non-client rendering policy
        DWMWA_TRANSITIONS_FORCEDISABLED,    // [set] Potentially enable/forcibly disable transitions
        DWMWA_ALLOW_NCPAINT,                // [set] Allow contents rendered in the non-client area to be visible on the DWM-drawn frame.
        DWMWA_CAPTION_BUTTON_BOUNDS,        // [get] Bounds of the caption button area in window-relative space.
        DWMWA_NONCLIENT_RTL_LAYOUT,         // [set] Is non-client content RTL mirrored
        DWMWA_FORCE_ICONIC_REPRESENTATION,  // [set] Force this window to display iconic thumbnails.
        DWMWA_FLIP3D_POLICY,                // [set] Designates how Flip3D will treat the window.
        DWMWA_EXTENDED_FRAME_BOUNDS,        // [get] Gets the extended frame bounds rectangle in screen space
        DWMWA_HAS_ICONIC_BITMAP,            // [set] Indicates an available bitmap when there is no better thumbnail representation.
        DWMWA_DISALLOW_PEEK,                // [set] Don't invoke Peek on the window.
        DWMWA_EXCLUDED_FROM_PEEK,           // [set] LivePreview exclusion information
        DWMWA_CLOAK,                        // [set] Cloak or uncloak the window
        DWMWA_CLOAKED,                      // [get] Gets the cloaked state of the window
        DWMWA_FREEZE_REPRESENTATION,        // [set] Force this window to freeze the thumbnail without live update
        DWMWA_LAST
    };
    
    

    This worked for me in a Winforms app -

        public class NativeMethods
        {
            public enum DWMWINDOWATTRIBUTE
            {
                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_CLOAK,
                DWMWA_CLOAKED,
                DWMWA_FREEZE_REPRESENTATION,
                DWMWA_LAST
            };
    
            [DllImport("dwmapi.dll", ExactSpelling = true, PreserveSig = true)]
            public static extern uint DwmGetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE dwAttribute, ref int pvAttribute, int cbsize);
        };
    
    -----------------------
    int isCloaked = -1;
    var ret = NativeMethods.DwmGetWindowAttribute(Handle, NativeMethods.DWMWINDOWATTRIBUTE.DWMWA_CLOAKED, ref isCloaked, 4);
    

    • Proposed as answer by RLWA32 Tuesday, September 15, 2020 2:09 PM
    Monday, September 14, 2020 7:18 PM
  • Thanks!

    In here: https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute

    ...the enum does not have "=1" after the first value thus implying it is zero-based.

    Tuesday, September 15, 2020 2:07 PM
  • Thanks!

    In here: https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute

    ...the enum does not have "=1" after the first value thus implying it is zero-based.

    Yes, yet another documentation error.  That's why I posted the actual enum from the SDK header.

    Tuesday, September 15, 2020 2:09 PM