wince5.0子类化的疑问

fatesy   2011-7-15 23:24 楼主

  1. Public Class ContextMenuHelper
    #Region "事件"
    Public Event ButtonDbClick(ByVal SubControl As Control, ByVal e As MouseEventArgs)
    Public Event ButtonClick(ByVal SubControl As Control, ByVal e As MouseEventArgs)
    #End Region
    Public Sub HookAllControls(ByVal ControlList As List(Of Control))
    For Each ThisControl As Control In ControlList
    If Not ThisControl.ContextMenu Is Nothing Then
    Dim CustomMessageWindow As New CustomMessageWindow(ThisControl)
    AddHandler CustomMessageWindow.ButtonDbClick, AddressOf ButtonDbClickPro
    AddHandler CustomMessageWindow.ButtonClick, AddressOf ButtonClickPro
    End If
    Next
    End Sub
    Public Sub ButtonDbClickPro(ByVal SubControl As Control, ByVal e As MouseEventArgs)
    RaiseEvent ButtonDbClick(SubControl, e)
    End Sub
    Public Sub ButtonClickPro(ByVal SubControl As Control, ByVal e As MouseEventArgs)
    RaiseEvent ButtonClick(SubControl, e)
    End Sub
    End Class

  1.  

  1. Public Class CustomMessageWindow : Implements IDisposable
    #Region "API"
    <DllImport("coredll.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
    Private Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal NewProc As Win32WndProc) As IntPtr
    End Function
    <DllImport("coredll.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
    Private Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal newProc As IntPtr) As IntPtr
    End Function
    <DllImport("coredll.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
    Private Shared Function CallWindowProc(ByVal lpPrevWndFunc As IntPtr, ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    End Function
    #End Region
    #Region "私有变量"
    Private Delegate Function Win32WndProc(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    Private OldWndProc As IntPtr
    Private NewWndProc As Win32WndProc = Nothing
    Public SubControl As Control
    #End Region
    #Region "常量"
    Private Const GWL_WNDPROC As Integer = -4
    Private Const WM_LBUTTONDOWN As Integer = &H201
    Private Const WM_LBUTTONDBLCLK As Integer = &H203
    #End Region
    #Region "事件"
    Public Event ButtonDbClick(ByVal SubControl As Control, ByVal e As MouseEventArgs)
    Public Event ButtonClick(ByVal SubControl As Control, ByVal e As MouseEventArgs)
    #End Region
    Public Sub New(ByVal NewSubControl As Control)
    SubControl = NewSubControl
    NewWndProc = New Win32WndProc(AddressOf MyWndProc)
    OldWndProc = SetWindowLong(NewSubControl.Handle, GWL_WNDPROC, NewWndProc)
    End Sub
    Private Function MyWndProc(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    Select Case Msg
    Case WM_LBUTTONDOWN
    Dim X As Integer, Y As Integer
    LoWord(X, Y, lParam)
    RaiseEvent ButtonClick(SubControl, New MouseEventArgs(MouseButtons.Left, 0, X, Y, 0))
    Return 1
    Case WM_LBUTTONDBLCLK
    Dim X As Integer, Y As Integer
    LoWord(X, Y, lParam)
    RaiseEvent ButtonDbClick(SubControl, New MouseEventArgs(MouseButtons.Left, 0, X, Y, 0))
    Return 1
    Case Else
    Return CallWindowProc(OldWndProc, hWnd, Msg, wParam, lParam)
    End Select
    End Function
    Public Sub LoWord(ByRef X As Integer, ByRef Y As Integer, ByVal lParam As Integer)
    X = lParam And &HFFFF
    Y = (lParam And &HFFFF0000) >> 16
    End Sub
    #Region " IDisposable Support "
    Private disposedValue As Boolean = False
    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
    If Not Me.disposedValue Then
    If disposing Then
    End If
    SetWindowLong(SubControl.Handle, GWL_WNDPROC, OldWndProc)
    End If
    Me.disposedValue = True
    End Sub
    Public Sub Dispose() Implements IDisposable.Dispose
    Dispose(True)
    GC.SuppressFinalize(Me)
    End Sub
    #End Region

    End Class

为了完善wince5.0系统下控件右键菜单contextmenu的弹出问题,我制作了如上两个类

功能倒是实现了,但同时麻烦也出现了,问题是:经常弹出系统错误,并直接挂掉我的程序。具体原因小弟我已经弄明白:就是子类化中CallWindowProc函数回调窗口原消息处理函数中参数不严密导致的内存读写错误

这里想众大虾求救了请问:有在wince5.0下安全可靠的子类化方法或者现成的代码吗?

回复评论 (1)

实现自我救赎,可以结贴了!
点赞  2011-7-16 08:52
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复