11using System . Diagnostics ;
2+ using System . Text . Json ;
23using Microsoft . Web . WebView2 . Core ;
34
45namespace MaiChartManager ;
56
67public sealed partial class Browser : Form
78{
89 private Uri ? loopbackUrl ;
10+ private double _currentZoomFactor = 1.0 ;
911 private static ILogger logger = AppMain . GetLogger < Browser > ( ) ;
1012
1113 private static bool IsRunningAsUwp ( )
@@ -28,6 +30,45 @@ public Browser(string? loopbackUrl = null)
2830 StartPosition = FormStartPosition . Manual ;
2931 Location = WebViewHelper . CalculatePosition ( Width , Height ) ;
3032 }
33+
34+ public static double TargetDpiScale { get ; private set ; }
35+
36+ /// <summary>
37+ /// 根据配置和屏幕信息计算 WebView2 的 ZoomFactor。
38+ /// UiZoom=0 表示自动模式:等效宽度 < 1440 时,将目标缩放 clamp 到 100%~150%,
39+ /// 然后除以系统缩放得到 ZoomFactor。
40+ /// UiZoom>0 表示用户指定的百分比(相对于物理分辨率的缩放比例),
41+ /// ZoomFactor = UiZoom / 100.0 / dpiScale。
42+ /// </summary>
43+ private double CalculateZoomFactor ( )
44+ {
45+ var dpiScale = DeviceDpi / 96.0 ;
46+ var screen = Screen . FromControl ( this ) ;
47+ var physicalWidth = screen . Bounds . Width ;
48+ var effectiveWidth = physicalWidth / dpiScale ;
49+
50+ // 始终计算 auto 模式下的目标缩放,供前端显示
51+ TargetDpiScale = effectiveWidth >= 1440
52+ ? dpiScale
53+ : Math . Clamp ( physicalWidth / 1440.0 , 1.0 , 1.5 ) ;
54+
55+ var uiZoom = StaticSettings . Config . UiZoom ;
56+ if ( uiZoom > 0 )
57+ {
58+ // 用户指定的百分比是 Windows 缩放意义上的,需要除以当前系统缩放
59+ return uiZoom / 100.0 / dpiScale ;
60+ }
61+
62+ // auto 模式
63+ return TargetDpiScale / dpiScale ;
64+ }
65+
66+ private void ApplyZoomFactor ( )
67+ {
68+ _currentZoomFactor = CalculateZoomFactor ( ) ;
69+ webView21 . ZoomFactor = _currentZoomFactor ;
70+ }
71+
3172 private void webView21_CoreWebView2InitializationCompleted ( object sender , CoreWebView2InitializationCompletedEventArgs e )
3273 {
3374 if ( IsRunningAsUwp ( ) )
@@ -42,11 +83,12 @@ private void webView21_CoreWebView2InitializationCompleted(object sender, CoreWe
4283
4384 WebViewHelper . SetupCoreWebView2 ( webView21 . CoreWebView2 , loopbackUrl ) ;
4485
45- // webView21.CoreWebView2.AddWebResourceRequestedFilter("*://mcm.invalid/MaiChartManagerServlet/*", CoreWebView2WebResourceContext.All);
46- // webView21.CoreWebView2.WebResourceRequested += OnWebResourceRequested ;
86+ // 应用缩放
87+ ApplyZoomFactor ( ) ;
4788
4889 webView21 . CoreWebView2 . PermissionRequested += WebViewHelper . OnPermissionRequested ;
4990 webView21 . CoreWebView2 . NewWindowRequested += CoreWebView2_NewWindowRequested ;
91+ webView21 . CoreWebView2 . WebMessageReceived += OnWebMessageReceived ;
5092 }
5193
5294 private async void CoreWebView2_NewWindowRequested ( object ? sender , CoreWebView2NewWindowRequestedEventArgs e )
@@ -81,13 +123,35 @@ private async void CoreWebView2_NewWindowRequested(object? sender, CoreWebView2N
81123 e . NewWindow = webView . CoreWebView2 ;
82124 webView . CoreWebView2 . DocumentTitleChanged += ( _ , _ ) => form . Text = webView . CoreWebView2 . DocumentTitle ;
83125 form . FormClosed += ( _ , _ ) => webView . Dispose ( ) ;
126+ webView . ZoomFactor = _currentZoomFactor ;
84127 }
85128 finally
86129 {
87130 deferral . Complete ( ) ;
88131 }
89132 }
90133
134+ private void OnWebMessageReceived ( object ? sender , CoreWebView2WebMessageReceivedEventArgs e )
135+ {
136+ try
137+ {
138+ var message = e . WebMessageAsJson ;
139+ using var doc = JsonDocument . Parse ( message ) ;
140+ var root = doc . RootElement ;
141+
142+ if ( root . GetProperty ( "type" ) . GetString ( ) != "setZoom" ) return ;
143+
144+ var value = root . GetProperty ( "value" ) . GetInt32 ( ) ;
145+ StaticSettings . Config . UiZoom = value ;
146+ StaticSettings . Config . Save ( ) ;
147+ ApplyZoomFactor ( ) ;
148+ }
149+ catch ( Exception ex )
150+ {
151+ logger . LogError ( ex , "处理 WebMessage 失败" ) ;
152+ }
153+ }
154+
91155
92156 private async void OnWebResourceRequested ( object ? sender , CoreWebView2WebResourceRequestedEventArgs args )
93157 {
0 commit comments