Vb.net 从另一个窗体确定窗体大小

Vb.net 从另一个窗体确定窗体大小,vb.net,forms,size,nonclient-area,Vb.net,Forms,Size,Nonclient Area,VB2012:为了在主窗体中进行一些计算,我需要知道辅助窗体的窗体大小。表单大小可能因用户而异,具体取决于操作系统和主题。我知道客户规模保持不变。然而,我认为我没有做正确的事情,因为我得到了不同的数字,这取决于我对表格大小的要求 作为说明,这里是我的主窗体,在加载事件时,我尝试获取警报窗体的大小 Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load 'get the default w

VB2012:为了在主窗体中进行一些计算,我需要知道辅助窗体的窗体大小。表单大小可能因用户而异,具体取决于操作系统和主题。我知道客户规模保持不变。然而,我认为我没有做正确的事情,因为我得到了不同的数字,这取决于我对表格大小的要求

作为说明,这里是我的主窗体,在加载事件时,我尝试获取警报窗体的大小

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

正如预期的那样,客户端大小相同,但总表单大小不同。我正试图把我的头绕在.高度和.宽度的差异上。没有其他代码可用于更改表单属性。第二条调试语句与IDE设计器中的表单大小匹配。为什么尺寸不同?如何正确查询以从另一个窗体获取窗体大小?

在显示窗体之前,它的大小将比显示时小。这是因为当您显示表单时,Windows将根据用户的屏幕和主题设置对其执行各种操作,例如:

  • 如果用户具有不同的DPI设置,请调整其大小
  • 根据用户选择的窗口主题对其应用边框
  • (等等)
最好的办法是先显示表单,然后确定其大小


如果您不希望表单立即可见,可以将其设置为0以使其不可见,然后在需要向用户显示表单时将其更改回1.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
然后在FRM上添加以下代码:

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
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
在frmAlert中,我添加了以下代码:

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
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设计器中的大小匹配。如果你能想到任何修改,请让我知道。非常感谢。

我的猜测是,由于打印第一行时表单尚未显示,Windows尚未向其添加边框。客户端大小保持不变,但当显示窗口并添加边框时,总大小会增加,从而得到第二个结果。这很有意义。现在我如何确定正确的尺寸?我正在尝试使用SystemInformation.FixedFrameBorderSize等,但即使这样,我也没有得到相同的答案you@Zeddy:好:)。FWIW如果你想发布一张图片,你可以通过答案编辑器上传它,然后将链接复制到评论中。这看起来可能是默认的表单实例问题。在
frmMain\u Load
中引用
frmAlert
(可能的默认实例),并在
按钮1中单击
显式创建它
Dim frm作为新的frmAlert