【VB.NET】在Vista之后的操作系统中获取窗体的正确坐标(忽略阴影)
我们可以使用系统API
然而在最新的操作系统中(Vista之后),通过
如果你不想计算阴影部分,仅仅想获得窗体自身的坐标,就必须要使用
代码如下:
参考来源
https://stackoverflow.com/questions/38685405/dwmgetwindowattribute-returns-0-with-pinvoke
GetWindowRect
,通过窗体句柄来获取指定窗体位于屏幕中的位置及大小。然而在最新的操作系统中(Vista之后),通过
GetWindowRect
获取的窗体范围数据,其实是包含窗体阴影部分的,因此其数据并不准确,如果涉及窗体坐标操控的话,会导致窗体偏移,无法移动到正确的位置。如果你不想计算阴影部分,仅仅想获得窗体自身的坐标,就必须要使用
DwmGetWindowAttribute
这个新的API来达成目的。代码如下:
Declare Function GetWindowRect Lib "user32.dll" (ByVal hwnd As IntPtr, ByRef lpRect As Rect) As Boolean
Declare Function DwmGetWindowAttribute Lib "dwmapi.dll" (ByVal hwnd As IntPtr, ByVal dwAttribute As Integer, ByRef pvAttribute As Rect, ByVal cbAttribute As Integer) As Integer
<Flags()> Public Enum DwmWindowAttribute As UInteger
DWMWA_NCRENDERING_ENABLED = 1
DWMWA_NCRENDERING_POLICY
DWMWA_TRANSITIONS_FORCEDISABLED
DWMWA_ALLOW_NCPAINT
DWMWA_CAPTION_BUTTON_BOUNDS
DWMWA_NONCLIENT_RTL_LAYOUT
DWMWA_FORCE_ICONIC_REPRESENTATION
DWMWA_FLIP3D_POLICY
DWMWA_EXTENDED_FRAME_BOUNDS
DWMWA_HAS_ICONIC_BITMAP
DWMWA_DISALLOW_PEEK
DWMWA_EXCLUDED_FROM_PEEK
DWMWA_CLOAK
DWMWA_CLOAKED
DWMWA_FREEZE_REPRESENTATION
DWMWA_LAST
End Enum
<Serializable(), StructLayout(LayoutKind.Sequential)> Public Structure Rect
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
Public Function ToRectangle() As Rectangle
Return Rectangle.FromLTRB(Left, Top, Right, Bottom)
End Function
End Structure
Public Shared Function GetWindowRectangle(ByVal handle As IntPtr) As Rectangle
Dim rect As New Rect()
If Environment.OSVersion.Version.Major >= 6 Then
Dim size As Integer = Marshal.SizeOf(GetType(Rect))
DwmGetWindowAttribute(handle, DwmWindowAttribute.DWMWA_EXTENDED_FRAME_BOUNDS, rect, size)
End If
If Environment.OSVersion.Version.Major < 6 OrElse rect.ToRectangle().Width = 0 Then
GetWindowRect(handle, rect)
End If
Return rect.ToRectangle()
End Function
Environment.OSVersion.Version.Major
用于判断操作系统版本,低于Vista的系统是没有 DwmGetWindowAttribute
这个API的,可以直接用 GetWindowRect
获取窗体坐标数据。参考来源
https://stackoverflow.com/questions/38685405/dwmgetwindowattribute-returns-0-with-pinvoke
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。