有关IMessageFilter的文档说明:
IMessageFilter 接口
定义消息筛选器接口。
命名空间: System.Windows.Forms
程序集: System.Windows.Forms(在 System.Windows.Forms.dll 中)
此接口允许应用程序在消息被调度到控件或窗体之前捕获它。
IMessageFilter.PreFilterMessage 方法
使用 PreFilterMessage 在消息被调度到控件或窗体之前将其筛选出来
如果筛选消息并禁止消息被调度,则为 true;如果允许消息继续到达下一个筛选器或控件,则为 false。
可以将实现 IMessageFilter 接口的类添加到应用程序的消息泵中,以在消息被调度到控件或窗体之前将它筛选出来或执行其他操作。若要将消息筛选器添加到应用程序的消息泵中,请使用 Application 类中的 AddMessageFilter 方法;当您不再需要在调度 Windows 消息之前捕获这些消息时,可以使用RemoveMessageFilter方法移除消息筛选器。
代码下载: RAR文件,2005
43 个解决方案
#1
可以不用关心“筛选”两字,只利用PreFilterMessage监视窗体消息,对消息进行分析。
这些消息局限于当前程序域内。
如要获取非当前程序域窗体消息,需要实现有关Windows钩子.
#2
对窗体消息Message,
Dim m As Message
m.HWnd为窗体句柄。
通过
Dim Ctr As Control = Control.FromHandle(m.HWnd)
取得句柄窗体或控件实例。
#3
如果对消息感兴趣,不妨简化一下IMessageFilter的实现过程。
IFilterAction.vb
Namespace LzmTW.MessageFilter
Public Interface IFilterAction
Sub Add()
Sub Remove()
End Interface
End Namespace
FilterAction.vb
Namespace LzmTW.MessageFilter
Friend Class FilterAction
Implements IMessageFilter, IFilterAction
Private Action As MessageFilterAction
Friend Sub New()
End Sub
Friend Sub Add(ByVal action As MessageFilterAction)
Me.Action = action
End Sub
Private Function PreFilterMessage(ByRef m As Message) As Boolean _
Implements System.Windows.Forms.IMessageFilter.PreFilterMessage
Return Me.Action.Invoke(m)
End Function
Public Sub Add() Implements IFilterAction.Add
Application.AddMessageFilter(Me)
End Sub
Public Sub Remove() Implements IFilterAction.Remove
Application.RemoveMessageFilter(Me)
End Sub
Public Shared Function Instance(ByVal acton As MessageFilterAction) As IFilterAction
Dim filter As New FilterAction
filter.Add(acton)
Return filter
End Function
End Class
End Namespace
注意这个类的定义修饰,为Friend.
简单的使用方法:
FilterHelper.vb
Namespace LzmTW.MessageFilter
Public Class FilterHelper
Private Sub New()
End Sub
Public Shared Function Instance(ByVal acton As MessageFilterAction) As IFilterAction
Return FilterAction.Instance(acton)
End Function
End Class
End Namespace
#4
Delegate.vb
Namespace LzmTW.MessageFilter
Public Delegate Function MessageFilterAction(ByVal m As Message) As Boolean
End Namespace
#5
示例一:
Public Class Form1
Private gFilter As LzmTW.MessageFilter.IFilterAction
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If Not gFilter Is Nothing Then Return
gFilter = LzmTW.MessageFilter.FilterHelper.Instance(AddressOf MessageWatcher)
gFilter.Add() '添加到Application并发生作用
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
gFilter.Remove() '从Application中移除
End Sub
Private Function MessageWatcher(ByVal m As Message) As Boolean
Console.WriteLine(m.ToString)
Return False '对消息不筛选。如为Return Ture,那么所有的窗体消息都筛选掉,窗体不作任何反应,"死"了。
End Function
End Class
#6
修改MessageWatcher,当你移动鼠标或按Tab键时,下面会提示出消息所捕获的当前控件(Form也是控件,控件就是窗体).
Private Function MessageWatcher(ByVal m As Message) As Boolean
Dim ctr As Control = Control.FromHandle(m.HWnd)
If ctr Is Nothing Then Return False
Console.WriteLine(ctr.ToString)
Return False
End Function
#7
窗体消息有很多,可以通过m.Msg进行筛选.
Private Const WM_KEYUP As Integer = &H101
Private Const WM_MOUSEHOVER As Integer = &H2A1
Private Function MessageWatcher(ByVal m As Message) As Boolean
Select Case m.Msg
Case WM_KEYUP, WM_MOUSEHOVER
Dim ctr As Control = Control.FromHandle(m.HWnd)
If ctr Is Nothing Then Return False
Console.WriteLine(ctr.ToString)
Case Else
End Select
Return False
End Function
#8
说真的,水兄。这个。不知道你在说什么。我想。你如果可能,最好先说明类的功能,我耐心的读完了帖子。知道你是封装了一个类,简化了实现IMessageFilter的。
#9
整理一下示例一:当移动鼠标或选择控件时,即时显示当前鼠标下面或当前控件的名称
Public Class Form1
Private gFilter As LzmTW.MessageFilter.IFilterAction
Private Const WM_KEYUP As Integer = &H101
Private Const WM_MOUSEHOVER As Integer = &H2A1
Private Function MessageWatcher(ByVal m As Message) As Boolean
Select Case m.Msg
Case WM_KEYUP, WM_MOUSEHOVER
Dim ctr As Control = Control.FromHandle(m.HWnd)
If Not ctr Is Nothing Then Me.Text = "this is " & ctr.Name
Case Else
End Select
Return False
End Function
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
gFilter = LzmTW.MessageFilter.FilterHelper.Instance(AddressOf MessageWatcher)
gFilter.Add()
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) _
Handles Me.FormClosing
gFilter.Remove()
End Sub
End Class
#10
我尝试说明怎么使用这个类,通过这个类可以做点什么.
#11
还有。。。
帖子刚发出来就加了精……
是不是太早了。怎么也要多几个回复后再啊。
帖子刚发出来就加了精……
是不是太早了。怎么也要多几个回复后再啊。
#12
关于加精,是我自己给自己加精。我习惯啦。
加精的理由,对我自己的贴子来说,不在于回复,而在于过程。
这贴子会比较长。
加精的理由,对我自己的贴子来说,不在于回复,而在于过程。
这贴子会比较长。
#13
如果我发个这样的帖子。你会不会一开始就加精呢。所谓执法要公正,流程上。并不能因为你是版主就先加精再把帖子变成精华。当然我不否认你的帖子写的很好。但总有老王卖瓜之嫌。并有执法不公之嫌。
#14
如果你跟我说,你想就某个问题写一个贴子,详细的将你的理解和解决的过程写出来,我肯定的先给你的贴子加精。我也热烈欢迎多多益善。
你以为我总给自己的贴子加精我很开心哪?
至于卖瓜之嫌,不公之嫌,这是你的看法,我不解释。
#15
窗体消息的种类有哪些?
WindowMessage.vb
WindowMessage.vb
Namespace LzmTW.MessageFilter
Public Enum WindowMessage
WM_NULL = &H0
WM_CREATE = &H1
WM_DESTROY = &H2
WM_MOVE = &H3
WM_SIZE = &H5
WM_ACTIVATE = &H6
WM_SETFOCUS = &H7
WM_KILLFOCUS = &H8
WM_ENABLE = &HA
WM_SETREDRAW = &HB
WM_SETTEXT = &HC
WM_GETTEXT = &HD
WM_GETTEXTLENGTH = &HE
WM_PAINT = &HF
WM_CLOSE = &H10
WM_QUERYENDSESSION = &H11
WM_QUIT = &H12
WM_QUERYOPEN = &H13
WM_ERASEBKGND = &H14
WM_SYSCOLORCHANGE = &H15
WM_ENDSESSION = &H16
WM_SHOWWINDOW = &H18
WM_CTLCOLOR = &H19
WM_WININICHANGE = &H1A
WM_DEVMODECHANGE = &H1B
WM_ACTIVATEAPP = &H1C
WM_FONTCHANGE = &H1D
WM_TIMECHANGE = &H1E
WM_CANCELMODE = &H1F
WM_SETCURSOR = &H20
WM_MOUSEACTIVATE = &H21
WM_CHILDACTIVATE = &H22
WM_QUEUESYNC = &H23
WM_GETMINMAXINFO = &H24
WM_PAINTICON = &H26
WM_ICONERASEBKGND = &H27
WM_NEXTDLGCTL = &H28
WM_SPOOLERSTATUS = &H2A
WM_DRAWITEM = &H2B
WM_MEASUREITEM = &H2C
WM_DELETEITEM = &H2D
WM_VKEYTOITEM = &H2E
WM_CHARTOITEM = &H2F
WM_SETFONT = &H30
WM_GETFONT = &H31
WM_SETHOTKEY = &H32
WM_GETHOTKEY = &H33
WM_QUERYDRAGICON = &H37
WM_COMPAREITEM = &H39
WM_GETOBJECT = &H3D
WM_COMPACTING = &H41
WM_COMMNOTIFY = &H44
WM_WINDOWPOSCHANGING = &H46
WM_WINDOWPOSCHANGED = &H47
WM_POWER = &H48
WM_COPYDATA = &H4A
WM_CANCELJOURNAL = &H4B
WM_NOTIFY = &H4E
WM_INPUTLANGCHANGEREQUEST = &H50
WM_INPUTLANGCHANGE = &H51
WM_TCARD = &H52
WM_HELP = &H53
WM_USERCHANGED = &H54
WM_NOTIFYFORMAT = &H55
WM_CONTEXTMENU = &H7B
WM_STYLECHANGING = &H7C
WM_STYLECHANGED = &H7D
WM_DISPLAYCHANGE = &H7E
WM_GETICON = &H7F
WM_SETICON = &H80
WM_NCCREATE = &H81
WM_NCDESTROY = &H82
WM_NCCALCSIZE = &H83
WM_NCHITTEST = &H84
WM_NCPAINT = &H85
WM_NCACTIVATE = &H86
WM_GETDLGCODE = &H87
WM_NCMOUSEMOVE = &HA0
WM_NCLBUTTONDOWN = &HA1
WM_NCLBUTTONUP = &HA2
WM_NCLBUTTONDBLCLK = &HA3
WM_NCRBUTTONDOWN = &HA4
WM_NCRBUTTONUP = &HA5
WM_NCRBUTTONDBLCLK = &HA6
WM_NCMBUTTONDOWN = &HA7
WM_NCMBUTTONUP = &HA8
WM_NCMBUTTONDBLCLK = &HA9
WM_KEYDOWN = &H100
WM_KEYUP = &H101
WM_CHAR = &H102
WM_DEADCHAR = &H103
WM_SYSKEYDOWN = &H104
WM_SYSKEYUP = &H105
WM_SYSCHAR = &H106
WM_SYSDEADCHAR = &H107
WM_KEYLAST = &H108
WM_IME_STARTCOMPOSITION = &H10D
WM_IME_ENDCOMPOSITION = &H10E
WM_IME_COMPOSITION = &H10F
WM_INITDIALOG = &H110
WM_COMMAND = &H111
WM_SYSCOMMAND = &H112
WM_TIMER = &H113
WM_HSCROLL = &H114
WM_VSCROLL = &H115
WM_INITMENU = &H116
WM_INITMENUPOPUP = &H117
WM_MENUSELECT = &H11F
WM_MENUCHAR = &H120
WM_ENTERIDLE = &H121
WM_CTLCOLORMSGBOX = &H132
WM_CTLCOLOREDIT = &H133
WM_CTLCOLORLISTBOX = &H134
WM_CTLCOLORBTN = &H135
WM_CTLCOLORDLG = &H136
WM_CTLCOLORSCROLLBAR = &H137
WM_CTLCOLORSTATIC = &H138
WM_MOUSEMOVE = &H200
WM_LBUTTONDOWN = &H201
WM_LBUTTONUP = &H202
WM_LBUTTONDBLCLK = &H203
WM_RBUTTONDOWN = &H204
WM_RBUTTONUP = &H205
WM_RBUTTONDBLCLK = &H206
WM_MBUTTONDOWN = &H207
WM_MBUTTONUP = &H208
WM_MBUTTONDBLCLK = &H209
WM_MOUSEWHEEL = &H20A
WM_PARENTNOTIFY = &H210
WM_ENTERMENULOOP = &H211
WM_EXITMENULOOP = &H212
WM_NEXTMENU = &H213
WM_SIZING = &H214
WM_CAPTURECHANGED = &H215
WM_MOVING = &H216
WM_POWERBROADCAST = &H218
WM_DEVICECHANGE = &H219
WM_MDICREATE = &H220
WM_MDIDESTROY = &H221
WM_MDIACTIVATE = &H222
WM_MDIRESTORE = &H223
WM_MDINEXT = &H224
WM_MDIMAXIMIZE = &H225
WM_MDITILE = &H226
WM_MDICASCADE = &H227
WM_MDIICONARRANGE = &H228
WM_MDIGETACTIVE = &H229
WM_MDISETMENU = &H230
WM_ENTERSIZEMOVE = &H231
WM_EXITSIZEMOVE = &H232
WM_DROPFILES = &H233
WM_MDIREFRESHMENU = &H234
WM_IME_SETCONTEXT = &H281
WM_IME_NOTIFY = &H282
WM_IME_CONTROL = &H283
WM_IME_COMPOSITIONFULL = &H284
WM_IME_SELECT = &H285
WM_IME_CHAR = &H286
WM_IME_KEYDOWN = &H290
WM_IME_KEYUP = &H291
WM_MOUSEHOVER = &H2A1
WM_MOUSELEAVE = &H2A3
WM_CUT = &H300
WM_COPY = &H301
WM_PASTE = &H302
WM_CLEAR = &H303
WM_UNDO = &H304
WM_RENDERFORMAT = &H305
WM_RENDERALLFORMATS = &H306
WM_DESTROYCLIPBOARD = &H307
WM_DRAWCLIPBOARD = &H308
WM_PAINTCLIPBOARD = &H309
WM_VSCROLLCLIPBOARD = &H30A
WM_SIZECLIPBOARD = &H30B
WM_ASKCBFORMATNAME = &H30C
WM_CHANGECBCHAIN = &H30D
WM_HSCROLLCLIPBOARD = &H30E
WM_QUERYNEWPALETTE = &H30F
WM_PALETTEISCHANGING = &H310
WM_PALETTECHANGED = &H311
WM_HOTKEY = &H312
WM_PRINT = &H317
WM_PRINTCLIENT = &H318
WM_HANDHELDFIRST = &H358
WM_HANDHELDLAST = &H35F
WM_AFXFIRST = &H360
WM_AFXLAST = &H37F
WM_PENWINFIRST = &H380
WM_PENWINLAST = &H38F
End Enum
End Namespace
#16
学习了。
谢谢...
但是用这个封装后的类有什么好处?
在分析下与WinPro的功能差异就更好了
谢谢...
但是用这个封装后的类有什么好处?
在分析下与WinPro的功能差异就更好了
#17
为方便起见
FilterItemBase.vb
Namespace LzmTW.MessageFilter
Public MustInherit Class FilterItemBase
Implements IFilterAction
Private filter As IFilterAction
Protected MustOverride Function Action(ByVal m As Message) As Boolean
Sub New()
filter = FilterAction.Instance(AddressOf Action)
End Sub
Public Sub Add() Implements IFilterAction.Add
filter.Add()
End Sub
Public Sub Remove() Implements IFilterAction.Remove
filter.Remove()
End Sub
End Class
End Namespace
#18
示例二:窗体实例监视类(f.Show过有效)
Public Class FormWatcher
Inherits LzmTW.MessageFilter.FilterItemBase
Private gForms As New List(Of Form)
Public ReadOnly Property Count() As Integer
Get
Return Forms.Length
End Get
End Property
Public ReadOnly Property Forms() As Form()
Get
Check()
Return gForms.ToArray
End Get
End Property
Public Function FindForm(ByVal text As String) As Form()
Dim array As New List(Of Form)
For Each f As Form In Me.Forms
If String.Compare(f.Text, text, True) = 0 Then
array.Add(f)
End If
Next
Return array.ToArray
End Function
Public Function FindForm(ByVal t As Type) As Form()
Dim array As New List(Of Form)
For Each f As Form In Me.Forms
If f.GetType Is t Then
array.Add(f)
End If
Next
Return array.ToArray
End Function
Private Sub Check()
For i As Integer = gForms.Count - 1 To 0 Step -1
Dim f As Form = gForms(i)
If f Is Nothing OrElse f.IsDisposed Then
gForms.Remove(f)
End If
Next
End Sub
Protected Overrides Function Action(ByVal m As System.Windows.Forms.Message) As Boolean
Dim ctr As Control = Control.FromHandle(m.HWnd)
If ctr Is Nothing Then Return False
If Not TypeOf ctr Is Form Then Return False
Dim f As Form = CType(ctr, Form)
If f.IsDisposed Then
If gForms.Contains(f) Then
gForms.Remove(f)
End If
Else
If Not gForms.Contains(f) Then
gForms.Add(f)
End If
End If
Return False
End Function
End Class
#19
使用:
Public Class Form1
Private Watcher As FormWatcher
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Watcher = New FormWatcher
Watcher.Add()
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) _
Handles Me.FormClosing
Watcher.Remove()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim f As New Form
f.Text = "aaaa"
f.Show()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim f As New Form2
f.Show()
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Console.WriteLine(Watcher.Count)
For Each f As Form In Watcher.Forms
Console.WriteLine(f.Text)
Next
End Sub
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
Dim array As Form() = Watcher.FindForm("aaaa")
If array.Length > 0 Then
Console.WriteLine(array(0).Text)
End If
End Sub
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
Dim array As Form() = Watcher.FindForm(GetType(Form2))
If array.Length > 0 Then
Console.WriteLine(array(0).Text)
End If
End Sub
End Class
#20
学
#21
扩充一下示例一,用下面的代码实现如图的效果(菜单用键盘选取时无效)
示例代码:
示例代码:
Public Class Form1
Private WithEvents ControlsWatcher As New LzmTW.MessageFilter.Apply.ControlsWatcher
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ControlsWatcher.Add()
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) _
Handles Me.FormClosing
ControlsWatcher.Remove()
End Sub
Private Sub ControlsWatcher_CurrentControlChanged(ByVal sender As Object, ByVal e As LzmTW.MessageFilter.Apply.CurrentControlChangedEventArgs) _
Handles ControlsWatcher.CurrentControlChanged
If sender Is Nothing Then
Me.ToolStripStatusLabel1.Text = e.ToString
Else
Me.ToolStripStatusLabel1.Text = String.Format("{0}:{1}", CType(sender, Form).Name, e.ToString)
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim f As New Form2
f.Show()
End Sub
End Class
#22
CurrentControlChangedEventArgs.vb
Namespace LzmTW.MessageFilter.Apply
Public Class CurrentControlChangedEventArgs
Inherits EventArgs
Private gControl As Control = Nothing
Private gToolStripItem As ToolStripItem = Nothing
Private gControlType As ControlType
Public ReadOnly Property Control() As Control
Get
Return gControl
End Get
End Property
Public ReadOnly Property ToolStripItem() As ToolStripItem
Get
Return gToolStripItem
End Get
End Property
Public ReadOnly Property ControlType() As ControlType
Get
Return gControlType
End Get
End Property
Friend Sub New(ByVal ctr As Object, ByVal controlType As ControlType)
Select Case controlType
Case controlType.Form, controlType.Control, controlType.ToolStrip
gControl = CType(ctr, Control)
Case controlType.ToolStripItem, controlType.ToolStripSeparator
gToolStripItem = CType(ctr, ToolStripItem)
Case Apply.ControlType.NULL
End Select
gControlType = controlType
End Sub
Public Overrides Function ToString() As String
Select Case ControlType
Case Apply.ControlType.NULL
Return ""
Case ControlType.Form, ControlType.Control, ControlType.ToolStrip
Return Me.Control.ToString
Case ControlType.ToolStripItem, ControlType.ToolStripSeparator
Return Me.ToolStripItem.ToString
End Select
Return ""
End Function
End Class
Public Enum ControlType
Form
Control
ToolStrip
ToolStripItem
ToolStripSeparator
NULL
End Enum
Public Delegate Sub CurrentControlChangedHandler(ByVal sender As Object, ByVal e As CurrentControlChangedEventArgs)
End Namespace
#23
ToolStripList.vb
Namespace LzmTW.MessageFilter.Apply
Public Class ToolStripList
Private Sub New()
End Sub
Public Shared Sub ForEach(ByVal toolStrip As ToolStrip, ByVal action As Action(Of ToolStripItem))
ListToolStripItem(toolStrip, action)
End Sub
Public Shared Sub ForEach(ByVal toolStripItem As ToolStripItem, ByVal action As Action(Of ToolStripItem))
ListToolStripItem(toolStripItem, action)
End Sub
Private Shared Sub ListToolStripItem(ByVal tooStrip As ToolStrip, ByVal action As Action(Of ToolStripItem))
For Each item As ToolStripItem In tooStrip.Items
ListToolStripItem(item, action)
Next
End Sub
Private Shared Sub ListToolStripItem(ByVal toolStripItem As ToolStripItem, ByVal action As Action(Of ToolStripItem))
action.Invoke(toolStripItem)
Dim NextParent As ToolStripDropDownItem = TryCast(toolStripItem, ToolStripDropDownItem)
If Not NextParent Is Nothing AndAlso NextParent.HasDropDownItems Then
For Each item As ToolStripItem In NextParent.DropDownItems
ListToolStripItem(item, action)
Next
End If
End Sub
Public Shared Function FindForm(ByVal item As ToolStripItem) As Form
Dim dropDown As ToolStripItem = item
While dropDown.IsOnDropDown
dropDown = dropDown.OwnerItem
End While
Return dropDown.GetCurrentParent.FindForm
End Function
End Class
End Namespace
#24
ControlsWatcher.Helper.vb
ControlsWatcher.vb
注释中的代码尝试实现菜单键盘选取,效果不大好.
此功能代码结束.
Imports LzmTW.MessageFilter.WindowMessage
Namespace LzmTW.MessageFilter.Apply
Partial Class ControlsWatcher
Private Class Helper
Inherits FilterItemBase
Public Event CurrentControlChanged As CurrentControlChangedHandler
Private current As Control
Protected Overrides Function Action(ByVal m As System.Windows.Forms.Message) As Boolean
Select Case m.Msg
Case WM_MOUSEACTIVATE, WM_MOUSEWHEEL, WM_MOUSEMOVE, WM_MOUSELEAVE, WM_MOUSEHOVER, _
WM_LBUTTONDOWN, WM_LBUTTONDBLCLK, WM_LBUTTONUP, WM_RBUTTONDOWN, WM_RBUTTONDBLCLK, WM_RBUTTONUP, _
WM_KEYDOWN, WM_KEYUP
Dim ctr As Control = Control.FromHandle(m.HWnd)
If Not Object.ReferenceEquals(current, ctr) Then
current = ctr
Dim mType As ControlType
If TypeOf ctr Is Form Then
mType = ControlType.Form
ElseIf TypeOf ctr Is ToolStrip Then
mType = ControlType.ToolStrip
ElseIf TypeOf ctr Is Control Then
mType = ControlType.Control
Else
mType = ControlType.NULL
End If
Me.OnCurrentControlChanged(New CurrentControlChangedEventArgs(current, mType))
End If
Case Else
End Select
Return False
End Function
Private Sub OnCurrentControlChanged(ByVal e As CurrentControlChangedEventArgs)
RaiseEvent CurrentControlChanged(Nothing, e)
End Sub
End Class
End Class
End Namespace
ControlsWatcher.vb
Namespace LzmTW.MessageFilter.Apply
Public Class ControlsWatcher
Implements IFilterAction
Public Event CurrentControlChanged As CurrentControlChangedHandler
Private WithEvents gHelper As New Helper
Private currentForm As Form
Private currentToolStrip As ToolStrip
Public Sub Add() Implements IFilterAction.Add
gHelper.Add()
End Sub
Public Sub Remove() Implements IFilterAction.Remove
gHelper.Remove()
End Sub
Private Sub OnCurrentControlChanged(ByVal e As CurrentControlChangedEventArgs)
RaiseEvent CurrentControlChanged(currentForm, e)
End Sub
Private Sub gHelper_CurrentControlChanged(ByVal sender As Object, ByVal e As CurrentControlChangedEventArgs) _
Handles gHelper.CurrentControlChanged
If e.ControlType = ControlType.NULL Then Return
Dim form As Form = e.Control.FindForm
If Not Object.ReferenceEquals(form, currentForm) Then
currentForm = form
End If
Me.OnCurrentControlChanged(e)
If e.ControlType = ControlType.ToolStrip Then
If Not Object.ReferenceEquals(e.Control, currentToolStrip) Then
If Not currentToolStrip Is Nothing Then
ToolStripList.ForEach(currentToolStrip, AddressOf ToolStripItemRemoveHandler)
End If
currentToolStrip = CType(e.Control, ToolStrip)
ToolStripList.ForEach(currentToolStrip, AddressOf ToolStripItemAddHandler)
End If
End If
End Sub
Private Sub ToolStripItemRemoveHandler(ByVal item As ToolStripItem)
RemoveHandler item.MouseEnter, AddressOf ToolStripItem_MouseEnter
RemoveHandler item.MouseLeave, AddressOf ToolStripItem_MouseLeave
'RemoveHandler item.Paint, AddressOf ToolStripItem_Paint
End Sub
Private Sub ToolStripItemAddHandler(ByVal item As ToolStripItem)
AddHandler item.MouseEnter, AddressOf ToolStripItem_MouseEnter
AddHandler item.MouseLeave, AddressOf ToolStripItem_MouseLeave
'AddHandler item.Paint, AddressOf ToolStripItem_Paint
End Sub
Private Sub ToolStripItem_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs)
currentForm = ToolStripList.FindForm(CType(sender, ToolStripItem))
If TypeOf sender Is ToolStripSeparator Then
OnCurrentControlChanged(New CurrentControlChangedEventArgs(sender, ControlType.ToolStripSeparator))
Else
OnCurrentControlChanged(New CurrentControlChangedEventArgs(sender, ControlType.ToolStripItem))
End If
End Sub
Private Sub ToolStripItem_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs)
OnCurrentControlChanged(New CurrentControlChangedEventArgs(Nothing, ControlType.NULL))
End Sub
'Private currentToolStripItem As ToolStripItem
'Private Sub ToolStripItem_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)
' ToolStripList.ForEach(currentToolStrip, AddressOf FindSelectedItem)
' If TypeOf currentToolStripItem Is ToolStripSeparator Then
' OnCurrentControlChanged(New CurrentControlChangedEventArgs(currentToolStripItem, ControlType.ToolStripSeparator))
' Else
' OnCurrentControlChanged(New CurrentControlChangedEventArgs(currentToolStripItem, ControlType.ToolStripItem))
' End If
'End Sub
'Private Sub FindSelectedItem(ByVal item As ToolStripItem)
' If item.Selected Then currentToolStripItem = item
'End Sub
End Class
End Namespace
注释中的代码尝试实现菜单键盘选取,效果不大好.
此功能代码结束.
#25
比较凌乱。你肯定会整理一次放到自己的blog里的。我回头看你blog.
#26
我也这样想哦
#27
凡是加NameSpace的,就是项目文件,不加的,是示例文件.
后面会打包上传.放在这也算寄存吧,很多代码我是写了就丢.
后面会打包上传.放在这也算寄存吧,很多代码我是写了就丢.
#29
下载了。没有一行注释……
#30
哈,现在很少写注释了.
我只是变量和函数名称上尽量的写清楚.
我只是变量和函数名称上尽量的写清楚.
#31
别的类比如CatchMessage你用不用无所谓
不过如果你曾经看过或用过IMessageFilter的话,应该看得明白是怎么回事.
那些API你不用管它,我只是试用试用的,类中并没有用它们.
不过如果你曾经看过或用过IMessageFilter的话,应该看得明白是怎么回事.
那些API你不用管它,我只是试用试用的,类中并没有用它们.
#32
学习
#33
太棒了,大餐!!!!!!
#34
将里头的代码看懂摸透会用,WinForm开发的相当部分知识也就掌握了.
我也意识的加了一些"不相关"的东西在里头.
希望对你们有所启发.仅供参考.
我也意识的加了一些"不相关"的东西在里头.
希望对你们有所启发.仅供参考.
#35
寄存:
192.168.1.242:8086
“/”应用程序中的服务器错误。
--------------------------------------------------------------------------------
由于目标机器积极拒绝,无法连接。 192.168.1.242:8086
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
异常详细信息: System.Net.Sockets.SocketException: 由于目标机器积极拒绝,无法连接。 192.168.1.242:8086
源错误:
执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息。
堆栈跟踪:
[SocketException (0x274d): 由于目标机器积极拒绝,无法连接。 192.168.1.242:8086]
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +2668969
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +717
CSDN.Community.TopicFileDataCenter.TopicFileComponent.Reply(ReplyGenerateData rgd) +0
CSDN.Community.TopicFileDataCenter.TopicFileDataCenterEntry.Reply(Guid topicId, DateTime createDate, ReplyInfo reply, CommunityUser user, UserSectionProfile usp) +73
CSDN.Community.PointForum.Services.ReplyTopicManager.ReplyTopic(ReplyInfo reply, DateTime topicPostDate, String& errorInfo, CommunityUser user, UserSectionProfile usp) +747
CSDN.Community.PointForum.WebControls.ReplyTopicPage.bt_Submit_Click(Object sender, EventArgs e) +604
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +105
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +107
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1746
192.168.1.242:8086
“/”应用程序中的服务器错误。
--------------------------------------------------------------------------------
由于目标机器积极拒绝,无法连接。 192.168.1.242:8086
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
异常详细信息: System.Net.Sockets.SocketException: 由于目标机器积极拒绝,无法连接。 192.168.1.242:8086
源错误:
执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息。
堆栈跟踪:
[SocketException (0x274d): 由于目标机器积极拒绝,无法连接。 192.168.1.242:8086]
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +2668969
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +717
CSDN.Community.TopicFileDataCenter.TopicFileComponent.Reply(ReplyGenerateData rgd) +0
CSDN.Community.TopicFileDataCenter.TopicFileDataCenterEntry.Reply(Guid topicId, DateTime createDate, ReplyInfo reply, CommunityUser user, UserSectionProfile usp) +73
CSDN.Community.PointForum.Services.ReplyTopicManager.ReplyTopic(ReplyInfo reply, DateTime topicPostDate, String& errorInfo, CommunityUser user, UserSectionProfile usp) +747
CSDN.Community.PointForum.WebControls.ReplyTopicPage.bt_Submit_Click(Object sender, EventArgs e) +604
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +105
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +107
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1746
#36
很厉害!佩服了
#37
弱弱的mark一下
#38
我也想知道,正在找這方面的資料~~~~~
#39
test
#40
test
#41
虽然时间有点跨度,但知识没有变。
#42
我是知道了用ImessageFilter之后才看到这个帖子的。
可惜我在c#,你在vb.net
是不是.net搞的语言太多了,高手集中不起来。所以很多时候问不到答案?
可惜我在c#,你在vb.net
是不是.net搞的语言太多了,高手集中不起来。所以很多时候问不到答案?
#43
lzmtw 兄,我遇到一个问题,就是不能筛选到窗体失效或者激活的消息。不知道是不是我的代码有误?请你帮我看一下。
这是窗体测试代码
Public Class Class1
Implements IMessageFilter
Private Const WM_MOVE As Long = &H3
'窗体失效
Private Const WM_ACTIVATE As Int32 = &H6
Private Const WA_INACTIVE As Int32 = 0
Private Const WM_ACTIVATEAPP As Int32 = &H1C
Private Const WM_NCACTIVATE As Int32 = &H86
Private Const WM_KILLFOCUS As Int32 = &H8
Private Const WM_SETFOCUS As Int32 = &H7
Private Const WM_LBUTTONDOWN As Integer = &H201
Private Const WM_KEYDOWN As Long = &H100
Private Const WM_KEYUP As Long = &H101
Public Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) As Boolean Implements System.Windows.Forms.IMessageFilter.PreFilterMessage
Select Case m.Msg
Case WM_LBUTTONDOWN
Case WM_KEYDOWN
Case WM_ACTIVATE '激活
Console.WriteLine(m.ToString & "_________________________________")
Case WM_NCACTIVATE
Console.WriteLine(m.ToString & "_________________________________")
Case WM_KILLFOCUS
Console.WriteLine(m.ToString & "_________________________________")
Case WM_SETFOCUS
Console.WriteLine(m.ToString & "_________________________________")
End Select
Return False
End Function
End Class
这是窗体测试代码
Public Class Form1
Dim c As New Class1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Application.AddMessageFilter(c)
End Sub
End Class
#1
可以不用关心“筛选”两字,只利用PreFilterMessage监视窗体消息,对消息进行分析。
这些消息局限于当前程序域内。
如要获取非当前程序域窗体消息,需要实现有关Windows钩子.
#2
对窗体消息Message,
Dim m As Message
m.HWnd为窗体句柄。
通过
Dim Ctr As Control = Control.FromHandle(m.HWnd)
取得句柄窗体或控件实例。
#3
如果对消息感兴趣,不妨简化一下IMessageFilter的实现过程。
IFilterAction.vb
Namespace LzmTW.MessageFilter
Public Interface IFilterAction
Sub Add()
Sub Remove()
End Interface
End Namespace
FilterAction.vb
Namespace LzmTW.MessageFilter
Friend Class FilterAction
Implements IMessageFilter, IFilterAction
Private Action As MessageFilterAction
Friend Sub New()
End Sub
Friend Sub Add(ByVal action As MessageFilterAction)
Me.Action = action
End Sub
Private Function PreFilterMessage(ByRef m As Message) As Boolean _
Implements System.Windows.Forms.IMessageFilter.PreFilterMessage
Return Me.Action.Invoke(m)
End Function
Public Sub Add() Implements IFilterAction.Add
Application.AddMessageFilter(Me)
End Sub
Public Sub Remove() Implements IFilterAction.Remove
Application.RemoveMessageFilter(Me)
End Sub
Public Shared Function Instance(ByVal acton As MessageFilterAction) As IFilterAction
Dim filter As New FilterAction
filter.Add(acton)
Return filter
End Function
End Class
End Namespace
注意这个类的定义修饰,为Friend.
简单的使用方法:
FilterHelper.vb
Namespace LzmTW.MessageFilter
Public Class FilterHelper
Private Sub New()
End Sub
Public Shared Function Instance(ByVal acton As MessageFilterAction) As IFilterAction
Return FilterAction.Instance(acton)
End Function
End Class
End Namespace
#4
Delegate.vb
Namespace LzmTW.MessageFilter
Public Delegate Function MessageFilterAction(ByVal m As Message) As Boolean
End Namespace
#5
示例一:
Public Class Form1
Private gFilter As LzmTW.MessageFilter.IFilterAction
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If Not gFilter Is Nothing Then Return
gFilter = LzmTW.MessageFilter.FilterHelper.Instance(AddressOf MessageWatcher)
gFilter.Add() '添加到Application并发生作用
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
gFilter.Remove() '从Application中移除
End Sub
Private Function MessageWatcher(ByVal m As Message) As Boolean
Console.WriteLine(m.ToString)
Return False '对消息不筛选。如为Return Ture,那么所有的窗体消息都筛选掉,窗体不作任何反应,"死"了。
End Function
End Class
#6
修改MessageWatcher,当你移动鼠标或按Tab键时,下面会提示出消息所捕获的当前控件(Form也是控件,控件就是窗体).
Private Function MessageWatcher(ByVal m As Message) As Boolean
Dim ctr As Control = Control.FromHandle(m.HWnd)
If ctr Is Nothing Then Return False
Console.WriteLine(ctr.ToString)
Return False
End Function
#7
窗体消息有很多,可以通过m.Msg进行筛选.
Private Const WM_KEYUP As Integer = &H101
Private Const WM_MOUSEHOVER As Integer = &H2A1
Private Function MessageWatcher(ByVal m As Message) As Boolean
Select Case m.Msg
Case WM_KEYUP, WM_MOUSEHOVER
Dim ctr As Control = Control.FromHandle(m.HWnd)
If ctr Is Nothing Then Return False
Console.WriteLine(ctr.ToString)
Case Else
End Select
Return False
End Function
#8
说真的,水兄。这个。不知道你在说什么。我想。你如果可能,最好先说明类的功能,我耐心的读完了帖子。知道你是封装了一个类,简化了实现IMessageFilter的。
#9
整理一下示例一:当移动鼠标或选择控件时,即时显示当前鼠标下面或当前控件的名称
Public Class Form1
Private gFilter As LzmTW.MessageFilter.IFilterAction
Private Const WM_KEYUP As Integer = &H101
Private Const WM_MOUSEHOVER As Integer = &H2A1
Private Function MessageWatcher(ByVal m As Message) As Boolean
Select Case m.Msg
Case WM_KEYUP, WM_MOUSEHOVER
Dim ctr As Control = Control.FromHandle(m.HWnd)
If Not ctr Is Nothing Then Me.Text = "this is " & ctr.Name
Case Else
End Select
Return False
End Function
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
gFilter = LzmTW.MessageFilter.FilterHelper.Instance(AddressOf MessageWatcher)
gFilter.Add()
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) _
Handles Me.FormClosing
gFilter.Remove()
End Sub
End Class
#10
我尝试说明怎么使用这个类,通过这个类可以做点什么.
#11
还有。。。
帖子刚发出来就加了精……
是不是太早了。怎么也要多几个回复后再啊。
帖子刚发出来就加了精……
是不是太早了。怎么也要多几个回复后再啊。
#12
关于加精,是我自己给自己加精。我习惯啦。
加精的理由,对我自己的贴子来说,不在于回复,而在于过程。
这贴子会比较长。
加精的理由,对我自己的贴子来说,不在于回复,而在于过程。
这贴子会比较长。
#13
如果我发个这样的帖子。你会不会一开始就加精呢。所谓执法要公正,流程上。并不能因为你是版主就先加精再把帖子变成精华。当然我不否认你的帖子写的很好。但总有老王卖瓜之嫌。并有执法不公之嫌。
#14
如果你跟我说,你想就某个问题写一个贴子,详细的将你的理解和解决的过程写出来,我肯定的先给你的贴子加精。我也热烈欢迎多多益善。
你以为我总给自己的贴子加精我很开心哪?
至于卖瓜之嫌,不公之嫌,这是你的看法,我不解释。
#15
窗体消息的种类有哪些?
WindowMessage.vb
WindowMessage.vb
Namespace LzmTW.MessageFilter
Public Enum WindowMessage
WM_NULL = &H0
WM_CREATE = &H1
WM_DESTROY = &H2
WM_MOVE = &H3
WM_SIZE = &H5
WM_ACTIVATE = &H6
WM_SETFOCUS = &H7
WM_KILLFOCUS = &H8
WM_ENABLE = &HA
WM_SETREDRAW = &HB
WM_SETTEXT = &HC
WM_GETTEXT = &HD
WM_GETTEXTLENGTH = &HE
WM_PAINT = &HF
WM_CLOSE = &H10
WM_QUERYENDSESSION = &H11
WM_QUIT = &H12
WM_QUERYOPEN = &H13
WM_ERASEBKGND = &H14
WM_SYSCOLORCHANGE = &H15
WM_ENDSESSION = &H16
WM_SHOWWINDOW = &H18
WM_CTLCOLOR = &H19
WM_WININICHANGE = &H1A
WM_DEVMODECHANGE = &H1B
WM_ACTIVATEAPP = &H1C
WM_FONTCHANGE = &H1D
WM_TIMECHANGE = &H1E
WM_CANCELMODE = &H1F
WM_SETCURSOR = &H20
WM_MOUSEACTIVATE = &H21
WM_CHILDACTIVATE = &H22
WM_QUEUESYNC = &H23
WM_GETMINMAXINFO = &H24
WM_PAINTICON = &H26
WM_ICONERASEBKGND = &H27
WM_NEXTDLGCTL = &H28
WM_SPOOLERSTATUS = &H2A
WM_DRAWITEM = &H2B
WM_MEASUREITEM = &H2C
WM_DELETEITEM = &H2D
WM_VKEYTOITEM = &H2E
WM_CHARTOITEM = &H2F
WM_SETFONT = &H30
WM_GETFONT = &H31
WM_SETHOTKEY = &H32
WM_GETHOTKEY = &H33
WM_QUERYDRAGICON = &H37
WM_COMPAREITEM = &H39
WM_GETOBJECT = &H3D
WM_COMPACTING = &H41
WM_COMMNOTIFY = &H44
WM_WINDOWPOSCHANGING = &H46
WM_WINDOWPOSCHANGED = &H47
WM_POWER = &H48
WM_COPYDATA = &H4A
WM_CANCELJOURNAL = &H4B
WM_NOTIFY = &H4E
WM_INPUTLANGCHANGEREQUEST = &H50
WM_INPUTLANGCHANGE = &H51
WM_TCARD = &H52
WM_HELP = &H53
WM_USERCHANGED = &H54
WM_NOTIFYFORMAT = &H55
WM_CONTEXTMENU = &H7B
WM_STYLECHANGING = &H7C
WM_STYLECHANGED = &H7D
WM_DISPLAYCHANGE = &H7E
WM_GETICON = &H7F
WM_SETICON = &H80
WM_NCCREATE = &H81
WM_NCDESTROY = &H82
WM_NCCALCSIZE = &H83
WM_NCHITTEST = &H84
WM_NCPAINT = &H85
WM_NCACTIVATE = &H86
WM_GETDLGCODE = &H87
WM_NCMOUSEMOVE = &HA0
WM_NCLBUTTONDOWN = &HA1
WM_NCLBUTTONUP = &HA2
WM_NCLBUTTONDBLCLK = &HA3
WM_NCRBUTTONDOWN = &HA4
WM_NCRBUTTONUP = &HA5
WM_NCRBUTTONDBLCLK = &HA6
WM_NCMBUTTONDOWN = &HA7
WM_NCMBUTTONUP = &HA8
WM_NCMBUTTONDBLCLK = &HA9
WM_KEYDOWN = &H100
WM_KEYUP = &H101
WM_CHAR = &H102
WM_DEADCHAR = &H103
WM_SYSKEYDOWN = &H104
WM_SYSKEYUP = &H105
WM_SYSCHAR = &H106
WM_SYSDEADCHAR = &H107
WM_KEYLAST = &H108
WM_IME_STARTCOMPOSITION = &H10D
WM_IME_ENDCOMPOSITION = &H10E
WM_IME_COMPOSITION = &H10F
WM_INITDIALOG = &H110
WM_COMMAND = &H111
WM_SYSCOMMAND = &H112
WM_TIMER = &H113
WM_HSCROLL = &H114
WM_VSCROLL = &H115
WM_INITMENU = &H116
WM_INITMENUPOPUP = &H117
WM_MENUSELECT = &H11F
WM_MENUCHAR = &H120
WM_ENTERIDLE = &H121
WM_CTLCOLORMSGBOX = &H132
WM_CTLCOLOREDIT = &H133
WM_CTLCOLORLISTBOX = &H134
WM_CTLCOLORBTN = &H135
WM_CTLCOLORDLG = &H136
WM_CTLCOLORSCROLLBAR = &H137
WM_CTLCOLORSTATIC = &H138
WM_MOUSEMOVE = &H200
WM_LBUTTONDOWN = &H201
WM_LBUTTONUP = &H202
WM_LBUTTONDBLCLK = &H203
WM_RBUTTONDOWN = &H204
WM_RBUTTONUP = &H205
WM_RBUTTONDBLCLK = &H206
WM_MBUTTONDOWN = &H207
WM_MBUTTONUP = &H208
WM_MBUTTONDBLCLK = &H209
WM_MOUSEWHEEL = &H20A
WM_PARENTNOTIFY = &H210
WM_ENTERMENULOOP = &H211
WM_EXITMENULOOP = &H212
WM_NEXTMENU = &H213
WM_SIZING = &H214
WM_CAPTURECHANGED = &H215
WM_MOVING = &H216
WM_POWERBROADCAST = &H218
WM_DEVICECHANGE = &H219
WM_MDICREATE = &H220
WM_MDIDESTROY = &H221
WM_MDIACTIVATE = &H222
WM_MDIRESTORE = &H223
WM_MDINEXT = &H224
WM_MDIMAXIMIZE = &H225
WM_MDITILE = &H226
WM_MDICASCADE = &H227
WM_MDIICONARRANGE = &H228
WM_MDIGETACTIVE = &H229
WM_MDISETMENU = &H230
WM_ENTERSIZEMOVE = &H231
WM_EXITSIZEMOVE = &H232
WM_DROPFILES = &H233
WM_MDIREFRESHMENU = &H234
WM_IME_SETCONTEXT = &H281
WM_IME_NOTIFY = &H282
WM_IME_CONTROL = &H283
WM_IME_COMPOSITIONFULL = &H284
WM_IME_SELECT = &H285
WM_IME_CHAR = &H286
WM_IME_KEYDOWN = &H290
WM_IME_KEYUP = &H291
WM_MOUSEHOVER = &H2A1
WM_MOUSELEAVE = &H2A3
WM_CUT = &H300
WM_COPY = &H301
WM_PASTE = &H302
WM_CLEAR = &H303
WM_UNDO = &H304
WM_RENDERFORMAT = &H305
WM_RENDERALLFORMATS = &H306
WM_DESTROYCLIPBOARD = &H307
WM_DRAWCLIPBOARD = &H308
WM_PAINTCLIPBOARD = &H309
WM_VSCROLLCLIPBOARD = &H30A
WM_SIZECLIPBOARD = &H30B
WM_ASKCBFORMATNAME = &H30C
WM_CHANGECBCHAIN = &H30D
WM_HSCROLLCLIPBOARD = &H30E
WM_QUERYNEWPALETTE = &H30F
WM_PALETTEISCHANGING = &H310
WM_PALETTECHANGED = &H311
WM_HOTKEY = &H312
WM_PRINT = &H317
WM_PRINTCLIENT = &H318
WM_HANDHELDFIRST = &H358
WM_HANDHELDLAST = &H35F
WM_AFXFIRST = &H360
WM_AFXLAST = &H37F
WM_PENWINFIRST = &H380
WM_PENWINLAST = &H38F
End Enum
End Namespace
#16
学习了。
谢谢...
但是用这个封装后的类有什么好处?
在分析下与WinPro的功能差异就更好了
谢谢...
但是用这个封装后的类有什么好处?
在分析下与WinPro的功能差异就更好了
#17
为方便起见
FilterItemBase.vb
Namespace LzmTW.MessageFilter
Public MustInherit Class FilterItemBase
Implements IFilterAction
Private filter As IFilterAction
Protected MustOverride Function Action(ByVal m As Message) As Boolean
Sub New()
filter = FilterAction.Instance(AddressOf Action)
End Sub
Public Sub Add() Implements IFilterAction.Add
filter.Add()
End Sub
Public Sub Remove() Implements IFilterAction.Remove
filter.Remove()
End Sub
End Class
End Namespace
#18
示例二:窗体实例监视类(f.Show过有效)
Public Class FormWatcher
Inherits LzmTW.MessageFilter.FilterItemBase
Private gForms As New List(Of Form)
Public ReadOnly Property Count() As Integer
Get
Return Forms.Length
End Get
End Property
Public ReadOnly Property Forms() As Form()
Get
Check()
Return gForms.ToArray
End Get
End Property
Public Function FindForm(ByVal text As String) As Form()
Dim array As New List(Of Form)
For Each f As Form In Me.Forms
If String.Compare(f.Text, text, True) = 0 Then
array.Add(f)
End If
Next
Return array.ToArray
End Function
Public Function FindForm(ByVal t As Type) As Form()
Dim array As New List(Of Form)
For Each f As Form In Me.Forms
If f.GetType Is t Then
array.Add(f)
End If
Next
Return array.ToArray
End Function
Private Sub Check()
For i As Integer = gForms.Count - 1 To 0 Step -1
Dim f As Form = gForms(i)
If f Is Nothing OrElse f.IsDisposed Then
gForms.Remove(f)
End If
Next
End Sub
Protected Overrides Function Action(ByVal m As System.Windows.Forms.Message) As Boolean
Dim ctr As Control = Control.FromHandle(m.HWnd)
If ctr Is Nothing Then Return False
If Not TypeOf ctr Is Form Then Return False
Dim f As Form = CType(ctr, Form)
If f.IsDisposed Then
If gForms.Contains(f) Then
gForms.Remove(f)
End If
Else
If Not gForms.Contains(f) Then
gForms.Add(f)
End If
End If
Return False
End Function
End Class
#19
使用:
Public Class Form1
Private Watcher As FormWatcher
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Watcher = New FormWatcher
Watcher.Add()
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) _
Handles Me.FormClosing
Watcher.Remove()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim f As New Form
f.Text = "aaaa"
f.Show()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim f As New Form2
f.Show()
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Console.WriteLine(Watcher.Count)
For Each f As Form In Watcher.Forms
Console.WriteLine(f.Text)
Next
End Sub
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
Dim array As Form() = Watcher.FindForm("aaaa")
If array.Length > 0 Then
Console.WriteLine(array(0).Text)
End If
End Sub
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
Dim array As Form() = Watcher.FindForm(GetType(Form2))
If array.Length > 0 Then
Console.WriteLine(array(0).Text)
End If
End Sub
End Class
#20
学
#21
扩充一下示例一,用下面的代码实现如图的效果(菜单用键盘选取时无效)
示例代码:
示例代码:
Public Class Form1
Private WithEvents ControlsWatcher As New LzmTW.MessageFilter.Apply.ControlsWatcher
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ControlsWatcher.Add()
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) _
Handles Me.FormClosing
ControlsWatcher.Remove()
End Sub
Private Sub ControlsWatcher_CurrentControlChanged(ByVal sender As Object, ByVal e As LzmTW.MessageFilter.Apply.CurrentControlChangedEventArgs) _
Handles ControlsWatcher.CurrentControlChanged
If sender Is Nothing Then
Me.ToolStripStatusLabel1.Text = e.ToString
Else
Me.ToolStripStatusLabel1.Text = String.Format("{0}:{1}", CType(sender, Form).Name, e.ToString)
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim f As New Form2
f.Show()
End Sub
End Class
#22
CurrentControlChangedEventArgs.vb
Namespace LzmTW.MessageFilter.Apply
Public Class CurrentControlChangedEventArgs
Inherits EventArgs
Private gControl As Control = Nothing
Private gToolStripItem As ToolStripItem = Nothing
Private gControlType As ControlType
Public ReadOnly Property Control() As Control
Get
Return gControl
End Get
End Property
Public ReadOnly Property ToolStripItem() As ToolStripItem
Get
Return gToolStripItem
End Get
End Property
Public ReadOnly Property ControlType() As ControlType
Get
Return gControlType
End Get
End Property
Friend Sub New(ByVal ctr As Object, ByVal controlType As ControlType)
Select Case controlType
Case controlType.Form, controlType.Control, controlType.ToolStrip
gControl = CType(ctr, Control)
Case controlType.ToolStripItem, controlType.ToolStripSeparator
gToolStripItem = CType(ctr, ToolStripItem)
Case Apply.ControlType.NULL
End Select
gControlType = controlType
End Sub
Public Overrides Function ToString() As String
Select Case ControlType
Case Apply.ControlType.NULL
Return ""
Case ControlType.Form, ControlType.Control, ControlType.ToolStrip
Return Me.Control.ToString
Case ControlType.ToolStripItem, ControlType.ToolStripSeparator
Return Me.ToolStripItem.ToString
End Select
Return ""
End Function
End Class
Public Enum ControlType
Form
Control
ToolStrip
ToolStripItem
ToolStripSeparator
NULL
End Enum
Public Delegate Sub CurrentControlChangedHandler(ByVal sender As Object, ByVal e As CurrentControlChangedEventArgs)
End Namespace
#23
ToolStripList.vb
Namespace LzmTW.MessageFilter.Apply
Public Class ToolStripList
Private Sub New()
End Sub
Public Shared Sub ForEach(ByVal toolStrip As ToolStrip, ByVal action As Action(Of ToolStripItem))
ListToolStripItem(toolStrip, action)
End Sub
Public Shared Sub ForEach(ByVal toolStripItem As ToolStripItem, ByVal action As Action(Of ToolStripItem))
ListToolStripItem(toolStripItem, action)
End Sub
Private Shared Sub ListToolStripItem(ByVal tooStrip As ToolStrip, ByVal action As Action(Of ToolStripItem))
For Each item As ToolStripItem In tooStrip.Items
ListToolStripItem(item, action)
Next
End Sub
Private Shared Sub ListToolStripItem(ByVal toolStripItem As ToolStripItem, ByVal action As Action(Of ToolStripItem))
action.Invoke(toolStripItem)
Dim NextParent As ToolStripDropDownItem = TryCast(toolStripItem, ToolStripDropDownItem)
If Not NextParent Is Nothing AndAlso NextParent.HasDropDownItems Then
For Each item As ToolStripItem In NextParent.DropDownItems
ListToolStripItem(item, action)
Next
End If
End Sub
Public Shared Function FindForm(ByVal item As ToolStripItem) As Form
Dim dropDown As ToolStripItem = item
While dropDown.IsOnDropDown
dropDown = dropDown.OwnerItem
End While
Return dropDown.GetCurrentParent.FindForm
End Function
End Class
End Namespace
#24
ControlsWatcher.Helper.vb
ControlsWatcher.vb
注释中的代码尝试实现菜单键盘选取,效果不大好.
此功能代码结束.
Imports LzmTW.MessageFilter.WindowMessage
Namespace LzmTW.MessageFilter.Apply
Partial Class ControlsWatcher
Private Class Helper
Inherits FilterItemBase
Public Event CurrentControlChanged As CurrentControlChangedHandler
Private current As Control
Protected Overrides Function Action(ByVal m As System.Windows.Forms.Message) As Boolean
Select Case m.Msg
Case WM_MOUSEACTIVATE, WM_MOUSEWHEEL, WM_MOUSEMOVE, WM_MOUSELEAVE, WM_MOUSEHOVER, _
WM_LBUTTONDOWN, WM_LBUTTONDBLCLK, WM_LBUTTONUP, WM_RBUTTONDOWN, WM_RBUTTONDBLCLK, WM_RBUTTONUP, _
WM_KEYDOWN, WM_KEYUP
Dim ctr As Control = Control.FromHandle(m.HWnd)
If Not Object.ReferenceEquals(current, ctr) Then
current = ctr
Dim mType As ControlType
If TypeOf ctr Is Form Then
mType = ControlType.Form
ElseIf TypeOf ctr Is ToolStrip Then
mType = ControlType.ToolStrip
ElseIf TypeOf ctr Is Control Then
mType = ControlType.Control
Else
mType = ControlType.NULL
End If
Me.OnCurrentControlChanged(New CurrentControlChangedEventArgs(current, mType))
End If
Case Else
End Select
Return False
End Function
Private Sub OnCurrentControlChanged(ByVal e As CurrentControlChangedEventArgs)
RaiseEvent CurrentControlChanged(Nothing, e)
End Sub
End Class
End Class
End Namespace
ControlsWatcher.vb
Namespace LzmTW.MessageFilter.Apply
Public Class ControlsWatcher
Implements IFilterAction
Public Event CurrentControlChanged As CurrentControlChangedHandler
Private WithEvents gHelper As New Helper
Private currentForm As Form
Private currentToolStrip As ToolStrip
Public Sub Add() Implements IFilterAction.Add
gHelper.Add()
End Sub
Public Sub Remove() Implements IFilterAction.Remove
gHelper.Remove()
End Sub
Private Sub OnCurrentControlChanged(ByVal e As CurrentControlChangedEventArgs)
RaiseEvent CurrentControlChanged(currentForm, e)
End Sub
Private Sub gHelper_CurrentControlChanged(ByVal sender As Object, ByVal e As CurrentControlChangedEventArgs) _
Handles gHelper.CurrentControlChanged
If e.ControlType = ControlType.NULL Then Return
Dim form As Form = e.Control.FindForm
If Not Object.ReferenceEquals(form, currentForm) Then
currentForm = form
End If
Me.OnCurrentControlChanged(e)
If e.ControlType = ControlType.ToolStrip Then
If Not Object.ReferenceEquals(e.Control, currentToolStrip) Then
If Not currentToolStrip Is Nothing Then
ToolStripList.ForEach(currentToolStrip, AddressOf ToolStripItemRemoveHandler)
End If
currentToolStrip = CType(e.Control, ToolStrip)
ToolStripList.ForEach(currentToolStrip, AddressOf ToolStripItemAddHandler)
End If
End If
End Sub
Private Sub ToolStripItemRemoveHandler(ByVal item As ToolStripItem)
RemoveHandler item.MouseEnter, AddressOf ToolStripItem_MouseEnter
RemoveHandler item.MouseLeave, AddressOf ToolStripItem_MouseLeave
'RemoveHandler item.Paint, AddressOf ToolStripItem_Paint
End Sub
Private Sub ToolStripItemAddHandler(ByVal item As ToolStripItem)
AddHandler item.MouseEnter, AddressOf ToolStripItem_MouseEnter
AddHandler item.MouseLeave, AddressOf ToolStripItem_MouseLeave
'AddHandler item.Paint, AddressOf ToolStripItem_Paint
End Sub
Private Sub ToolStripItem_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs)
currentForm = ToolStripList.FindForm(CType(sender, ToolStripItem))
If TypeOf sender Is ToolStripSeparator Then
OnCurrentControlChanged(New CurrentControlChangedEventArgs(sender, ControlType.ToolStripSeparator))
Else
OnCurrentControlChanged(New CurrentControlChangedEventArgs(sender, ControlType.ToolStripItem))
End If
End Sub
Private Sub ToolStripItem_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs)
OnCurrentControlChanged(New CurrentControlChangedEventArgs(Nothing, ControlType.NULL))
End Sub
'Private currentToolStripItem As ToolStripItem
'Private Sub ToolStripItem_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)
' ToolStripList.ForEach(currentToolStrip, AddressOf FindSelectedItem)
' If TypeOf currentToolStripItem Is ToolStripSeparator Then
' OnCurrentControlChanged(New CurrentControlChangedEventArgs(currentToolStripItem, ControlType.ToolStripSeparator))
' Else
' OnCurrentControlChanged(New CurrentControlChangedEventArgs(currentToolStripItem, ControlType.ToolStripItem))
' End If
'End Sub
'Private Sub FindSelectedItem(ByVal item As ToolStripItem)
' If item.Selected Then currentToolStripItem = item
'End Sub
End Class
End Namespace
注释中的代码尝试实现菜单键盘选取,效果不大好.
此功能代码结束.
#25
比较凌乱。你肯定会整理一次放到自己的blog里的。我回头看你blog.
#26
我也这样想哦
#27
凡是加NameSpace的,就是项目文件,不加的,是示例文件.
后面会打包上传.放在这也算寄存吧,很多代码我是写了就丢.
后面会打包上传.放在这也算寄存吧,很多代码我是写了就丢.
#28
#29
下载了。没有一行注释……
#30
哈,现在很少写注释了.
我只是变量和函数名称上尽量的写清楚.
我只是变量和函数名称上尽量的写清楚.
#31
别的类比如CatchMessage你用不用无所谓
不过如果你曾经看过或用过IMessageFilter的话,应该看得明白是怎么回事.
那些API你不用管它,我只是试用试用的,类中并没有用它们.
不过如果你曾经看过或用过IMessageFilter的话,应该看得明白是怎么回事.
那些API你不用管它,我只是试用试用的,类中并没有用它们.
#32
学习
#33
太棒了,大餐!!!!!!
#34
将里头的代码看懂摸透会用,WinForm开发的相当部分知识也就掌握了.
我也意识的加了一些"不相关"的东西在里头.
希望对你们有所启发.仅供参考.
我也意识的加了一些"不相关"的东西在里头.
希望对你们有所启发.仅供参考.
#35
寄存:
192.168.1.242:8086
“/”应用程序中的服务器错误。
--------------------------------------------------------------------------------
由于目标机器积极拒绝,无法连接。 192.168.1.242:8086
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
异常详细信息: System.Net.Sockets.SocketException: 由于目标机器积极拒绝,无法连接。 192.168.1.242:8086
源错误:
执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息。
堆栈跟踪:
[SocketException (0x274d): 由于目标机器积极拒绝,无法连接。 192.168.1.242:8086]
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +2668969
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +717
CSDN.Community.TopicFileDataCenter.TopicFileComponent.Reply(ReplyGenerateData rgd) +0
CSDN.Community.TopicFileDataCenter.TopicFileDataCenterEntry.Reply(Guid topicId, DateTime createDate, ReplyInfo reply, CommunityUser user, UserSectionProfile usp) +73
CSDN.Community.PointForum.Services.ReplyTopicManager.ReplyTopic(ReplyInfo reply, DateTime topicPostDate, String& errorInfo, CommunityUser user, UserSectionProfile usp) +747
CSDN.Community.PointForum.WebControls.ReplyTopicPage.bt_Submit_Click(Object sender, EventArgs e) +604
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +105
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +107
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1746
192.168.1.242:8086
“/”应用程序中的服务器错误。
--------------------------------------------------------------------------------
由于目标机器积极拒绝,无法连接。 192.168.1.242:8086
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
异常详细信息: System.Net.Sockets.SocketException: 由于目标机器积极拒绝,无法连接。 192.168.1.242:8086
源错误:
执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息。
堆栈跟踪:
[SocketException (0x274d): 由于目标机器积极拒绝,无法连接。 192.168.1.242:8086]
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +2668969
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +717
CSDN.Community.TopicFileDataCenter.TopicFileComponent.Reply(ReplyGenerateData rgd) +0
CSDN.Community.TopicFileDataCenter.TopicFileDataCenterEntry.Reply(Guid topicId, DateTime createDate, ReplyInfo reply, CommunityUser user, UserSectionProfile usp) +73
CSDN.Community.PointForum.Services.ReplyTopicManager.ReplyTopic(ReplyInfo reply, DateTime topicPostDate, String& errorInfo, CommunityUser user, UserSectionProfile usp) +747
CSDN.Community.PointForum.WebControls.ReplyTopicPage.bt_Submit_Click(Object sender, EventArgs e) +604
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +105
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +107
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1746
#36
很厉害!佩服了
#37
弱弱的mark一下
#38
我也想知道,正在找這方面的資料~~~~~
#39
test
#40
test
#41
虽然时间有点跨度,但知识没有变。
#42
我是知道了用ImessageFilter之后才看到这个帖子的。
可惜我在c#,你在vb.net
是不是.net搞的语言太多了,高手集中不起来。所以很多时候问不到答案?
可惜我在c#,你在vb.net
是不是.net搞的语言太多了,高手集中不起来。所以很多时候问不到答案?
#43
lzmtw 兄,我遇到一个问题,就是不能筛选到窗体失效或者激活的消息。不知道是不是我的代码有误?请你帮我看一下。
这是窗体测试代码
Public Class Class1
Implements IMessageFilter
Private Const WM_MOVE As Long = &H3
'窗体失效
Private Const WM_ACTIVATE As Int32 = &H6
Private Const WA_INACTIVE As Int32 = 0
Private Const WM_ACTIVATEAPP As Int32 = &H1C
Private Const WM_NCACTIVATE As Int32 = &H86
Private Const WM_KILLFOCUS As Int32 = &H8
Private Const WM_SETFOCUS As Int32 = &H7
Private Const WM_LBUTTONDOWN As Integer = &H201
Private Const WM_KEYDOWN As Long = &H100
Private Const WM_KEYUP As Long = &H101
Public Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) As Boolean Implements System.Windows.Forms.IMessageFilter.PreFilterMessage
Select Case m.Msg
Case WM_LBUTTONDOWN
Case WM_KEYDOWN
Case WM_ACTIVATE '激活
Console.WriteLine(m.ToString & "_________________________________")
Case WM_NCACTIVATE
Console.WriteLine(m.ToString & "_________________________________")
Case WM_KILLFOCUS
Console.WriteLine(m.ToString & "_________________________________")
Case WM_SETFOCUS
Console.WriteLine(m.ToString & "_________________________________")
End Select
Return False
End Function
End Class
这是窗体测试代码
Public Class Form1
Dim c As New Class1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Application.AddMessageFilter(c)
End Sub
End Class