|
| 1 | +# Background |
| 2 | +The WebView attempts to detects monitor scale changes and applies the monitor DPI scale to all UI produced by the WebView. |
| 3 | +When the host app has a DPI awareness of PerMonitorV2, then all child HWNDs receive WM_DPICHANGED. |
| 4 | +The WebView can check the current monitor DPI scale when it receives WM_DPICHANGED. |
| 5 | +But if the host app is just PerMonitor aware (not v2), then only the top level window receives WM_DPICHANGED. |
| 6 | +The WebView could try to use other metrics (like resize) to check the DPI, but resize is not guaranteed in that scenario. |
| 7 | +From [GitHub feedback](https://github.com/MicrosoftEdge/WebView2Feedback/issues/65), |
| 8 | +we also know that there are consumers of WebView that want to explicitly set a custom DPI scale for WebView. |
| 9 | + |
| 10 | +In this document we describe the updated API. We'd appreciate your feedback. |
| 11 | + |
| 12 | + |
| 13 | +# Description |
| 14 | +To allow the app to control the DPI scale of WebView, we are adding a `RasterizationScale` property to the CoreWebView2Controller interface. |
| 15 | +The RasterizationScale property controls the DPI scaling for all UI in WebView. |
| 16 | + |
| 17 | +In order to maintain compatibility with apps developed before this API existed, |
| 18 | +WebView2 continues to detect monitor scale changes by default and will update the RasterizationScale property. |
| 19 | +When the RasterizationScale property is updated, the `RasterizationScaleChanged` event is raised. |
| 20 | +The app can tell WebView2 to stop updating the RasterizationScale property by changing |
| 21 | +`ShouldDetectMonitorDpiScaleChanges` from the default value of true, to false. |
| 22 | + |
| 23 | +# Examples |
| 24 | +The following code snippets show how to use the RasterizationScale and ShouldDetectMonitorScaleChanges properties, |
| 25 | +and now to listen to the RasterizationScaleChanged event. |
| 26 | +## Win32 C++ |
| 27 | +```cpp |
| 28 | +void ViewComponent::SetRasterizationScale(float additionalScale) |
| 29 | +{ |
| 30 | + CHECK_FAILURE(m_controller->put_ShouldDetectMonitorScaleChanges(FALSE)); |
| 31 | + m_webviewAdditionalRasterizationScale = additionalScale; |
| 32 | + // RasterizationScale is typically the monitor DPI scale and text scaling, but |
| 33 | + // the app could add an additional scale for its own scenarios. |
| 34 | + double rasterizationScale = |
| 35 | + additionalScale * m_appWindow->GetDpiScale() * m_appWindow->GetTextScale(); |
| 36 | + CHECK_FAILURE(m_controller->put_RasterizationScale(rasterizationScale)); |
| 37 | +} |
| 38 | + |
| 39 | +Callback<ICoreWebView2RasterizationScaleChangedEventHandler>( |
| 40 | + [this](ICoreWebView2Controller* sender, IUnknown* args) -> HRESULT { |
| 41 | + double rasterizationScale; |
| 42 | + CHECK_FAILURE(m_controller->get_RasterizationScale(&rasterizationScale)); |
| 43 | + |
| 44 | + std::wstring message = L"WebView2APISample (RasterizationScale: " + |
| 45 | + std::to_wstring(int(rasterizationScale * 100)) + L"%)"; |
| 46 | + SetWindowText(m_appWindow->GetMainWindow(), message.c_str()); |
| 47 | + return S_OK; |
| 48 | + }) |
| 49 | +.Get(), &m_rasterizationScaleChangedToken)); |
| 50 | +``` |
| 51 | +## .Net |
| 52 | +```c# |
| 53 | +public void SetRasterizationScale(double additionalScale) |
| 54 | +{ |
| 55 | + CoreWebView2Controller.ShouldDetectMonitorScaleChanges = false; |
| 56 | + m_webviewAdditionalRasterizationScale = additionalScale; |
| 57 | + |
| 58 | + // RasterizationScale is typically the monitor DPI scale and text scaling, but |
| 59 | + // the app could add an additional scale for its own scenarios. |
| 60 | + double rasterizationScale = additionalScale * GetDpiScale() * GetTextScale(); |
| 61 | + CoreWebView2Controller.RasterizationScale = rasterizationScale; |
| 62 | +} |
| 63 | +``` |
| 64 | + |
| 65 | + |
| 66 | +# API Notes |
| 67 | +See [API Details](#api-details) section below for API reference. |
| 68 | + |
| 69 | +# API Details |
| 70 | +## Win32 C++ |
| 71 | +```c# |
| 72 | +interface ICoreWebView2Controller2 : ICoreWebView2Controller { |
| 73 | + /// The rasterization scale for the WebView. The rasterization scale is the |
| 74 | + /// combination of the monitor DPI scale and text scaling set by the user. |
| 75 | + /// This value should be updated when the DPI scale of the app's top level |
| 76 | + /// window changes (i.e. monitor DPI scale changes or window changes monitor) |
| 77 | + /// or when the text scale factor of the system changes. |
| 78 | + /// |
| 79 | + /// \snippet AppWindow.cpp DPIChanged |
| 80 | + /// |
| 81 | + /// \snippet AppWindow.cpp TextScaleChanged1 |
| 82 | + /// |
| 83 | + /// \snippet AppWindow.cpp TextScaleChanged2 |
| 84 | + /// |
| 85 | + /// Rasterization scale applies to the WebView content, as well as |
| 86 | + /// popups, context menus, scroll bars, and so on. Normal app scaling scenarios |
| 87 | + /// should use the ZoomFactor property or SetBoundsAndZoomFactor API which |
| 88 | + /// only scale the rendered HTML content and not popups, context menus, scroll bars and so on. |
| 89 | + /// |
| 90 | + /// \snippet ViewComponent.cpp RasterizationScale |
| 91 | + [propget] HRESULT RasterizationScale([out, retval] double* scale); |
| 92 | + // Set the rasteriation scale property. |
| 93 | + [propput] HRESULT RasterizationScale([in] double scale); |
| 94 | + |
| 95 | + /// ShouldDetectMonitorScaleChanges property determines whether the WebView |
| 96 | + /// attempts to track monitor DPI scale changes. When true, the WebView will |
| 97 | + /// track monitor DPI scale changes, update the RasterizationScale property, |
| 98 | + /// and raises RasterizationScaleChanged event. |
| 99 | + /// When false, the WebView will not track monitor DPI scale changes, and the app |
| 100 | + /// must update the RasterizationScale property itself. RasterizationScaleChanged |
| 101 | + /// event will never raise when ShouldDetectMonitorScaleChanges is false. Apps that want |
| 102 | + /// to set their own rasterization scale should set this property to false to avoid the |
| 103 | + /// WebView2 updating the RasterizationScale property to match the monitor DPI scale. |
| 104 | + [propget] HRESULT ShouldDetectMonitorScaleChanges([out, retval] BOOL* value); |
| 105 | + /// Set the ShouldDetectMonitorScaleChanges property. |
| 106 | + [propput] HRESULT ShouldDetectMonitorScaleChanges([in] BOOL value); |
| 107 | + |
| 108 | + /// Add an event handler for the RasterizationScaleChanged event. |
| 109 | + /// The event is raised when the WebView detects that the monitor DPI scale |
| 110 | + /// has changed, ShouldDetectMonitorScaleChanges is true, and the WebView has |
| 111 | + /// changed the RasterizationScale property. |
| 112 | + /// |
| 113 | + /// \snippet ViewComponent.cpp RasterizationScaleChanged |
| 114 | + HRESULT add_RasterizationScaleChanged( |
| 115 | + [in] ICoreWebView2RasterizationScaleChangedEventHandler* |
| 116 | + eventHandler, |
| 117 | + [out] EventRegistrationToken* token); |
| 118 | + /// Remove an event handler previously added with |
| 119 | + /// add_RasterizationScaleChanged. |
| 120 | + HRESULT remove_RasterizationScaleChanged( |
| 121 | + [in] EventRegistrationToken token); |
| 122 | +} |
| 123 | +interface ICoreWebView2RasterizationScaleChangedEventHandler : IUnknown { |
| 124 | + /// Called to provide the implementer with the event args for the |
| 125 | + /// corresponding event. There are no event args and the args |
| 126 | + /// parameter will be null. |
| 127 | + HRESULT Invoke( |
| 128 | + [in] ICoreWebView2Controller2* sender, |
| 129 | + [in] IUnknown* args); |
| 130 | +} |
| 131 | +``` |
| 132 | +## .Net and WinRT |
| 133 | +```c# |
| 134 | +namespace Microsoft.Web.WebView2.Core |
| 135 | +{ |
| 136 | + unsealed runtimeclass CoreWebView2Controller |
| 137 | + { |
| 138 | + /// <summary> |
| 139 | + /// Gets or sets the WebView rasterization scale. |
| 140 | + /// </summary> |
| 141 | + /// <remarks> |
| 142 | + /// The rasterization scale is the combination of the monitor DPI scale and text scaling set by the user. This value should be updated when the DPI scale of the app's top level window changes (i.e. monitor DPI scale changes or the window changes monitor) or when the text scale factor of the system changes. |
| 143 | + /// Rasterization scale applies to the WebView content, as well as popups, context menus, scroll bars, and so on. Normal app scaling scenarios should use the <see cref="CoreWebView2.ZoomFactor"/> property or <see cref="CoreWebView2.SetBoundsAndZoomFactor"/> method. |
| 144 | + /// </remarks> |
| 145 | + Double RasterizationScale { get; set; }; |
| 146 | + |
| 147 | + /// <summary> |
| 148 | + /// Determines whether the WebView will detect monitor scale changes. |
| 149 | + /// </summary> |
| 150 | + /// <remarks> |
| 151 | + /// ShouldDetectMonitorScaleChanges property determines whether the WebView attempts to track monitor DPI scale schanges. When true, the WebView will track monitor DPI scale changes, update the <see cref="CoreWebView2.RasterizationScale"/> property, and raise <see cref="CoreWebView2.RasterizationScaleChanged"/> event. When false, the WebView will not track monitor DPI scale changes, and the app must update the <see cref="CoreWebView2.RasterizationScale"/> property itself. <see cref="CoreWebView2.RasterizationScaleChanged"/> event will never be raised when ShouldDetectMonitorScaleChanges is false. |
| 152 | + /// </remarks> |
| 153 | + Boolean ShouldDetectMonitorScaleChanges { get; set; }; |
| 154 | + |
| 155 | + /// <summary> |
| 156 | + /// RasterizationScalechanged is raised when the <see cref="CoreWebView2Controller.RasterizationScale"/> property changes. |
| 157 | + /// </summary> |
| 158 | + /// <remarks> |
| 159 | + /// The event is raised when the Webview detects that the monitor DPI scale has changed, <see cref="CoreWebView2Controller.ShouldDetectMonitorScaleChanges"/> is true, and the Webview has changed the <see cref="CoreWebView2Controller.RasterizationScale"/> property. |
| 160 | + /// </remarks> |
| 161 | + /// <seealso cref="CoreWebView2Controller.RasterizationScale"/> |
| 162 | + event Windows.Foundation.TypedEventHandler<CoreWebView2Controller, Object> RasterizationScaleChanged; |
| 163 | + } |
| 164 | +``` |
0 commit comments