为 COMPILED 应用程序激活 Aero 时,如何使用 VBNET 或 C# 代码正确确定非客户区大小?(是的,这个问题只发生在运行编译的应用程序时,而不是从 IDE 启动应用程序时)
当我调整表单大小或执行与表单的高度/宽度相关的任何操作时,我永远不会得到预期的结果。
例如这是一个简单的两种形式的对接代码的一部分:
VB-NET:
Me.Location = New Point((form1.Location.X + form1.Width), form1.Location.Y)
C#:
this.Location = new Point((form1.Location.X + form1.Width), form1.Location.Y);
举个例子,我将展示我的一个程序。
上面的代码在 Aero 未激活时运行完美:
...但是如果 Aero 被激活,那么结果如下:
请注意右侧的表单如何位于左侧表单的非客户端边框下方。
...或者这是左侧表单位于右侧表单的非客户端边框下方的其他图像:
我的问题是解决这个问题的方法是什么?
更新:
扩展框架解决方案不起作用。
表格1:
Imports System.Runtime.InteropServices
Public Class Form1
Public Moving_From_Secondary_Form As Boolean = False
<DllImport("dwmapi.dll")> _
Private Shared Function DwmExtendFrameIntoClientArea(ByVal hwnd As IntPtr, ByRef margins As MARGINS) As Integer
End Function
<StructLayout(LayoutKind.Sequential)> _
Public Structure MARGINS
Public leftWidth As Integer
Public rightWidth As Integer
Public topHeight As Integer
Public bottomHeight As Integer
End Structure
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim margins As New MARGINS()
margins.leftWidth = -1
margins.rightWidth = -1
margins.topHeight = -1
margins.bottomHeight = -1
DwmExtendFrameIntoClientArea(Me.Handle, margins)
Form2.Show()
End Sub
Private Sub Form1_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Move
If Not Moving_From_Secondary_Form Then Form2.Location = New Point(Me.Right, Me.Top)
End Sub
End Class
表格2:
Public Class Form2
Private Sub Form2_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Move
Form1.Moving_From_Secondary_Form = True
Form1.Location = New Point(Me.Left - Form1.Width, Me.Top)
Form1.Moving_From_Secondary_Form = False
End Sub
End Class
结果:
另外我想记住: 这个问题只发生在运行编译的应用程序时,而不是从 IDE 启动应用程序时
**
更新:
**
测试了 GetWindowRect 解决方案,总是返回一个 0,对我不起作用,也许我做错了什么:
Imports System.Runtime.InteropServices
Public Class Form1
Private Declare Function GetWindowRect Lib "user32" (ByVal Handle As IntPtr, Rect As RECT) As Long
Private Declare Function CopyRect Lib "user32" (DestRect As RECT, SourceRect As RECT) As Long
<StructLayout(LayoutKind.Sequential)> _
Structure RECT
Public Left As Int32
Public Top As Int32
Public Right As Int32
Public Bottom As Int32
End Structure
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Form2.Show()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim rectWindow As RECT, rectCopy As RECT
'Get the bounding rectangle of this window
GetWindowRect(Me.Handle, rectWindow)
'Copy the rectangle
CopyRect(rectCopy, rectWindow)
MsgBox("This form's width:" & (rectCopy.Right - rectCopy.Left).ToString & " pixels")
Form2.Location = New Point(rectCopy.Right, rectCopy.Top)
End Sub
End Class
**
更新:
**
再次尝试使用 GetWindowRect,这次代码正确编写但没有解决问题:
Imports System.Runtime.InteropServices
Public Class Form1
<StructLayout(LayoutKind.Sequential)> _
Private Structure RECT
Public Left As Int32
Public Top As Int32
Public Right As Int32
Public Bottom As Int32
End Structure
Private Declare Function GetWindowRect Lib "user32" (ByVal HWND As Integer, ByRef lpRect As RECT) As Integer
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim rc As RECT
GetWindowRect(MyBase.Handle, rc)
Dim width As Integer = rc.Right - rc.Left
Form2.Show()
Form2.Location = New Point(rc.Right, rc.Top)
End Sub
End Class
我要记住:这个问题只发生在win7/Vista上运行编译的应用程序时,而不是从IDE启动应用程序时