stride3d/stride · error · NotSupportedException

Form of type [ ] is not supported. Only…

Error message

Form of type [{Description.DeviceWindowHandle.GetType().Name}] is not supported. Only System.Windows.Control are supported

What it means

On Windows, CreateSurface presents through an HWND; if DeviceWindowHandle.Handle is IntPtr.Zero it throws NotSupportedException saying only System.Windows.Control-based handles are supported. A zero handle means the window control was never created (or a custom IWindowHandle implementation doesn't wrap a real Win32 control), so vkCreateWin32SurfaceKHR would fail.

Solutions

  1. Pass a real System.Windows.Control (or GameForm/GameWindow) wrapped in the WindowHandle so Handle is a valid HWND.
  2. Force handle creation before presenter creation (access control.Handle to trigger creation, after the control is on a shown form).
  3. Don't construct DeviceWindowHandle manually with IntPtr.Zero — use Game.Window's handle.
  4. On non-Windows platforms this path is irrelevant; verify Context type matches the platform (e.g. use the SDL context for cross-platform).

Example fix

// before
var handle = new WindowHandle(AppContextType.Window, IntPtr.Zero);
// after
var handle = new WindowHandle(AppContextType.Window, gameForm.Handle);
Defensive patterns

Strategy: validation

Validate before calling

if (Platform.Type == PlatformType.Windows && desc.DeviceWindowHandle.Handle == IntPtr.Zero)
    throw new InvalidOperationException("Window handle is not yet created; show/create the control first");

Type guard

bool HasValidWin32Handle(WindowHandle h) => h?.Handle is IntPtr hwnd && hwnd != IntPtr.Zero;

Try / catch

try { presenter = new SwapChainGraphicsPresenter(device, desc); }
catch (NotSupportedException ex) when (ex.Message.Contains("System.Windows.Control")) { log.Error("Invalid/empty Win32 window handle", ex); throw; }

Prevention

When it happens

Trigger: Creating a SwapChainGraphicsPresenter on Windows where Description.DeviceWindowHandle.Handle == IntPtr.Zero — e.g. a custom IWindowHandle implementation, a Form/control whose handle hasn't been created yet, or a headless context type reaching the Win32 path.

Common situations: Passing a WindowHandle constructed without a control; accessing the control's handle before the form is shown (Handle not forced); using a custom game window type not derived from the supported control wrapper; WPF interop done incorrectly.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/e3d6bd6ab2f2bad9. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs:578

#if STRIDE_UI_SDL
            // iOS reuses the SDL surface-creation path (GameContextiOS inherits GameContextSDL);
            // SDL's VulkanCreateSurface routes to VkMetalSurfaceCreateInfoEXT internally on iOS.
            if (Description.DeviceWindowHandle.Context == Games.AppContextType.DesktopSDL
                || Description.DeviceWindowHandle.Context == Games.AppContextType.iOS)
            {
                var control = Description.DeviceWindowHandle.NativeWindow as SDL.Window;
                Silk.NET.Core.Native.VkNonDispatchableHandle surfaceHandle = default;
                SDL.Window.SDL.VulkanCreateSurface((Silk.NET.SDL.Window*)control.SdlHandle, new Silk.NET.Core.Native.VkHandle(GraphicsDevice.NativeInstance.Handle), ref surfaceHandle);
                surface = new VkSurfaceKHR(surfaceHandle.Handle);
            }
            else
#endif
            if (Platform.Type == PlatformType.Windows)
            {
                var controlHandle = Description.DeviceWindowHandle.Handle;
                if (controlHandle == IntPtr.Zero)
                {
                    throw new NotSupportedException($"Form of type [{Description.DeviceWindowHandle.GetType().Name}] is not supported. Only System.Windows.Control are supported");
                }

                var surfaceCreateInfo = new VkWin32SurfaceCreateInfoKHR
                {
                    sType = VkStructureType.Win32SurfaceCreateInfoKHR,
                    hinstance = Process.GetCurrentProcess().Handle,
                    hwnd = controlHandle,
                };
                GraphicsDevice.CheckResult(GraphicsDevice.NativeInstanceApi.vkCreateWin32SurfaceKHR(GraphicsDevice.NativeInstance, &surfaceCreateInfo, null, out surface));
            }
            else if (Platform.Type == PlatformType.Android)
            {
                throw new NotImplementedException();
            }
            else if (Platform.Type == PlatformType.Linux)
            {
                throw new NotSupportedException("Only SDL is supported for the time being on Linux");
            }

View on GitHub (pinned to 96fad776d2)