|
1 | 1 | # Optional WinUI 3 backend on Windows |
2 | 2 |
|
3 | 3 | `NATIVEAPI_ENABLE_WINUI3=ON` selects WinUI 3 for new Windows menus and |
4 | | -message dialogs. Menus use `Microsoft.UI.Xaml.Controls.MenuFlyout`; message |
| 4 | +message dialogs, plus Windows App SDK title-bar and notification integration. Menus use `Microsoft.UI.Xaml.Controls.MenuFlyout`; message |
5 | 5 | dialogs use `Microsoft.UI.Xaml.Controls.ContentDialog`. Both share a lazy XAML |
6 | 6 | runtime and use private XAML Islands, including in tray-only applications. |
7 | 7 | Future WinUI components should use this same option and runtime. |
| 8 | +File dialogs use the Windows system picker; they are not XAML controls. |
8 | 9 |
|
9 | 10 | With the option OFF (the default), menus and dialogs retain their Win32 |
10 | 11 | implementations. Public C++ and C interfaces stay platform independent. |
@@ -95,8 +96,8 @@ No runtime switch or new API is required. |
95 | 96 | message loop (normally `Application::Run()`). `Close()` dismisses it. |
96 | 97 | - `Application` pumps messages until dismissal and temporarily disables the |
97 | 98 | application's currently visible, enabled top-level windows. |
98 | | -- `Window` disables the calling thread's active visible window. The public API |
99 | | - has no explicit parent parameter yet; if no active window exists, the dialog |
| 99 | +- `Window` disables the window supplied by `SetParentWindow()`, or the calling |
| 100 | + thread's active visible window if no parent was supplied. Without either, it |
100 | 101 | opens without an owner. It never blocks other applications. |
101 | 102 | - `SetTitle` and `SetMessage` update displayed content. Long messages scroll. |
102 | 103 | The OK button, title-bar close, and `Close()` dismiss the dialog. Previously |
@@ -156,3 +157,99 @@ destruction while open, and sharing the runtime with a menu: |
156 | 157 | ```powershell |
157 | 158 | ./build/menu-modern/tests/Debug/winui3_dialog_test.exe |
158 | 159 | ``` |
| 160 | + |
| 161 | +## Extended desktop features |
| 162 | + |
| 163 | +Build `desktop_features_example` and run it with one of these arguments: |
| 164 | + |
| 165 | +| Argument | Example | |
| 166 | +|---|---| |
| 167 | +| `dialog` (default) | Save/Discard/Cancel buttons, editable input, checkbox, progress | |
| 168 | +| `window` | Existing HWND with AppWindow title-bar colors and DWM Mica | |
| 169 | +| `open` / `multiple` | Select one or several files | |
| 170 | +| `save` | Select a save destination | |
| 171 | +| `folder` | Select a folder | |
| 172 | +| `notify` | Deliver a system notification; clicking it prints activation arguments and exits | |
| 173 | + |
| 174 | +```powershell |
| 175 | +cmake --build build/menu-modern --config Debug --target desktop_features_example desktop_features_test |
| 176 | +./build/menu-modern/examples/desktop_features_example/Debug/desktop_features_example.exe dialog |
| 177 | +``` |
| 178 | + |
| 179 | +`MessageDialog::IsExtendedSupported()` reports whether the extended controls are |
| 180 | +compiled in. Configure buttons, default button and parent before opening. Input, |
| 181 | +checkbox and progress can be updated while open. `SetProgress(-2)` hides progress, |
| 182 | +`-1` is indeterminate, and values from 0 to 1 are determinate. Invalid values are |
| 183 | +rejected. After dismissal, read `GetResult()`, `GetInputText()` and |
| 184 | +`IsCheckboxChecked()`. Escape, close button and programmatic close return `Close`; |
| 185 | +`None` means no result yet. On a modeless dialog, wait until `IsOpen()` is false. |
| 186 | +Use all operations, including destruction, on the UI thread. |
| 187 | + |
| 188 | +`Window::SetTitleBarColors()` and `ResetTitleBarColors()` operate on the existing |
| 189 | +HWND through AppWindow; they do not replace an embedding framework's content. |
| 190 | +Title-bar visibility uses OverlappedPresenter. Mica/Acrylic continue to use DWM, |
| 191 | +so availability depends on the Windows version. Opaque content painted by a host |
| 192 | +framework can cover the backdrop. The native HWND lifetime now controls removal |
| 193 | +from WindowRegistry; destroying a temporary wrapper does not unregister the HWND. |
| 194 | + |
| 195 | +`FileDialog` supports `OpenFile`, `OpenFiles`, `SaveFile`, and `SelectFolder`. |
| 196 | +`Open()` blocks with message dispatch and returns true for acceptance **or user |
| 197 | +cancellation**; distinguish them with `GetResult()`. `GetPaths()` returns UTF-8 |
| 198 | +filesystem paths. Failures return false with `GetLastError()`. Configure an explicit |
| 199 | +parent with `SetParentWindow()` when one exists. Without a visible parent, a small |
| 200 | +reusable owner is hosted on the calling STA. Keep the FileDialog alive until Open |
| 201 | +returns. Only Window modality is supported; other modality values fail explicitly. |
| 202 | + |
| 203 | +With WinUI3 enabled, the implementation uses the OS |
| 204 | +[Windows.Storage.Pickers APIs with HWND interop](https://learn.microsoft.com/en-us/windows/apps/develop/ui/display-ui-objects), |
| 205 | +which work with the pinned App SDK 1.6. It does **not** use the newer |
| 206 | +Microsoft.Windows.Storage.Pickers namespace introduced in App SDK 1.8. WinRT file |
| 207 | +pickers inherit the OS restrictions (including elevated-process restrictions). |
| 208 | +The Win32 build uses IFileDialog, including native multiselect and folder picking. |
| 209 | +SaveFile initially filters `.txt`; supply extensions explicitly for other formats. |
| 210 | +Clearing the extension list uses `.txt` in the WinRT backend and all files in Win32. The WinRT save picker can create an empty file |
| 211 | +when the selection is confirmed; callers should then write its contents. |
| 212 | + |
| 213 | +`NotificationManager` uses Microsoft.Windows.AppNotifications, with optional |
| 214 | +notification buttons and `NotificationActivatedEvent`. Subscribe before |
| 215 | +`Initialize()` at every app startup, including notification-triggered launches. |
| 216 | +Pump the normal application UI loop for activation callbacks. Initialize, Show, |
| 217 | +Remove and Shutdown belong on the main STA. Call Shutdown before stopping the loop; |
| 218 | +it unregisters this process but preserves the OS registration needed to relaunch |
| 219 | +it from delivered notifications. Registration is owned by this manager: applications |
| 220 | +already managing AppNotificationManager themselves should not initialize a second |
| 221 | +registration through this library. Tags must be 1–16 ASCII letters/digits/`_`/`-`. |
| 222 | +Show replaces notifications with the same tag in the library's `nativeapi` group. |
| 223 | +Success means the OS accepted the notification, not that a banner was visible: |
| 224 | +Windows notification settings and Do Not Disturb may suppress it. Both the runtime |
| 225 | +framework and its notification/Singleton components must be installed. |
| 226 | + |
| 227 | +### Platform support |
| 228 | + |
| 229 | +| Feature | Windows, WinUI3 ON | Windows, OFF | Other platforms | |
| 230 | +|---|---|---|---| |
| 231 | +| Extended MessageDialog | Supported | Setters return false; basic dialog retained | Setters return false; existing basic implementation retained | |
| 232 | +| Title-bar colors | AppWindow | Returns false | Returns false | |
| 233 | +| FileDialog | System WinRT picker | IFileDialog | IsSupported returns false | |
| 234 | +| NotificationManager | App SDK notifications | IsSupported returns false | IsSupported returns false | |
| 235 | + |
| 236 | +All six platform directories define the new module entry points. C ABI files are |
| 237 | +generated; the generator's header catalog in the sibling workspace now includes |
| 238 | +`file_dialog.h` and `notification_manager.h`. This checkout is outside workspace/core, |
| 239 | +so generation is driven through the workspace codegen wrapper with CORE pointing |
| 240 | +at this checkout; downstream submodules are uninitialized and are not synced here. |
| 241 | + |
| 242 | +### Additional verification |
| 243 | + |
| 244 | +The default `desktop_features_test` checks option validation and C handle lifetime |
| 245 | +without displaying UI. Explicit desktop integration modes are: |
| 246 | + |
| 247 | +```powershell |
| 248 | +./build/menu-modern/tests/Debug/desktop_features_test.exe --ui |
| 249 | +./build/menu-modern/tests/Debug/desktop_features_test.exe --pickers |
| 250 | +./build/menu-modern/tests/Debug/desktop_features_test.exe --notify |
| 251 | +``` |
| 252 | + |
| 253 | +These exercise extended dialog state and live updates, HWND registration lifetime, |
| 254 | +AppWindow title-bar changes, Mica, cancellation of all four picker modes, and |
| 255 | +notification submission/removal. `--notify` briefly sends a test notification. |
0 commit comments