Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

put_ShouldDetectMonitorScaleChanges unable to block Windows DPI scale #3665

Closed
menghuijinxi opened this issue Jul 27, 2023 · 6 comments
Closed
Assignees
Labels
bug Something isn't working

Comments

@menghuijinxi
Copy link

I disable the impact of Windows DPI on webview2 through the following method:

CreateCoreWebView2EnvironmentWithOptions(nullptr, currentCacheFolder, nullptr,
		Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
			[uri](HRESULT result, ICoreWebView2Environment* env) -> HRESULT {

				// Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window hWnd
				env->CreateCoreWebView2Controller(WEBHwnd, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
					[uri](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT {
                        
						wil::com_ptr<ICoreWebView2Controller3> controller3 =
						controller.query<ICoreWebView2Controller3>();
						controller3->put_ShouldDetectMonitorScaleChanges(FALSE);
			}
		}

image

@novac42 novac42 added bug Something isn't working status-circle back Check back after requesting general information. and removed question labels Jul 28, 2023
@novac42
Copy link
Contributor

novac42 commented Jul 28, 2023

@menghuijinxi Could you tell us the repro steps, what's the expected outcome vs actual results? Also may you share informartion about the environment:

  • Framework (WinUI, Win32, WinForms, UWP, WPF, etc)
  • SDK and Runtime version
  • Operating System version

@menghuijinxi
Copy link
Author

I think calling “controller3->put_ShouldDetectMonitorScaleChanges(FALSE)” should not have any scaling effects on WebView2 when switching Windows DPI Scale. However, in reality, even after calling this, switching Windows DPI Scale still affects WebView2 and causes scaling effects

Framework:Win32
Microsoft.Web.WebView2:1.0.1901.177
Microsoft.Windows.ImplementationLibrary:1.0.230629.1
System version:Win11 10.0.22621

@menghuijinxi
Copy link
Author

menghuijinxi commented Jul 28, 2023

// code snippet

   static wil::com_ptr<ICoreWebView2Controller> webviewController = nullptr;
static wil::com_ptr<ICoreWebView2> webview = nullptr;

//Create Child Window
WNDCLASSEX windowClass = { 0 };
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.lpfnWndProc = DefWindowProc;
windowClass.hInstance = hInstance;
windowClass.hIcon = nullptr;
windowClass.hCursor = nullptr;
windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
windowClass.lpszClassName = L"WebView2";

if (!RegisterClassEx(&windowClass))
{
	MessageBox(0, L"RegisterClass Failed.", 0, 0);
	return;
}

//HWnd is the parent window

WEBHwnd = CreateWindowEx(WS_EX_LAYERED, windowClass.lpszClassName, L"WebView2", WS_CHILD, cacheRect.left, cacheRect.top, cacheRect.right, cacheRect.bottom,
	hWnd, NULL, hInstance, NULL);

ShowWindow(WEBHwnd, SW_SHOW);
UpdateWindow(WEBHwnd);

// <-- WebView2 sample code starts here -->
// Step 3 - Create a single WebView within the parent window
// Locate the browser and set up the environment for WebView
CreateCoreWebView2EnvironmentWithOptions(nullptr, currentCacheFolder, nullptr,
	Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
		[uri](HRESULT result, ICoreWebView2Environment* env) -> HRESULT {

			// Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window hWnd
			env->CreateCoreWebView2Controller(WEBHwnd, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
				[uri](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT {
					if (controller != nullptr) {
						webviewController = controller;
						webviewController->get_CoreWebView2(&webview);
					}

					//Set the background color to transparent
					{
						COREWEBVIEW2_COLOR bgColor = { 0, 0, 0, 0 };
						wil::com_ptr<ICoreWebView2Controller2> controller2 =
							webviewController.query<ICoreWebView2Controller2>();
						controller2->put_DefaultBackgroundColor(bgColor);
						controller2->put_ZoomFactor(ZoomFactorValue);
					}

					//Mask the impact of Windows DPI Scale
					{
						wil::com_ptr<ICoreWebView2Controller3> controller3 = 
							webviewController.query<ICoreWebView2Controller3>();
						controller3->put_ShouldDetectMonitorScaleChanges(FALSE);
					}

					// Add a few settings for the webview
					// The demo step is redundant since the values are the default settings
					wil::com_ptr<ICoreWebView2Settings> settings;
					webview->get_Settings(&settings);
					settings->put_IsScriptEnabled(TRUE);
					settings->put_AreDefaultScriptDialogsEnabled(TRUE);
					settings->put_IsWebMessageEnabled(TRUE);
					
					//Disable wheel scaling
					settings->put_IsZoomControlEnabled(false);

					// Resize WebView to fit the bounds of the parent window
					RECT rect;
					GetClientRect(WEBHwnd, &rect);
					webviewController->put_Bounds(rect);

					// Schedule an async task to navigate to Bing
					webview->Navigate(uri);

					EventRegistrationToken token;

					// <Scripting>
					// Step 5 - Scripting
					// Schedule an async task to add initialization script that freezes the Object object
					webview->AddScriptToExecuteOnDocumentCreated(L"Object.freeze(Object);", nullptr);
					// Schedule an async task to get the document URL
					webview->ExecuteScript(L"window.document.URL;", Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
						[](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT {
							LPCWSTR URL = resultObjectAsJson;
							//doSomethingWithURL(URL);
							return S_OK;
						}).Get());
					// </Scripting>

					// Schedule an async task to add initialization script that
					// 1) Add an listener to print message from the host
					// 2) Post document URL to the host
					webview->AddScriptToExecuteOnDocumentCreated(
						L"window.chrome.webview.addEventListener(\'message\', event => alert(event.data));" \
						L"window.chrome.webview.postMessage(window.document.URL);",
						nullptr);
					// </CommunicationHostWeb>

					return S_OK;
				}).Get());
			return S_OK;
		}).Get());

@novac42 novac42 removed the status-circle back Check back after requesting general information. label Aug 2, 2023
@bradp0721
Copy link
Member

@menghuijinxi, can you be more specific about the scaling effects you are seeing? Calling ShouldDetectMonitorScaleChanges(FALSE) should prevent the WebView2 from changing the RasterizationScale property as a result of monitor DPI scale changes. It is the app's responsibility to update the RasterizationScale. But calling ShouldDetectMonitorScaleChanges(FALSE) does not change the scale of the WebView2.

So if you created WebView2 on a monitor with a scale of 1.25, WebView2 would set the RasterizationScale to 1.25. Calling ShouldDetectMonitorScaleChanges(FALSE) will prevent future monitor scale changes from impacting RasterizationScale, but it does not change the WebView2 RasterizationScale back to 1.0. If you want WebView2 to render at 100%, you need to also call put_RasterizationScale(1.0).

@menghuijinxi
Copy link
Author

After your explanation, I understand the purpose of the ShouldDetectMonitorScaleChanges function, this function is not what I need.

@menghuijinxi
Copy link
Author

I now use “GetDpiForMonitor” to obtain the DPI of the Windows system, and then divide it by 96 to get the system’s scaling factor, assuming it is 1.25. Finally, by using 1/1.25=0.8 and invoking put_RasterizationScale(0.8), I can achieve the desired effect and solve this problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants