dotnet / pinvoke

A library containing all P/Invoke code so you don't have to import it every time. Maintained and updated to support the latest Windows OS.
MIT License
2.12k stars 222 forks source link

Can't get DwmGetWindowAttribute to work #527

Closed Slion closed 4 years ago

Slion commented 4 years ago

I tried a bunch of stuff including the following all I get is null reference exception thrown by DwmGetWindowAttribute.

        PInvoke.RECT rect = new PInvoke.RECT();
        int size = Marshal.SizeOf(typeof(PInvoke.RECT));
        IntPtr rectPtr = Marshal.AllocHGlobal(size);
        PInvoke.DwmApi.DwmGetWindowAttribute(hwnd, DwmApi.DWMWINDOWATTRIBUTE.DWMWA_EXTENDED_FRAME_BOUNDS,out rectPtr,size);
        Marshal.PtrToStructure(rectPtr, rect);
        Marshal.FreeHGlobal(rectPtr);

It's a lot faster to get it working using that solution: https://stackoverflow.com/a/58675103/3969362

AArnott commented 4 years ago

It looks like we incorrectly use out and a pointer type, which turns into a double-pointer.

AArnott commented 4 years ago

Thanks for reporting, @Slion

Slion commented 4 years ago

Congrats on the quick turn around. @AArnott Any chance of having an overload taking RECT as parameter much like on that stackoverflow post linked above?

AArnott commented 4 years ago

No. Our convention is to use the same types used in the native signature. But it shouldn't be hard for you to use RECT. Much easier than your original code nsippet.

Something like this:

unsafe void Foo()
{
        PInvoke.RECT rect = new PInvoke.RECT();
        PInvoke.DwmApi.DwmGetWindowAttribute(hwnd, DwmApi.DWMWINDOWATTRIBUTE.DWMWA_EXTENDED_FRAME_BOUNDS, &rect, sizeof(rect));
}

Don't worry about the 'unsafe' code. It doesn't mean your caller has to be unsafe. And honestly, this way you're not responsible for allocating, freeing, and copying native memory that could leak. C# pointer code is much easier than all this IntPtr nonsense that was invented to support poor VB.

Slion commented 4 years ago

@AArnott Thanks for that insight. When will that fix make it into a release?

AArnott commented 4 years ago

It looks like it's been quite a while, with quite a bit of work, since our last release. I'll go ahead and release to nuget.org today.