You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET VSTO Excel插件窗体移至副屏后调整尺寸异常问题咨询

问题根因

该问题由多屏不同缩放比例场景下Windows Forms的DPI感知配置缺失,以及VSTO宿主的默认DPI适配逻辑冲突导致,2.5倍的放大系数正好匹配主屏的250%缩放设置:未开启逐屏DPI感知时,窗体始终继承主屏的缩放逻辑,移到100%缩放的副屏后设置尺寸时,系统会自动对输入的尺寸再叠加一次主屏缩放比例转换,最终导致实际尺寸超出预期。你看到的Me.DeviceDpi始终为96,正是因为窗体默认未开启逐屏DPI感知,系统统一返回96DPI后自行拉伸窗体导致。

解决方案
  • 第一步:升级项目目标框架到.NET Framework 4.7.2及以上版本,获得稳定的逐屏DPI感知支持。
  • 第二步:修改项目的app.config配置,开启PerMonitorV2 DPI感知:
<configuration>
  <runtime>
    <AppContextSwitchOverrides value="Switch.System.Windows.Forms.DoNotPerformDpiScalingInDialogHost=false" />
  </runtime>
  <System.Windows.Forms.ApplicationConfigurationSection>
    <add key="DpiAwareness" value="PerMonitorV2" />
  </System.Windows.Forms.ApplicationConfigurationSection>
</configuration>
  • 第三步:在窗体代码中引入Win32 API用于获取屏幕实际缩放系数,添加如下声明:
Imports System.Runtime.InteropServices

Public Class YourFormClass
    <DllImport("gdi32.dll")>
    Private Shared Function GetDeviceCaps(ByVal hdc As IntPtr, ByVal nIndex As Integer) As UInteger
    End Function

    ' 其余原有代码
End Class
  • 第四步:将窗体的AutoScaleMode属性设置为AutoScaleMode.None,关闭系统默认的自动缩放逻辑,改为手动控制尺寸转换。
  • 第五步:添加缩放系数获取方法,修正窗体移动与尺寸设置代码,先根据目标屏幕的缩放系数换算正确的尺寸值:
' 获取指定屏幕的缩放系数
Private Function GetScreenScalingFactor(screen As Screen) As Single
    Using g As Graphics = Graphics.FromHwnd(IntPtr.Zero)
        Dim desktopPtr As IntPtr = g.GetHdc()
        Dim dpiX As UInteger = GetDeviceCaps(desktopPtr, 88) ' 88对应LOGPIXELSX,即水平DPI
        g.ReleaseHdc(desktopPtr)
        Return dpiX / 96.0F
    End Using
End Function

' 修正后的移动+调整尺寸代码
Dim activeScreen As Screen = ' 你原有逻辑获取的目标副屏
Dim scalingFactor As Single = GetScreenScalingFactor(activeScreen)

Me.StartPosition = FormStartPosition.Manual
' 位置直接取副屏对应坐标即可,无需额外叠加偏移
Me.Location = New Point(activeScreen.Bounds.X + 100, activeScreen.Bounds.Y + 100)

' 按目标屏幕缩放系数换算实际需要设置的尺寸,避免系统自动缩放
Dim targetWidth As Integer = CInt(2278 / scalingFactor)
Dim targetHeight As Integer = CInt(308 / scalingFactor)
Me.Size = New Size(targetWidth, targetHeight)
验证说明

修改后重新生成插件,再将窗体移到副屏调整尺寸时,系统不会再自动叠加缩放系数,尺寸会和你的预期值一致,且DeviceDpi属性会随窗体所在屏幕的缩放比例自动变化。

内容的提问来源于stack exchange,提问作者Andrew Goldman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 22:18:00