Windows native examples use the MSVC toolchain with Visual Studio C++ build
tools and vcpkg zlib:x64-windows. The Skia entrypoints are the recommended
native mainline. WGPU diagnostic entrypoints still use wgpu_mbt dynamic mode
with the official wgpu-windows-x86_64-msvc-release.zip release.
Windows native WebView support is auto-detected by the moui_webview
prebuild from the .tools/webview2/ cache directory (set up by
scripts/windows/setup_msvc_deps.ps1 -InstallWebView2), matching how Linux
auto-detects WebKitGTK via pkg-config. Fallback builds compile without the
WebView2 SDK and report HostWebViewCapabilities.available=false; builds with
the SDK use WebView2 controllers parented to the app HWND, sync
DrawFrame.platform_views, forward controlled navigation and
title/history/bridge events, and drain WebViewController tasks after renderer
presentation. Override auto-detection by setting environment variables
such as MOUI_WINDOWS_ENABLE_WEBVIEW2=1,
MOUI_WINDOWS_WEBVIEW2_INCLUDE=<webview2-sdk-include>, and
MOUI_WINDOWS_WEBVIEW2_LINK_FLAGS=\"<WebView2Loader link flags>\", or by setting
the explicit MOUI_WINDOWS_WEBVIEW2_STUB_CC_FLAGS /
MOUI_WINDOWS_WEBVIEW2_CC_LINK_FLAGS pair. The prebuild adds
-DMOUI_WINDOWS_ENABLE_WEBVIEW2 when WebView2 flags are resolved.
winget install --id Microsoft.VisualStudio.2022.BuildTools -e
powershell -ExecutionPolicy Bypass -File .\\scripts\\windows\\setup_msvc_deps.ps1 -InstallZlib
powershell -ExecutionPolicy Bypass -File .\\scripts\\windows\\build_windows_msvc.ps1 `
-Package examples/showcase/windows_skia `
-BuildOnly
powershell -ExecutionPolicy Bypass -File .\\scripts\\windows\\package_windows_app_msvc.ps1 `
-Package examples/showcase/windows_skia `
-AppName MoUIShowcaseThe MSVC helper imports vcvarsall.bat through vswhere, sets CC and CXX
to cl.exe on PATH, and applies shared CL/LINK flags for MoonBit native
stubs. It detects whether the selected package imports the WGPU
provider. Skia packages do not download or package wgpu_native.dll; WGPU
diagnostic packages set MBT_WGPU_LINK_MODE=dynamic and point
MBT_WGPU_NATIVE_ROOT at the extracted MSVC WGPU release. moui_skia emits
/std:c++20 stub flags for its Windows Skia C++ bindings via the package
prebuild. Packaged MSVC apps use the vcpkg
zlib:x64-windows runtime for native image decoding. When the
Visual Studio-bundled vcpkg rejects direct classic installs, run
setup_msvc_deps.ps1 -InstallZlib so the dependency is installed with an
ignored repository-local manifest workspace under .tools\\vcpkg-msvc. Packaged
apps should be launched through the generated run.cmd; WGPU diagnostic
packages use that wrapper so the bundled WGPU release metadata is visible to
the dynamic loader.
To run an entrypoint directly after setup:
powershell -ExecutionPolicy Bypass -Command "& { . .\\scripts\\windows\\msvc_env.ps1; moon run examples/showcase/windows_skia --target native }"The Showcase Windows Skia route is an interactive app entrypoint. Keep matching-host first-frame smoke in tester/backend smoke runners rather than adding auto-exit flags to the composition root.
Windows Skia/Ganesh link flags are generated by moui_skia/build.js (from
MOUI_SKIA_CC_LINK_FLAGS): moui_skia/native/moon.pkg uses them for
binding-local tests, while moui_skia_renderer/build.js registers one final
application link_configs entry. Win32 system libraries for the window host come
from window/windows prebuild link_configs. DirectWrite WGPU text uses
moui_wgpu_renderer/directwrite link_configs (-lz).
Example windows_skia / windows_wgpu entrypoints should not repeat Skia or
Win32 link flags. They only need an empty cc-link-flags override so Moon
disables tcc -run when required:
link: { "native": { "cc-link-flags": "" } },WebView2 flags remain owned by moui_webview/build.js link_configs for
backend/windows when the SDK is detected.
The Windows host follows the same Event and HostRuntimeDriver path as
macOS, with platform-specific ownership limited to Win32 window handles,
services, lifecycle, resize handling, text-input session synchronization, and
redraw requests. Concrete rendering is injected through
ordered RendererProvider values at the application entrypoint.
backend/windows supplies an opaque HostSurface with native handles, a GDI CPU presenter,
and raw-byte HostImageSource; concrete Skia/WGPU construction stays in
moui_skia_renderer and moui_wgpu_renderer. Text
clipboard requests are implemented through the Win32
CF_UNICODETEXT clipboard API and normalized to UTF-8 at the host-service
boundary. The Windows service bridge also opens URLs through ShellExecuteW,
presents basic open/save/directory dialogs through the Win32 common dialog and
shell APIs, presents command menus at the current cursor position through
TrackPopupMenu, reads/writes UTF-8 text files through the shared text-file
service contract, and reports light/dark system theme from the current user's
AppsUseLightTheme registry value.
The native app entrypoint applies that reported theme to the runtime environment
before creating the host driver, matching the macOS startup path. Windows
theme-change events use the shared Event::ThemeChanged runtime path when
emitted by the local window backend.
The UI Automation bridge in backend/windows is a candidate native adapter.
It consumes committed semantics snapshots/deltas, creates fragment providers,
and returns UIA actions through the exact-generation runtime action entrypoint.
It depends on the narrow mbw_install_native_message_hook API in
wzzc-dev/window/windows so the window-owned WndProc can delegate
WM_GETOBJECT without subclassing the HWND. The hook must first be released in
the pinned window package and the adapter must compile with MSVC plus the
Windows SDK. Native accessibility readiness remains false until a real UIA
client proves tree queries, patterns, actions, focus, deletion, and live
notifications; package tests and non-Windows fallback builds are only L1.
Right-click context-menu requests use the same TrackPopupMenu path and dispatch
the selected ActionCommand back through HostRuntimeDriver.
File drag/drop events emitted by the local window/windows backend are
normalized through Event::DragDrop and dispatched to
View::on_file_drop targets, matching the macOS host path.
The @render_wgpu.native(...) diagnostic factory installs the sibling
moui_wgpu_renderer/directwrite provider
through the same renderer/runtime boundary used by macOS CoreText and composes
it with moui_wgpu_renderer/cosmic_text as fallback. That provider is currently an
explicit scaffold using moui_wgpu_renderer/text_protocol for UTF-32 input encoding,
private versioned measurement payload parsing, a versioned registration
payload, and a generic shaped-run envelope for glyph placements plus
DirectWrite-private raster payloads. It also routes raster glyph bytes through
the shared single-channel raster parser. Its native stub advertises the
DirectWrite integration point while returning no platform layout/raster data,
so the composed Cosmic fallback handles native text until the real DirectWrite
engine lands. Choose MoonCosmic through the factory's text_engine argument.
The canonical examples/showcase/windows_wgpu entrypoint remains a WGPU
diagnostic; it selects the DirectWrite scaffold with Moon Cosmic as its
internal fallback. examples/showcase/windows_skia is the Windows Skia
mainline and evidence application.
Select Skia by importing wzzc-dev/moui_skia_renderer, adding
@render_skia.from_env(platform=@render_skia.NativeGpuPlatform::Windows) to
the app builder, and capturing WindowsHostAppOptions in @windows.entry.
The provider binds a RendererSession backed by @render_skia.SkiaRasterRenderer
and presents the CPU pixel frame through the Win32 presenter. The C presenter
copies the RGBA premultiplied readback into a top-down 32-bit BGRA DIB buffer
and blits it to the client DC with StretchDIBits. If moui_skia/native is only
in fallback mode, renderer creation is rejected with a diagnostic instead of
opening an empty HWND.
The Windows host loop drains RendererEvent image requests, keeps only
cancellable byte-I/O tasks, and returns token-matched completions to the
selected session. Skia or WGPU owns decode, resource caches, and completion
diagnostics; backend/windows keeps no image revision or cache-residency
mirror. Applied completions request redraw for the matching HWND, while stale
or disposed tokens are ignored. The required async second-frame artifact
remains matching-host pending until a Windows/MSVC run records it from a Skia
composition root.
Passed Windows runtime observation still needs a Windows/MSVC host running the
Showcase or Markdown Editor Skia entrypoints with recorded artifacts. On
non-Windows hosts, the Win32 presenter and service stubs may fail C compilation
because they require windows.h, so a Darwin failure of
moui/backend/windows or moui_skia_renderer is a host/toolchain limit rather than Windows
runtime observation.
To use a preseeded local wgpu-native release for WGPU diagnostics instead of
the helper-managed copy, set MBT_WGPU_NATIVE_ROOT to the extracted MSVC
release root or pass that path as -WgpuNativeRoot to the Windows helper
script. MSVC dynamic roots should contain lib\\wgpu_native.dll and
wgpu-native-meta\\wgpu-native-git-tag.