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
- Pass a real System.Windows.Control (or GameForm/GameWindow) wrapped in the WindowHandle so Handle is a valid HWND.
- Force handle creation before presenter creation (access control.Handle to trigger creation, after the control is on a shown form).
- Don't construct DeviceWindowHandle manually with IntPtr.Zero — use Game.Window's handle.
- 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
- Wrap real controls (GameForm/GameWindow) in the WindowHandle, never IntPtr.Zero
- Force handle creation by accessing control.Handle after the form is created/shown
- Use Game.Window's handle instead of hand-constructing WindowHandle
- Match the context type to the platform (SDL context for cross-platform paths)
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
- DeviceWindowHandle cannot be null
- Invalid window handle.
- AHardwareBuffer import requires…
- argumentsBuffer
- Bound render targets
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)