溢出检查确实妨碍了这里。解决这个问题的最好方法是声明一个union。联合是具有重叠值的结构。它优雅地允许您将 IntPtr 覆盖在具有 Short 类型的结构成员之上。转换速度极快,不会抛出溢出异常。
将一个新模块添加到您的项目中,将其命名为 NativeMethods 并使其如下所示:
Imports System.Runtime.InteropServices
Imports System.Drawing
Module NativeMethods
<StructLayout(LayoutKind.Explicit)> _
Public Structure LParamMap
Public Sub New(value As IntPtr)
lparam = value
End Sub
Public Shared Widening Operator CType(value As LParamMap) As Point
Return New Point(value.loword, value.hiword)
End Operator
<FieldOffset(0)> Public lparam As IntPtr
<FieldOffset(0)> Public loword As Short
<FieldOffset(2)> Public hiword As Short
End Structure
End Module
我为 Point 添加了一个转换运算符,因为那是您真正想要的。一些执行此操作的测试代码:
Imports System.Drawing
Imports System.Diagnostics
Module Module1
Sub Main()
Debug.Assert(BitConverter.IsLittleEndian)
Dim test As New LParamMap(New IntPtr(-1))
Debug.Assert(test.loword = -1)
Debug.Assert(test.hiword = -1)
Dim pos As Point = test
Debug.Assert(pos = New Point(-1, -1))
End Sub
End Module
它现在变成了一个非常简单的单行代码,例如覆盖表单的 WndProc() 方法:
Protected Overrides Sub WndProc(ByRef m As Windows.Forms.Message)
If m.Msg = &H200 Then
Dim pos As Point = New LParamMap(m.LParam)
'' etc...
End If
MyBase.WndProc(m)
End Sub