Hook必须先Unhook!回调也一样(CallBack),否则都会出错! HookDeclare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As LongGlobal hHook As Long Global Const WH_KEYBOARD = 2 ----- 'Hook Public Sub Hook() hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf KeyboardProc, App.hInstance, 0) End Function 'unhook Public Sub UnHook() If hHook Then Call UnhookWindowsHookEx(hHook) '卸下键盘钩子 hHook = 0 End If End Function '========== '回调Callback Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Public Const GWL_WNDPROC = (-4) Public lpPrevWndProc As Long Public lngHWnd As LongPublic Sub MyHook(hwnd As Long) lngHWnd = hwnd lpPrevWndProc = SetWindowLong(lngHWnd, GWL_WNDPROC, AddressOf WindowProc) End Sub'钩 子 函 数 撤 消: Public Sub myUnHook() Dim lngReturnValue As Long lngReturnValue = SetWindowLong(lngHWnd, GWL_WNDPROC, lpPrevWndProc) End Sub ------------------ 如果用Hook,一定要UnHook() 如果用了回调,一定要先myUnHook()
各位老大,问题是这样: 1。在一个调试过的简单 form1 窗体中,无法在 formunload 等中加 end 语句(注释掉hook可以加),尽管该程序无须 end即可关闭,但在另一个程序中需要 end 才能结束程序。所以,是否同意我的结论,在hook中与end冲突(代码在下面,大家看看是否unhook了)。 2。如果是这样,如何让这个只卸载的窗体(所以要end)关闭?下面代码通过,但在拷贝到另一个程序(已经在formunload中使用end命令)点击exit命令出错。Dim MyNot As NOTIFYICONDATA '定义一个托盘结构 Private Sub Command11_Click() '按下删除托盘图标按钮 With MyNot .hIcon = Form1.Icon '托盘图标指针指向窗口的图标 .hwnd = Form1.hwnd '窗体指针 .szTip = "" '弹出提示字符串,删除时应为空 .uCallbackMessage = WM_USER + 100 '对应程序定义的消息 .uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE '图标标志 .uID = 1 '图标识别符 .cbSize = Len(MyNot) '计算结构实例MyNot的长度 End With Dim hh As Long hh = Shell_NotifyIcon(NIM_DELETE, MyNot) '删除该托盘图标 trayflag = False '托盘图标删除后trayflag为假 End Sub Private Sub Command12_Click() '按下创建托盘图标按钮 Dim hh As Long With MyNot .hIcon = Form1.Icon .hwnd = Form1.hwnd .szTip = "托盘图标" & Chr(&H0) .uCallbackMessage = WM_USER + 100 .uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE .uID = 1 .cbSize = Len(MyNot) End With hh = Shell_NotifyIcon(NIM_ADD, MyNot) '添加一个托盘图标 trayflag = True '托盘图标添加后trayflag为真 End Sub
Private Sub Command14_Click() '退出窗口按钮被按下 If trayflag = True Then Command11_Click '如果托盘图标仍在,模拟按下"删除托盘图标"按钮 Unhook '退出消息循环 Unload Me '卸载窗体 End Sub Private Sub exit_Click() If trayflag = True Then Command11_Click '如果托盘图标仍在,模拟按下“删除托盘图标"按钮 Unhook '退出消息循环 Unload Me '卸载窗体 End Sub Private Sub Form_Load() gHW = Me.hwnd '取得本窗体指针 hook '调用钩子函数,将自制消息处理函数钩入Windows的消息循环 Call Command12_Click End SubPrivate Sub Form_Unload(Cancel As Integer) Dim d As Integer d = 45 + 45 Call Command11_Click End Sub Private Sub hide_Click() Form1.hide '隐藏窗口 End Sub Private Sub show_Click() Form1.show End Sub 真的烦死我了。
http://www.csdn.net/expert/topic/566/566700.xml?temp=.1494562
可能你把关闭消息hook了,所以先unhook
HookDeclare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As LongGlobal hHook As Long
Global Const WH_KEYBOARD = 2
-----
'Hook
Public Sub Hook()
hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf KeyboardProc, App.hInstance, 0)
End Function
'unhook
Public Sub UnHook()
If hHook Then
Call UnhookWindowsHookEx(hHook) '卸下键盘钩子
hHook = 0
End If
End Function
'==========
'回调Callback
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Const GWL_WNDPROC = (-4)
Public lpPrevWndProc As Long
Public lngHWnd As LongPublic Sub MyHook(hwnd As Long)
lngHWnd = hwnd
lpPrevWndProc = SetWindowLong(lngHWnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub'钩 子 函 数 撤 消:
Public Sub myUnHook()
Dim lngReturnValue As Long
lngReturnValue = SetWindowLong(lngHWnd, GWL_WNDPROC, lpPrevWndProc)
End Sub
------------------
如果用Hook,一定要UnHook()
如果用了回调,一定要先myUnHook()
1。在一个调试过的简单 form1 窗体中,无法在 formunload 等中加 end 语句(注释掉hook可以加),尽管该程序无须 end即可关闭,但在另一个程序中需要 end 才能结束程序。所以,是否同意我的结论,在hook中与end冲突(代码在下面,大家看看是否unhook了)。
2。如果是这样,如何让这个只卸载的窗体(所以要end)关闭?下面代码通过,但在拷贝到另一个程序(已经在formunload中使用end命令)点击exit命令出错。Dim MyNot As NOTIFYICONDATA '定义一个托盘结构
Private Sub Command11_Click() '按下删除托盘图标按钮
With MyNot
.hIcon = Form1.Icon '托盘图标指针指向窗口的图标
.hwnd = Form1.hwnd '窗体指针
.szTip = "" '弹出提示字符串,删除时应为空
.uCallbackMessage = WM_USER + 100 '对应程序定义的消息
.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE '图标标志
.uID = 1 '图标识别符
.cbSize = Len(MyNot) '计算结构实例MyNot的长度
End With
Dim hh As Long
hh = Shell_NotifyIcon(NIM_DELETE, MyNot) '删除该托盘图标
trayflag = False '托盘图标删除后trayflag为假
End Sub
Private Sub Command12_Click() '按下创建托盘图标按钮
Dim hh As Long
With MyNot
.hIcon = Form1.Icon
.hwnd = Form1.hwnd
.szTip = "托盘图标" & Chr(&H0)
.uCallbackMessage = WM_USER + 100
.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
.uID = 1
.cbSize = Len(MyNot)
End With
hh = Shell_NotifyIcon(NIM_ADD, MyNot) '添加一个托盘图标
trayflag = True '托盘图标添加后trayflag为真
End Sub
Private Sub Command14_Click() '退出窗口按钮被按下
If trayflag = True Then Command11_Click '如果托盘图标仍在,模拟按下"删除托盘图标"按钮
Unhook '退出消息循环
Unload Me '卸载窗体
End Sub
Private Sub exit_Click()
If trayflag = True Then Command11_Click '如果托盘图标仍在,模拟按下“删除托盘图标"按钮
Unhook '退出消息循环
Unload Me '卸载窗体
End Sub
Private Sub Form_Load()
gHW = Me.hwnd '取得本窗体指针
hook '调用钩子函数,将自制消息处理函数钩入Windows的消息循环
Call Command12_Click
End SubPrivate Sub Form_Unload(Cancel As Integer)
Dim d As Integer
d = 45 + 45
Call Command11_Click
End Sub Private Sub hide_Click()
Form1.hide '隐藏窗口
End Sub
Private Sub show_Click()
Form1.show
End Sub
真的烦死我了。
还有,你应该用窗口子类化技术,没必要用什么hook。
实在搞不定,建议你去看看VB自带的例子systray。
单击托盘上的 exit 命令出错。