{"record":{"id":"e3d6bd6ab2f2bad9","repo":"stride3d/stride","slug":"form-of-type-description-devicewindowhandle-gettype-name-is","errorCode":null,"errorMessage":"Form of type [{Description.DeviceWindowHandle.GetType().Name}] is not supported. Only System.Windows.Control are supported","messagePattern":"Form of type \\[(.+?)\\] is not supported\\. Only System\\.Windows\\.Control are supported","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs","lineNumber":578,"sourceCode":"#if STRIDE_UI_SDL\n            // iOS reuses the SDL surface-creation path (GameContextiOS inherits GameContextSDL);\n            // SDL's VulkanCreateSurface routes to VkMetalSurfaceCreateInfoEXT internally on iOS.\n            if (Description.DeviceWindowHandle.Context == Games.AppContextType.DesktopSDL\n                || Description.DeviceWindowHandle.Context == Games.AppContextType.iOS)\n            {\n                var control = Description.DeviceWindowHandle.NativeWindow as SDL.Window;\n                Silk.NET.Core.Native.VkNonDispatchableHandle surfaceHandle = default;\n                SDL.Window.SDL.VulkanCreateSurface((Silk.NET.SDL.Window*)control.SdlHandle, new Silk.NET.Core.Native.VkHandle(GraphicsDevice.NativeInstance.Handle), ref surfaceHandle);\n                surface = new VkSurfaceKHR(surfaceHandle.Handle);\n            }\n            else\n#endif\n            if (Platform.Type == PlatformType.Windows)\n            {\n                var controlHandle = Description.DeviceWindowHandle.Handle;\n                if (controlHandle == IntPtr.Zero)\n                {\n                    throw new NotSupportedException($\"Form of type [{Description.DeviceWindowHandle.GetType().Name}] is not supported. Only System.Windows.Control are supported\");\n                }\n\n                var surfaceCreateInfo = new VkWin32SurfaceCreateInfoKHR\n                {\n                    sType = VkStructureType.Win32SurfaceCreateInfoKHR,\n                    hinstance = Process.GetCurrentProcess().Handle,\n                    hwnd = controlHandle,\n                };\n                GraphicsDevice.CheckResult(GraphicsDevice.NativeInstanceApi.vkCreateWin32SurfaceKHR(GraphicsDevice.NativeInstance, &surfaceCreateInfo, null, out surface));\n            }\n            else if (Platform.Type == PlatformType.Android)\n            {\n                throw new NotImplementedException();\n            }\n            else if (Platform.Type == PlatformType.Linux)\n            {\n                throw new NotSupportedException(\"Only SDL is supported for the time being on Linux\");\n            }","sourceCodeStart":560,"sourceCodeEnd":596,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs#L560-L596","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\nvar handle = new WindowHandle(AppContextType.Window, IntPtr.Zero);\n// after\nvar handle = new WindowHandle(AppContextType.Window, gameForm.Handle);","handlingStrategy":"validation","validationCode":"if (Platform.Type == PlatformType.Windows && desc.DeviceWindowHandle.Handle == IntPtr.Zero)\n    throw new InvalidOperationException(\"Window handle is not yet created; show/create the control first\");","typeGuard":"bool HasValidWin32Handle(WindowHandle h) => h?.Handle is IntPtr hwnd && hwnd != IntPtr.Zero;","tryCatchPattern":"try { presenter = new SwapChainGraphicsPresenter(device, desc); }\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"System.Windows.Control\")) { log.Error(\"Invalid/empty Win32 window handle\", ex); throw; }","preventionTips":["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)"],"tags":["vulkan","win32","window-handle","platform"],"backgroundTag":"invalid-argument-value","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}