diff --git a/src/thirtytwo/Application.cs b/src/thirtytwo/Application.cs index 45592fd..b66eadd 100644 --- a/src/thirtytwo/Application.cs +++ b/src/thirtytwo/Application.cs @@ -231,5 +231,7 @@ public static string GetUserDefaultLocaleName() public static Direct2dFactory Direct2dFactory => s_direct2dFactory ??= new(); public static DirectWriteFactory DirectWriteFactory => s_directWriteFactory ??= new(); public static DirectWriteGdiInterop DirectWriteGdiInterop => s_directWriteGdiInterop ??= new(); + + /// public static ImagingFactory ImagingFactory => s_imagingFactory ??= new(); } \ No newline at end of file diff --git a/src/thirtytwo/Controls/ActiveXControl.cs b/src/thirtytwo/Controls/ActiveXControl.cs index 08e3fb0..3b274b0 100644 --- a/src/thirtytwo/Controls/ActiveXControl.cs +++ b/src/thirtytwo/Controls/ActiveXControl.cs @@ -40,7 +40,7 @@ public ActiveXControl( _classId = classId; IUnknown* unknown = ComHelpers.CreateComClass(classId); _instance = new(unknown, takeOwnership: true); - _instanceAsActiveObject = unknown->QueryAgileInterface(); + _instanceAsActiveObject = unknown->TryQueryAgileInterface(); using ComScope oleObject = ComScope.QueryFrom(unknown); if (oleObject.Pointer->GetMiscStatus(DVASPECT.DVASPECT_CONTENT, out OLEMISC status).Succeeded) diff --git a/src/thirtytwo/NativeMethods.txt b/src/thirtytwo/NativeMethods.txt index ee1ef57..0cb8d22 100644 --- a/src/thirtytwo/NativeMethods.txt +++ b/src/thirtytwo/NativeMethods.txt @@ -248,6 +248,8 @@ IsWindowEnabled IsWindowVisible IUIAutomationElement IUnknown +IWICBitmapDecoderInfo +IWICComponentInfo IWICImagingFactory2 KEY_INFORMATION_CLASS KEY_NAME_INFORMATION @@ -386,6 +388,7 @@ UpdateWindow USER_DEFAULT_SCREEN_DPI VARIANT_* VIRTUAL_KEY +WICComponentEnumerateOptions WIN32_ERROR WINDOWPOS WM_* diff --git a/src/thirtytwo/Win32/Graphics/Imaging/BitmapDecoder.cs b/src/thirtytwo/Win32/Graphics/Imaging/BitmapDecoder.cs index 081748f..1cff12b 100644 --- a/src/thirtytwo/Win32/Graphics/Imaging/BitmapDecoder.cs +++ b/src/thirtytwo/Win32/Graphics/Imaging/BitmapDecoder.cs @@ -3,6 +3,9 @@ namespace Windows.Win32.Graphics.Imaging; +/// +/// WIC Bitmap Decoder. +/// public unsafe class BitmapDecoder : DirectDrawBase { public BitmapDecoder(IWICBitmapDecoder* pointer) : base(pointer) { } diff --git a/src/thirtytwo/Win32/Graphics/Imaging/ComponentEnumerator.cs b/src/thirtytwo/Win32/Graphics/Imaging/ComponentEnumerator.cs new file mode 100644 index 0000000..78bab9e --- /dev/null +++ b/src/thirtytwo/Win32/Graphics/Imaging/ComponentEnumerator.cs @@ -0,0 +1,51 @@ +// Copyright (c) Jeremy W. Kuhne. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Windows.Win32.System.Com; + +namespace Windows.Win32.Graphics.Imaging; + +public unsafe class ComponentEnumerator : DirectDrawBase +{ + public ComponentEnumerator(IEnumUnknown* pointer) : base(pointer) { } + + public ComponentEnumerator(WICComponentType componentType) + : base(CreateComponentEnumerator(Application.ImagingFactory, componentType)) + { + } + + public static IEnumUnknown* CreateComponentEnumerator(ImagingFactory factory, WICComponentType componentType) + { + IEnumUnknown* enumerator; + factory.Pointer->CreateComponentEnumerator( + (uint)componentType, + (uint)WICComponentEnumerateOptions.WICComponentEnumerateDefault, + &enumerator).ThrowOnFailure(); + + GC.KeepAlive(factory); + return enumerator; + } + + public static implicit operator IEnumUnknown*(ComponentEnumerator d) => d.Pointer; + + public bool Next([NotNullWhen(true)] out ComponentInfo? componentInfo) + { + componentInfo = null; + IEnumUnknown* enumerator = this; + if (enumerator is null) + { + return false; + } + + uint fetched; + using ComScope unknown = new(null); + HRESULT result = enumerator->Next(1, unknown, &fetched); + if (result != HRESULT.S_OK || fetched != 1) + { + return false; + } + + componentInfo = new(unknown.Pointer->QueryInterface()); + return true; + } +} \ No newline at end of file diff --git a/src/thirtytwo/Win32/Graphics/Imaging/ComponentInfo.cs b/src/thirtytwo/Win32/Graphics/Imaging/ComponentInfo.cs new file mode 100644 index 0000000..b884169 --- /dev/null +++ b/src/thirtytwo/Win32/Graphics/Imaging/ComponentInfo.cs @@ -0,0 +1,36 @@ +// Copyright (c) Jeremy W. Kuhne. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Windows.Win32.Graphics.Imaging; + +public unsafe class ComponentInfo : DirectDrawBase +{ + public ComponentInfo(IWICComponentInfo* pointer) : base(pointer) { } + + public ComponentInfo(Guid componentClassId) + : base(CreateComponentInfo(Application.ImagingFactory, componentClassId)) + { + } + + public static IWICComponentInfo* CreateComponentInfo(ImagingFactory factory, Guid componentClassId) + { + IWICComponentInfo* info; + factory.Pointer->CreateComponentInfo(&componentClassId, &info).ThrowOnFailure(); + GC.KeepAlive(factory); + return info; + } + + public string FriendlyName + { + get + { + uint length; + Pointer->GetFriendlyName(0, null, &length).ThrowOnFailure(); + char* name = stackalloc char[(int)length]; + Pointer->GetFriendlyName(length, name, &length).ThrowOnFailure(); + return new string(name); + } + } + + public static implicit operator IWICComponentInfo*(ComponentInfo d) => d.Pointer; +} \ No newline at end of file diff --git a/src/thirtytwo/Win32/Graphics/Imaging/ImagingFactory.cs b/src/thirtytwo/Win32/Graphics/Imaging/ImagingFactory.cs index 41e5207..f6ad965 100644 --- a/src/thirtytwo/Win32/Graphics/Imaging/ImagingFactory.cs +++ b/src/thirtytwo/Win32/Graphics/Imaging/ImagingFactory.cs @@ -6,6 +6,9 @@ namespace Windows.Win32.Graphics.Imaging; +/// +/// WIC Imaging Factory. +/// public unsafe class ImagingFactory : DirectDrawBase { public ImagingFactory() : base(Create()) { } diff --git a/src/thirtytwo/Win32/System/Com/IUnknown.cs b/src/thirtytwo/Win32/System/Com/IUnknown.cs index af9e69f..3cbdeb4 100644 --- a/src/thirtytwo/Win32/System/Com/IUnknown.cs +++ b/src/thirtytwo/Win32/System/Com/IUnknown.cs @@ -9,17 +9,24 @@ namespace Windows.Win32.System.Com; public unsafe partial struct IUnknown : IVTable { - public TInterface* QueryInterface() where TInterface : unmanaged, IComIID + public TInterface* TryQueryInterface() where TInterface : unmanaged, IComIID { TInterface* @interface = default; QueryInterface(IID.Get(), (void**)&@interface); return @interface; } - public AgileComPointer? QueryAgileInterface() + public TInterface* QueryInterface() where TInterface : unmanaged, IComIID + { + TInterface* @interface = default; + QueryInterface(IID.Get(), (void**)&@interface).ThrowOnFailure(); + return @interface; + } + + public AgileComPointer? TryQueryAgileInterface() where TInterface : unmanaged, IComIID { - TInterface* @interface = QueryInterface(); + TInterface* @interface = TryQueryInterface(); return @interface is null ? null : new(@interface, takeOwnership: true); } diff --git a/src/thirtytwo/thirtytwo.csproj b/src/thirtytwo/thirtytwo.csproj index 139d1fa..7cecf0f 100644 --- a/src/thirtytwo/thirtytwo.csproj +++ b/src/thirtytwo/thirtytwo.csproj @@ -13,7 +13,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/thirtytwo_tests/Win32/Graphics/Imaging/ComponentInfoTests.cs b/src/thirtytwo_tests/Win32/Graphics/Imaging/ComponentInfoTests.cs new file mode 100644 index 0000000..a25af4a --- /dev/null +++ b/src/thirtytwo_tests/Win32/Graphics/Imaging/ComponentInfoTests.cs @@ -0,0 +1,18 @@ +// Copyright (c) Jeremy W. Kuhne. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Windows.Win32.Graphics.Imaging; + +public class ComponentInfoTests +{ + [Fact] + public void EnumerateDecoders() + { + ComponentEnumerator enumerator = new(WICComponentType.WICDecoder); + while (enumerator.Next(out ComponentInfo? info)) + { + Assert.NotNull(info); + Assert.NotNull(info.FriendlyName); + } + } +} diff --git a/src/thirtytwo_tests/Win32/System/Com/StandardDispatchTests.cs b/src/thirtytwo_tests/Win32/System/Com/StandardDispatchTests.cs index de15f4f..0507d93 100644 --- a/src/thirtytwo_tests/Win32/System/Com/StandardDispatchTests.cs +++ b/src/thirtytwo_tests/Win32/System/Com/StandardDispatchTests.cs @@ -38,7 +38,7 @@ public void StandardDispatch_ImplDoesNotProvideEx() &standard).ThrowOnFailure(); // StdDispatch does not provide an implementation of IDispatchEx. - IDispatchEx* dispatchEx = standard->QueryInterface(); + IDispatchEx* dispatchEx = standard->TryQueryInterface(); Assert.True(dispatchEx is null); standard->Release(); diff --git a/src/thirtytwo_tests/thirtytwo_tests.csproj b/src/thirtytwo_tests/thirtytwo_tests.csproj index db9034b..a93be0e 100644 --- a/src/thirtytwo_tests/thirtytwo_tests.csproj +++ b/src/thirtytwo_tests/thirtytwo_tests.csproj @@ -9,14 +9,14 @@ - - - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all