diff --git a/PInvoke/Shell32/ImageTranscode.cs b/PInvoke/Shell32/ImageTranscode.cs
new file mode 100644
index 00000000..5fdedeb9
--- /dev/null
+++ b/PInvoke/Shell32/ImageTranscode.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.ComTypes;
+
+namespace Vanara.PInvoke;
+
+public static partial class Shell32
+{
+ /// Indicates the format of the resulting image.
+ [PInvokeData("imagetranscode.h", MSDNShortId = "NN:imagetranscode.ITranscodeImage")]
+ public enum TI_FLAGS
+ {
+ /// Convert the image to BMP format.
+ TI_BITMAP = 1,
+
+ /// Convert the image to JPEG format.
+ TI_JPEG = 2
+ }
+
+ /// Exposes a method that allows conversion to JPEG or bitmap (BMP) image formats from any image type supported by Windows.
+ // https://docs.microsoft.com/en-us/windows/win32/api/imagetranscode/nn-imagetranscode-itranscodeimage
+ [PInvokeData("imagetranscode.h", MSDNShortId = "NN:imagetranscode.ITranscodeImage")]
+ [ComImport, Guid("BAE86DDD-DC11-421c-B7AB-CC55D1D65C44"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), CoClass(typeof(ImageTranscode))]
+ public interface ITranscodeImage
+ {
+ /// Converts an image to JPEG or bitmap (BMP) image format.
+ ///
+ /// Type: IShellItem*
+ /// The Shell Item for the image to convert.
+ ///
+ ///
+ /// Type: UINT
+ /// The requested height in pixels. Should be less than or equal to the actual height of the original image. See Remarks.
+ ///
+ ///
+ /// Type: UINT
+ /// The requested width in pixels. Should be less than or equal to the actual width of the original image. See Remarks.
+ ///
+ ///
+ /// Type: TI_FLAGS
+ /// One of the following flags.
+ /// TI_BITMAP
+ /// Convert the image to BMP format.
+ /// TI_JPEG
+ /// Convert the image to JPEG format.
+ ///
+ ///
+ /// Type: IStream*
+ /// A stream to receive the converted image. The stream must be created by the calling code prior to calling TranscodeImage.
+ ///
+ ///
+ /// Type: UINT*
+ /// The actual width of the converted image.
+ ///
+ ///
+ /// Type: UINT*
+ /// The actual height of the converted image.
+ ///
+ ///
+ ///
+ /// The aspect ratio of the original image is preserved. The new image is resized so that it will fit into a box of width
+ /// uiMaxWidth and height uiMaxHeight.
+ ///
+ /// The image size will not be changed if the original image already fits in this bounding box.
+ /// If both uiMaxWidth and uiMaxHeight are zero, the returned image will be the same size as the original.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/imagetranscode/nf-imagetranscode-itranscodeimage-transcodeimage HRESULT
+ // TranscodeImage( [in] IShellItem *pShellItem, UINT uiMaxWidth, UINT uiMaxHeight, DWORD flags, IStream *pvImage, [out, optional]
+ // UINT *puiWidth, [out, optional] UINT *puiHeight );
+ void TranscodeImage([In] IShellItem pShellItem, uint uiMaxWidth, uint uiMaxHeight, TI_FLAGS flags, [In, Out] IStream pvImage, out uint puiWidth, out uint puiHeight);
+ }
+
+ /// CLSID_ImageTranscode
+ [ComImport, Guid("17B75166-928F-417d-9685-64AA135565C1"), ClassInterface(ClassInterfaceType.None)]
+ public class ImageTranscode { }
+}
\ No newline at end of file
diff --git a/PInvoke/Shell32/InputPanelConfiguration.cs b/PInvoke/Shell32/InputPanelConfiguration.cs
new file mode 100644
index 00000000..f0ed753c
--- /dev/null
+++ b/PInvoke/Shell32/InputPanelConfiguration.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Vanara.PInvoke;
+
+public static partial class Shell32
+{
+ /// Provides functionality for desktop apps to opt in to the focus tracking mechanism used in Windows Store apps.
+ ///
+ /// Warning
+ ///
+ /// IInputPanelConfiguration will not work in Windows 10.
+ ///
+ ///
+ /// Implement the IInputPanelConfiguration interface if your Desktop client processes need to leverage the invoking and dismissing
+ /// semantics of the touch keyboard and handwriting input panel.
+ ///
+ ///
+ /// The IInputPanelConfiguration interface enables your app to opt in to the focus tracking mechanism for Windows Store apps.
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/inputpanelconfiguration/nn-inputpanelconfiguration-iinputpanelconfiguration
+ [PInvokeData("inputpanelconfiguration.h", MSDNShortId = "NN:inputpanelconfiguration.IInputPanelConfiguration")]
+ [ComImport, Guid("41C81592-514C-48BD-A22E-E6AF638521A6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), CoClass(typeof(InputPanelConfiguration))]
+ public interface IInputPanelConfiguration
+ {
+ ///
+ /// Enables a client process to opt-in to the focus tracking mechanism for Windows Store apps that controls the invoking and
+ /// dismissing semantics of the touch keyboard.
+ ///
+ /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
+ ///
+ /// Note
+ ///
+ /// This method will not work in Windows 10. A user can manually configure settings through the notification center or through the
+ /// Typing settings to enable pulling up a touch keyboard automatically when focusing on an edit control.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/inputpanelconfiguration/nf-inputpanelconfiguration-iinputpanelconfiguration-enablefocustracking
+ // HRESULT EnableFocusTracking();
+ [PreserveSig]
+ HRESULT EnableFocusTracking();
+ }
+
+ /// Enables Windows Store apps to opt out of the automatic invocation behavior.
+ ///
+ /// Clients can request that the touch keyboard and handwriting input panel check to see that a user tapped in the edit control with
+ /// focus before invoking.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/inputpanelconfiguration/nn-inputpanelconfiguration-iinputpanelinvocationconfiguration
+ [PInvokeData("inputpanelconfiguration.h", MSDNShortId = "NN:inputpanelconfiguration.IInputPanelInvocationConfiguration")]
+ [ComImport, Guid("A213F136-3B45-4362-A332-EFB6547CD432"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ public interface IInputPanelInvocationConfiguration
+ {
+ /// Requires an explicit user tap in an edit field before the touch keyboard invokes.
+ /// The RequireTouchInEditControl method always returns S_OK.
+ ///
+ ///
+ /// When the RequireTouchInEditControl method is called, all future focus changes require an explicit user tap in an edit
+ /// field before the touch keyboard invokes. You can call the RequireTouchInEditControl method multiple times, but there's no
+ /// way to undo the setting.
+ ///
+ ///
+ /// This setting applies for any focus event that takes place to a window that is running in the process that called it. The
+ /// RequireTouchInEditControl method doesn't affect owned windows in another process that have an ownership chain to the
+ /// current process that called RequireTouchInEditControl.
+ ///
+ ///
+ /// The RequireTouchInEditControl method always returns S_OK. If this API is used, then the IsUIBusy property
+ /// has no effect. The two interaction models are essentially mutually exclusive.
+ ///
+ /// The following code shows how to call the RequireTouchInEditControl method.
+ ///
+ /// #include <inputpanelconfiguration.h>
+ /// #include <inputpanelconfiguration_i.c>
+ ///
+ /// IInputPanelInvocationConfiguration *pInputPanelInvocationConfiguration;
+ /// CoCreateInstance(CLSID_InputPanelConfiguration, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pInputPanelInvocationConfiguration));
+ /// pInputPanelInvocationConfiguration->RequireTouchInEditControl();
+ ///
+ ///
+ /// Note Calling Release before the app finishes drawing UI can cause undefined behavior. If the touch keyboard isn't already
+ /// running, calling Release could cause tiptsf.dll to be unloaded, because there are no more references to the dll. If this
+ /// occurs, the state set by the RequireTouchInEditControl method is lost.
+ ///
+ ///
+ /// If you need to delay the invocation of the touch keyboard until a later time, like when animations or direct manipulation have
+ /// completed, use the IsUIBusy custom UI automation property. For more info, see Registering Custom Properties, Events, and
+ /// Control Patterns.
+ ///
+ ///
+ /// When you set IsUIBusy to True, the touch keyboard doesn't change visual state based on focus changes within the
+ /// app. It's still able to change visual state based on overriding user action, like using a physical keyboard or manual dismissal.
+ ///
+ ///
+ /// When you set IsUIBusy to False, the touch keyboard resumes its default behavior and queries synchronously for the
+ /// control that has focus.
+ ///
+ /// The following code shows how to register the IsUIBusy custom UI automation property.
+ ///
+ /// /* 03391bea-6681-474b-955c-60f664397ac6 */
+ /// DEFINE_GUID( GUID_UIBusy, 0x03391bea, 0x6681, 0x474b, 0x95, 0x5c, 0x60, 0xf6, 0x64, 0x39, 0x7a, 0xc6);
+ /// UIAutomationPropertyInfo customPropertyInfo = { GUID_UIBusy, L"IsUIBusy", UIAutomationType_Bool };
+ /// CComPtr<IUIAutomationRegistrar> spRegistrar;
+ /// hr = spRegistrar.CoCreateInstance( CLSID_CUIAutomationRegistrar, nullptr, CLSCTX_INPROC_SERVER);
+ /// if (SUCCEEDED(hr)) {
+ /// PATTERNID customPropertyId;
+ /// hr = spRegistrar->RegisterProperty(&customPropertyInfo, &customPropertyId);
+ /// }
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/inputpanelconfiguration/nf-inputpanelconfiguration-iinputpanelinvocationconfiguration-requiretouchineditcontrol
+ // HRESULT RequireTouchInEditControl();
+ [PreserveSig]
+ HRESULT RequireTouchInEditControl();
+ }
+
+ /// CLSID_InputPanelConfiguration
+ [ComImport, Guid("2853ADD3-F096-4C63-A78F-7FA3EA837FB7"), ClassInterface(ClassInterfaceType.None)]
+ public class InputPanelConfiguration { }
+}
\ No newline at end of file