VB2012技术问询:主窗体如何准确获取次级窗体的Form Size?
解决VB2012中获取Alert窗体Form Size不一致的问题
嘿,这个坑我之前踩过!在主窗体frmMain_Load里直接拿Alert窗体的尺寸,经常会拿到不准的值,核心原因就是窗体还没完成完整初始化——系统还没来得及根据当前操作系统主题、DPI设置渲染完非客户区(标题栏、边框这些),这时候的Size是临时值,不是最终的实际尺寸。
下面给你几个靠谱的解决方案:
方案1:在Alert窗体完全显示后传递尺寸
最稳妥的方式是等Alert窗体的非客户区完全渲染完成后,再把尺寸传给主窗体。可以用Alert窗体的Shown事件(这个事件会在窗体完全绘制完成后触发):
Alert窗体代码
Private Sub AlertForm_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown ' 把当前窗体的最终尺寸传给主窗体 frmMain.ReceiveAlertSize(Me.Size) ' 如果不需要显示Alert,可以在这里直接Hide() Me.Hide() End Sub
主窗体代码
' 公开一个方法接收Alert的尺寸 Public Sub ReceiveAlertSize(alertFinalSize As Size) ' 这里就可以用准确的尺寸做计算了 Console.WriteLine("Alert窗体实际尺寸:" & alertFinalSize.ToString()) End Sub
方案2:强制初始化Alert窗体句柄获取尺寸
如果不想依赖Alert的事件,可以在主窗体里先强制创建Alert窗体的句柄,让系统完成非客户区的尺寸计算,再获取值:
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim tempAlert As New AlertForm() ' 强制创建窗体句柄,触发系统计算非客户区尺寸 tempAlert.CreateHandle() ' 此时获取的Size就是最终的准确值 Dim correctAlertSize As Size = tempAlert.Size ' 用完记得销毁临时实例释放资源 tempAlert.Dispose() ' 接下来就可以用correctAlertSize做你的计算了 End Sub
补充说明:为什么尺寸会不一致?
窗体的Size是客户区尺寸 + 非客户区尺寸的总和,其中非客户区(标题栏、边框)的大小由当前系统的主题、DPI、窗口样式决定。在窗体初始化流程中:
- 先初始化
ClientSize(这是你固定的部分) - 系统随后才会根据环境参数计算并渲染非客户区,更新
Form.Size
而frmMain_Load触发时,Alert窗体大概率还停留在第一步,所以拿到的是未包含非客户区的临时尺寸,自然和后续拿到的最终值不一样。
内容的提问来源于stack exchange,提问作者sinDizzy
相关产品推荐
相关产品推荐

