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