从另一个表单确定表单大小
Determine Form Size from another Form
VB2012:为了在主窗体中进行一些计算,我需要知道辅助窗体的窗体大小。表单大小可能因用户而异,具体取决于 OS 和主题。我了解客户规模保持不变。但是我认为我没有做正确的事情,因为根据我要求表格大小的位置,我得到了不同的数字。
作为示例,这里是我的主窗体,在加载事件中我尝试获取警报窗体的大小
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'get the default width and height of an Alert form.
Dim frmW As Integer = frmAlert.Width 'in pixels
Dim frmH As Integer = frmAlert.Height 'in pixels
Dim frCsW As Integer = frmAlert.ClientSize.Width 'in pixels
Dim frmCsH As Integer = frmAlert.ClientSize.Height 'in pixels
Debug.Print("frmW={0} frmH={1} frCsW={2} frmCsH={3}", frmW, frmH, frCsW, frmCsH)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'set up a new alert form
Dim frm As New frmAlert
'show the alert form
frm.StartPosition = FormStartPosition.CenterParent
frm.Show() 'with this option the Alert Forms stay on the screen even if the Main form is minimized.
End Sub
现在警报表单设置为 FormBorderStyle=FixedDialog、ControlBox=False、MaximizeBox=False 和 MinimizeBox=False,在警报表单中我在加载事件中有这个:
Private Sub frmAlert_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Debug.Print("me.width={0} me.height={1} cs.width={2} cs.height={3}", Me.Width, Me.Height, Me.ClientSize.Width, Me.ClientSize.Height)
End Sub
这是调试输出
frmW=380 frmH=168 frCsW=374 frmCsH=162
me.width=390 me.height=200 cs.width=374 cs.height=162
正如预期的那样,客户端大小相同,但总表单大小不同。我正在努力思考 .Height 和 .Width 的差异。不存在其他代码来更改表单属性。第二个调试语句与 IDE 设计器中的窗体大小相匹配。为什么尺寸不同?我将如何正确查询以从另一个表单获取表单大小?
在表单显示之前,它的大小会比显示时小。这是因为当您显示表单时 Windows 会根据用户的屏幕和主题设置对其执行各种操作,例如:
- 如果用户有不同的 DPI 设置,请调整它的大小。
- 根据用户选择的 window 主题为其应用边框。
- (等等)
最好的办法是先显示表单,然后获取其大小。
如果您不希望表单立即可见,您可以将其 Opacity
property 设置为 0 使其不可见,然后在您需要将表单显示给用户。
好的,所以根据@Visual Vincent 的建议,我在创建新表单时创建了一个构造函数。这进入 frmAlert.Designer.vb
Partial Class frmAlert
Private mIsProcessFormCode As Boolean = True
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.mIsProcessFormCode = True
End Sub
Public Sub New(ByVal IsProcessFormCode As Boolean)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.mIsProcessFormCode = IsProcessFormCode
End Sub
End Class
然后在 frmMain 上添加以下代码:
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Debug.Print("routine={0}", System.Reflection.MethodBase.GetCurrentMethod.Name)
Dim frm As New frmAlert(False) 'create an instance of the form without any of the Form processes
frm.Opacity = 0 'makes the form totally transparent
frm.Visible = False
frm.Show()
Dim frmWidth As Integer = frm.Width
Dim frHeight As Integer = frm.Height
Dim frCsWidth As Integer = frm.ClientSize.Width
Dim frCsHeight As Integer = frm.ClientSize.Height
frm.Close()
frm.Dispose()
Debug.Print("frmWidth={0} frHeight={1} frCsWidth={2} frCsHeight={3}", frmWidth, frHeight, frCsWidth, frCsHeight)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Debug.Print("routine={0}", System.Reflection.MethodBase.GetCurrentMethod.Name)
'set up the alert form normally
Dim frm As New frmAlert
'show the alert form
frm.StartPosition = FormStartPosition.CenterParent
frm.Show() 'with this option the Alert Forms stay on the screen even if the Main form is minimized.
End Sub
并在 frmAlert 中添加以下代码:
Private Sub frmAlert_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
Try
'process the form code ONLY if required
Debug.Print("routine={0} mIsProcessFormCode={1}", System.Reflection.MethodBase.GetCurrentMethod.Name, mIsProcessFormCode)
If mIsProcessFormCode Then
'do Closed stuff
End If
Catch ex As Exception
Debug.Print(ex.ToString)
End Try
End Sub
Private Sub frmAlert_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
Try
'process the form code ONLY if required
Debug.Print("routine={0} mIsProcessFormCode={1}", System.Reflection.MethodBase.GetCurrentMethod.Name, mIsProcessFormCode)
If mIsProcessFormCode Then
'do Closing stuff
End If
Catch ex As Exception
Debug.Print(ex.ToString)
End Try
End Sub
Private Sub frmAlert_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
'process the form code ONLY if required
Debug.Print("routine={0} mIsProcessFormCode={1}", System.Reflection.MethodBase.GetCurrentMethod.Name, mIsProcessFormCode)
Debug.Print("me.width={0} me.height={1} cs.width={2} cs.height={3}", Me.Width, Me.Height, Me.ClientSize.Width, Me.ClientSize.Height)
If mIsProcessFormCode Then
'process text file
End If
Catch ex As Exception
Debug.Print(ex.ToString)
End Try
End Sub
和调试输出:
routine=frmMain_Load
routine=frmAlert_Load mIsProcessFormCode=False
me.width=390 me.height=200 cs.width=374 cs.height=162
routine=frmAlert_FormClosing mIsProcessFormCode=False
routine=frmAlert_FormClosed mIsProcessFormCode=False
frmWidth=390 frHeight=200 frCsWidth=374 frCsHeight=162
routine=Button1_Click
routine=frmAlert_Load mIsProcessFormCode=True
me.width=390 me.height=200 cs.width=374 cs.height=162
我相信这就是我想要的。所有 frmAlert 大小都与我在 IDE 设计器中的大小相匹配。如果您能想到任何修改,请告诉我。非常感谢。
VB2012:为了在主窗体中进行一些计算,我需要知道辅助窗体的窗体大小。表单大小可能因用户而异,具体取决于 OS 和主题。我了解客户规模保持不变。但是我认为我没有做正确的事情,因为根据我要求表格大小的位置,我得到了不同的数字。
作为示例,这里是我的主窗体,在加载事件中我尝试获取警报窗体的大小
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'get the default width and height of an Alert form.
Dim frmW As Integer = frmAlert.Width 'in pixels
Dim frmH As Integer = frmAlert.Height 'in pixels
Dim frCsW As Integer = frmAlert.ClientSize.Width 'in pixels
Dim frmCsH As Integer = frmAlert.ClientSize.Height 'in pixels
Debug.Print("frmW={0} frmH={1} frCsW={2} frmCsH={3}", frmW, frmH, frCsW, frmCsH)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'set up a new alert form
Dim frm As New frmAlert
'show the alert form
frm.StartPosition = FormStartPosition.CenterParent
frm.Show() 'with this option the Alert Forms stay on the screen even if the Main form is minimized.
End Sub
现在警报表单设置为 FormBorderStyle=FixedDialog、ControlBox=False、MaximizeBox=False 和 MinimizeBox=False,在警报表单中我在加载事件中有这个:
Private Sub frmAlert_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Debug.Print("me.width={0} me.height={1} cs.width={2} cs.height={3}", Me.Width, Me.Height, Me.ClientSize.Width, Me.ClientSize.Height)
End Sub
这是调试输出
frmW=380 frmH=168 frCsW=374 frmCsH=162
me.width=390 me.height=200 cs.width=374 cs.height=162
正如预期的那样,客户端大小相同,但总表单大小不同。我正在努力思考 .Height 和 .Width 的差异。不存在其他代码来更改表单属性。第二个调试语句与 IDE 设计器中的窗体大小相匹配。为什么尺寸不同?我将如何正确查询以从另一个表单获取表单大小?
在表单显示之前,它的大小会比显示时小。这是因为当您显示表单时 Windows 会根据用户的屏幕和主题设置对其执行各种操作,例如:
- 如果用户有不同的 DPI 设置,请调整它的大小。
- 根据用户选择的 window 主题为其应用边框。
- (等等)
最好的办法是先显示表单,然后获取其大小。
如果您不希望表单立即可见,您可以将其 Opacity
property 设置为 0 使其不可见,然后在您需要将表单显示给用户。
好的,所以根据@Visual Vincent 的建议,我在创建新表单时创建了一个构造函数。这进入 frmAlert.Designer.vb
Partial Class frmAlert
Private mIsProcessFormCode As Boolean = True
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.mIsProcessFormCode = True
End Sub
Public Sub New(ByVal IsProcessFormCode As Boolean)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.mIsProcessFormCode = IsProcessFormCode
End Sub
End Class
然后在 frmMain 上添加以下代码:
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Debug.Print("routine={0}", System.Reflection.MethodBase.GetCurrentMethod.Name)
Dim frm As New frmAlert(False) 'create an instance of the form without any of the Form processes
frm.Opacity = 0 'makes the form totally transparent
frm.Visible = False
frm.Show()
Dim frmWidth As Integer = frm.Width
Dim frHeight As Integer = frm.Height
Dim frCsWidth As Integer = frm.ClientSize.Width
Dim frCsHeight As Integer = frm.ClientSize.Height
frm.Close()
frm.Dispose()
Debug.Print("frmWidth={0} frHeight={1} frCsWidth={2} frCsHeight={3}", frmWidth, frHeight, frCsWidth, frCsHeight)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Debug.Print("routine={0}", System.Reflection.MethodBase.GetCurrentMethod.Name)
'set up the alert form normally
Dim frm As New frmAlert
'show the alert form
frm.StartPosition = FormStartPosition.CenterParent
frm.Show() 'with this option the Alert Forms stay on the screen even if the Main form is minimized.
End Sub
并在 frmAlert 中添加以下代码:
Private Sub frmAlert_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
Try
'process the form code ONLY if required
Debug.Print("routine={0} mIsProcessFormCode={1}", System.Reflection.MethodBase.GetCurrentMethod.Name, mIsProcessFormCode)
If mIsProcessFormCode Then
'do Closed stuff
End If
Catch ex As Exception
Debug.Print(ex.ToString)
End Try
End Sub
Private Sub frmAlert_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
Try
'process the form code ONLY if required
Debug.Print("routine={0} mIsProcessFormCode={1}", System.Reflection.MethodBase.GetCurrentMethod.Name, mIsProcessFormCode)
If mIsProcessFormCode Then
'do Closing stuff
End If
Catch ex As Exception
Debug.Print(ex.ToString)
End Try
End Sub
Private Sub frmAlert_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
'process the form code ONLY if required
Debug.Print("routine={0} mIsProcessFormCode={1}", System.Reflection.MethodBase.GetCurrentMethod.Name, mIsProcessFormCode)
Debug.Print("me.width={0} me.height={1} cs.width={2} cs.height={3}", Me.Width, Me.Height, Me.ClientSize.Width, Me.ClientSize.Height)
If mIsProcessFormCode Then
'process text file
End If
Catch ex As Exception
Debug.Print(ex.ToString)
End Try
End Sub
和调试输出:
routine=frmMain_Load
routine=frmAlert_Load mIsProcessFormCode=False
me.width=390 me.height=200 cs.width=374 cs.height=162
routine=frmAlert_FormClosing mIsProcessFormCode=False
routine=frmAlert_FormClosed mIsProcessFormCode=False
frmWidth=390 frHeight=200 frCsWidth=374 frCsHeight=162
routine=Button1_Click
routine=frmAlert_Load mIsProcessFormCode=True
me.width=390 me.height=200 cs.width=374 cs.height=162
我相信这就是我想要的。所有 frmAlert 大小都与我在 IDE 设计器中的大小相匹配。如果您能想到任何修改,请告诉我。非常感谢。