突然想設計一個能在RunTime時,改變控件大小和位置的功能,而且要求儘量純.NET而不用Win32的鉤子。最重要的是對一般的界面設計透明,不要過多地影響普通界面設計的過程。 初步想法是,用一個類來處理一個Control,在變成設計態時,先保存現在的Mouse和Key的處理函數,並取消他們,然後用我們自己的Mouse和Key句柄替代原來的消息處理。在退出設計態時再恢復原來消息處理函數。
取消和添加消息處理有AddHandler 和 RemoveHandler ,但找了半天沒有發現能獲取當前控件消息函數的功能,於是Google了半天,東拼西湊了一些資料得到了下面的代碼。如哪位有更好的辦法,還請不吝賜教
Public Function GetEventSubscribers(ByVal target As Object, ByVal eventName As String) As [Delegate]()
Dim WinFormsEventName As String = ("Event" & eventName)
Dim t As Type = target.GetType
Do
Dim fia As FieldInfo() = t.GetFields((BindingFlags.NonPublic Or (BindingFlags.Static Or BindingFlags.Instance)))
Dim fi As FieldInfo
For Each fi In fia
Dim d As [Delegate]
'Debug.WriteLine(fi.Name)
If (fi.Name = eventName) Then
d = CType(fi.GetValue(target), [Delegate])
If (Not d Is Nothing) Then
Return d.GetInvocationList
End If
End If
If (fi.Name = WinFormsEventName) Then
Dim ehl As EventHandlerList = DirectCast(target.GetType.GetProperty("Events", (BindingFlags.FlattenHierarchy Or (BindingFlags.NonPublic Or BindingFlags.Instance))).GetValue(target, Nothing), EventHandlerList)
d = ehl.Item(fi.GetValue(target))
If (Not d Is Nothing) Then
Return d.GetInvocationList
End If
End If
Next
t = t.BaseType
Loop While (Not t Is Nothing)
Return New [Delegate](0 - 1) {}
End Function
Dim WinFormsEventName As String = ("Event" & eventName)
Dim t As Type = target.GetType
Do
Dim fia As FieldInfo() = t.GetFields((BindingFlags.NonPublic Or (BindingFlags.Static Or BindingFlags.Instance)))
Dim fi As FieldInfo
For Each fi In fia
Dim d As [Delegate]
'Debug.WriteLine(fi.Name)
If (fi.Name = eventName) Then
d = CType(fi.GetValue(target), [Delegate])
If (Not d Is Nothing) Then
Return d.GetInvocationList
End If
End If
If (fi.Name = WinFormsEventName) Then
Dim ehl As EventHandlerList = DirectCast(target.GetType.GetProperty("Events", (BindingFlags.FlattenHierarchy Or (BindingFlags.NonPublic Or BindingFlags.Instance))).GetValue(target, Nothing), EventHandlerList)
d = ehl.Item(fi.GetValue(target))
If (Not d Is Nothing) Then
Return d.GetInvocationList
End If
End If
Next
t = t.BaseType
Loop While (Not t Is Nothing)
Return New [Delegate](0 - 1) {}
End Function