- 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
复制代码
- 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下安全可靠的子类化方法或者现成的代码吗?
|