2013-12-12 70 views
0

在i接收的WndProc一個WM_MOUSEMOVE消息的lParam包含光標座標。我這個參數轉化爲Point結構:WM_MOUSEMOVE Lparam型低位溢出

Friend Shared Function LParamToPoint(ByVal lParam As IntPtr) As Point 
    Return New Point(LOWORD(lParam.ToInt32()), HIWORD(lParam.ToInt32())) 
End Function 

Friend Shared Function HIWORD(ByVal value As Integer) As Short 
    Return CShort((value >> 16)) 
End Function 

Friend Shared Function LOWORD(ByVal value As Integer) As Short 
    Return CShort((value And UShort.MaxValue)) 
End Function 

我的問題是光標當x座標爲負的LOWORD函數失敗溢出異常。根據MSDN,您應該使用GET_X_LPARAMGET_Y_LPARAM宏而不是HI/LO WORD宏。但是在vb.net中沒有這樣的函數可用。

那該怎麼辦?

回答

1

溢出檢查真的在這裏的方式。解決此問題的最佳方法是聲明工會。聯合是具有重疊值的結構。它優雅地允許您覆蓋類型爲Short的結構成員之上的IntPtr。轉換爲極其速度快,不能拋出溢出異常。

添加新模塊到您的項目,將其命名爲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 

我在一個轉換操作符傳出了點,因爲這是你真正想要的。一些測試代碼行使此項:

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 
+0

這方式比更優雅我做法。非常感謝! –