Option ExplicitPrivate Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare Function SetParent Lib "user32.dll" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Const WS_EX_MDICHILD As Long = &H40& Private Const GWL_STYLE = (-16) Private Const GWL_EXSTYLE As Long = (-20) Private Const WS_CHILD = &H40000000 Private Const WS_CHILDWINDOW = (WS_CHILD) Private Const WM_CLOSE As Long = &H10Dim MDIwordpad As Long'写字板窗口句柄 Private Sub Form_Load()
Dim lngStyle As Long Dim lngExStyle As Long Shell "C:\Program Files\Windows NT\Accessories\wordpad.exe", vbNormalFocus MDIwordpad = FindWindow(vbNullString, "文档 - 写字板") If MDIwordpad > 0 Then SetParent MDIwordpad, Me.hwnd SetWindowLong MDIwordpad, GWL_EXSTYLE, WS_EX_MDICHILD End If End Sub'关闭VB窗体时关闭写字板窗口 Private Sub Form_Unload(Cancel As Integer) Call SendMessage(MDIwordpad, WM_CLOSE, 0, 0) End Sub
Attribute VB_Name = "Module1" Public Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long '//结束钩子 Public Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long '//下一个钩子 Public Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Long) As Long '//发送消息 Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As LongPrivate Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As SECURITY_ATTRIBUTES, lpThreadAttributes As SECURITY_ATTRIBUTES, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long Declare Function FindExecutable Lib "shell32.dll" Alias "FindExecutableA" (ByVal lpFile As String, ByVal lpDirectory As String, ByVal lpResult As String) As Long Declare Function PostThreadMessage Lib "user32" Alias "PostThreadMessageA" (ByVal idThread As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Any) As Long Declare Function GetLastError Lib "kernel32" () As LongConst INFINITE = &HFFFF Const STARTF_USESHOWWINDOW = &H1 Private Enum enSW SW_HIDE = 0 SW_NORMAL = 1 SW_MAXIMIZE = 3 SW_MINIMIZE = 6 End Enum Private Enum enPriority_Class NORMAL_PRIORITY_CLASS = &H20 IDLE_PRIORITY_CLASS = &H40 HIGH_PRIORITY_CLASS = &H80 End EnumPrivate Type PROCESS_INFORMATION hProcess As Long hThread As Long dwProcessId As Long dwThreadId As Long End Type Private Type STARTUPINFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Byte hStdInput As Long hStdOutput As Long hStdError As Long End Type Private Type SECURITY_ATTRIBUTES nLength As Long lpSecurityDescriptor As Long bInheritHandle As Long End Type Public Const SW_SHOWNORMAL = 1Public Const WM_CLOSE = &H10 Public Const HCBT_ACTIVATE = 5 Public Const HCBT_DESTROYWND = 4 Public Const WH_CBT = 5Public IHwnd As Long Public IHook As Long Public IThreadId As Long Public WindowText As String Public IText As String '---回调--- Public Function HookProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long If nCode < 0 Then HookProc = CallNextHookEx(IHook, nCode, wParam, lParam) Exit Function End If
If nCode = HCBT_DESTROYWND Then If GetCurrentThreadId = IThreadId Then If MsgBox("是否关闭当前程序,请确认(Y/N)?", vbYesNo + vbQuestion, "关闭") = vbNo Then nCode = 0 Else End If End If End If HookProc = CallNextHookEx(IHook, nCode, wParam, lParam) End Function '******************************************************************************************** '******************************************************************************************** '-------设置钩子----------- Sub EnableHook() If IHook = 0 Then IHook = SetWindowsHookEx(WH_CBT, AddressOf HookProc, App.hInstance, IThreadId) End If End Sub '-------取消钩子----------- Sub FreeHook() If IHook <> 0 Then Call UnhookWindowsHookEx(IHook) IHook = 0 End If End Sub Public Function Super_Shell(ByVal sFileName As String) As Long Dim strResult As String * 260 Dim lResult As Long Dim start As STARTUPINFO Dim proc As PROCESS_INFORMATION Dim rc As Long Dim sec1 As SECURITY_ATTRIBUTES Dim sec2 As SECURITY_ATTRIBUTES Dim strCommandLine As String On Error GoTo ErrProc '通过FindExecutable找到的关联文件字符串strResult在返回时,后面会有很多null(asc=0) '不把这些null去掉就无法打开指定的文件,只会打开一个空的文件 '返回值lResult 大于32表示成功;31表示不存在文件类型的关联;0表示系统内存或资源不足; 'ERROR_FILE_NOT_FOUND表示指定的文件不存在;ERROR_PATH_NOT_FOUND表示指定的路径不存在;ERROR_BAD_FORMAT表示执行格式无效 lResult = FindExecutable(sFileName, "", strResult) If lResult < 32 Then MsgBox "没有可以打开" & sFileName & "文件的可执行程序!", vbCritical + vbOKOnly, "提示" Exit Function Else 'Set the structure size sec1.nLength = Len(sec1) sec2.nLength = Len(sec2) start.cb = Len(start) start.dwFlags = STARTF_USESHOWWINDOW start.lpReserved = vbNullString start.cbReserved2 = 0 start.lpReserved2 = 0 start.wShowWindow = enSW.SW_NORMAL strCommandLine = ReplaceStrNull(strResult) + " " + ReplaceStrNull(sFileName) rc = CreateProcess(vbNullString, strCommandLine, sec1, sec2, False, NORMAL_PRIORITY_CLASS, ByVal 0, vbNullString, start, proc) IThreadId = proc.dwThreadId EnableHook End If
End Function'替换字符串中的空字符 vbnullchar Public Function ReplaceStrNull(ByVal strSrc As String) As String Dim i As Integer Dim str As String Dim strDesc As String str = "" strDesc = "" For i = 1 To Len(strSrc) str = Mid(strSrc, i, 1) If Asc(str) <> 0 Then strDesc = strDesc + str End If Next i ReplaceStrNull = strDesc
End Function 调用 Super_Shell "d:\tt.txt"运行发现钩子没有设置成功,在enableHook中调用getlasterror 返回 87 -- 参数类型不匹配,那位能帮我查查原因,谢谢了
Private Declare Function SetParent Lib "user32.dll" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Const WS_EX_MDICHILD As Long = &H40&
Private Const GWL_STYLE = (-16)
Private Const GWL_EXSTYLE As Long = (-20)
Private Const WS_CHILD = &H40000000
Private Const WS_CHILDWINDOW = (WS_CHILD)
Private Const WM_CLOSE As Long = &H10Dim MDIwordpad As Long'写字板窗口句柄 Private Sub Form_Load()
Dim lngStyle As Long
Dim lngExStyle As Long
Shell "C:\Program Files\Windows NT\Accessories\wordpad.exe", vbNormalFocus
MDIwordpad = FindWindow(vbNullString, "文档 - 写字板")
If MDIwordpad > 0 Then
SetParent MDIwordpad, Me.hwnd
SetWindowLong MDIwordpad, GWL_EXSTYLE, WS_EX_MDICHILD
End If
End Sub'关闭VB窗体时关闭写字板窗口
Private Sub Form_Unload(Cancel As Integer)
Call SendMessage(MDIwordpad, WM_CLOSE, 0, 0)
End Sub
Public Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
'//结束钩子
Public Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
'//下一个钩子
Public Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Long) As Long
'//发送消息
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As LongPrivate Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As SECURITY_ATTRIBUTES, lpThreadAttributes As SECURITY_ATTRIBUTES, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Declare Function FindExecutable Lib "shell32.dll" Alias "FindExecutableA" (ByVal lpFile As String, ByVal lpDirectory As String, ByVal lpResult As String) As Long
Declare Function PostThreadMessage Lib "user32" Alias "PostThreadMessageA" (ByVal idThread As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Any) As Long
Declare Function GetLastError Lib "kernel32" () As LongConst INFINITE = &HFFFF
Const STARTF_USESHOWWINDOW = &H1
Private Enum enSW
SW_HIDE = 0
SW_NORMAL = 1
SW_MAXIMIZE = 3
SW_MINIMIZE = 6
End Enum
Private Enum enPriority_Class
NORMAL_PRIORITY_CLASS = &H20
IDLE_PRIORITY_CLASS = &H40
HIGH_PRIORITY_CLASS = &H80
End EnumPrivate Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End Type
Private Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Byte
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
Public Const SW_SHOWNORMAL = 1Public Const WM_CLOSE = &H10
Public Const HCBT_ACTIVATE = 5
Public Const HCBT_DESTROYWND = 4
Public Const WH_CBT = 5Public IHwnd As Long
Public IHook As Long
Public IThreadId As Long
Public WindowText As String
Public IText As String
'---回调---
Public Function HookProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If nCode < 0 Then
HookProc = CallNextHookEx(IHook, nCode, wParam, lParam)
Exit Function
End If
If nCode = HCBT_DESTROYWND Then
If GetCurrentThreadId = IThreadId Then
If MsgBox("是否关闭当前程序,请确认(Y/N)?", vbYesNo + vbQuestion, "关闭") = vbNo Then
nCode = 0
Else
End If
End If
End If
HookProc = CallNextHookEx(IHook, nCode, wParam, lParam)
End Function
'********************************************************************************************
'********************************************************************************************
'-------设置钩子-----------
Sub EnableHook()
If IHook = 0 Then
IHook = SetWindowsHookEx(WH_CBT, AddressOf HookProc, App.hInstance, IThreadId)
End If
End Sub
'-------取消钩子-----------
Sub FreeHook()
If IHook <> 0 Then
Call UnhookWindowsHookEx(IHook)
IHook = 0
End If
End Sub
Public Function Super_Shell(ByVal sFileName As String) As Long
Dim strResult As String * 260
Dim lResult As Long
Dim start As STARTUPINFO
Dim proc As PROCESS_INFORMATION
Dim rc As Long
Dim sec1 As SECURITY_ATTRIBUTES
Dim sec2 As SECURITY_ATTRIBUTES
Dim strCommandLine As String
On Error GoTo ErrProc
'通过FindExecutable找到的关联文件字符串strResult在返回时,后面会有很多null(asc=0)
'不把这些null去掉就无法打开指定的文件,只会打开一个空的文件
'返回值lResult 大于32表示成功;31表示不存在文件类型的关联;0表示系统内存或资源不足;
'ERROR_FILE_NOT_FOUND表示指定的文件不存在;ERROR_PATH_NOT_FOUND表示指定的路径不存在;ERROR_BAD_FORMAT表示执行格式无效
lResult = FindExecutable(sFileName, "", strResult)
If lResult < 32 Then
MsgBox "没有可以打开" & sFileName & "文件的可执行程序!", vbCritical + vbOKOnly, "提示"
Exit Function
Else
'Set the structure size
sec1.nLength = Len(sec1)
sec2.nLength = Len(sec2)
start.cb = Len(start)
start.dwFlags = STARTF_USESHOWWINDOW
start.lpReserved = vbNullString
start.cbReserved2 = 0
start.lpReserved2 = 0
start.wShowWindow = enSW.SW_NORMAL
strCommandLine = ReplaceStrNull(strResult) + " " + ReplaceStrNull(sFileName)
rc = CreateProcess(vbNullString, strCommandLine, sec1, sec2, False, NORMAL_PRIORITY_CLASS, ByVal 0, vbNullString, start, proc)
IThreadId = proc.dwThreadId
EnableHook
End If
Super_Shell = rc
Exit Function
ErrProc:
Super_Shell = 0
MsgBox "打开文件出错,错误信息:" + Err.Description, vbOKOnly + vbExclamation, "提示"
End Function'替换字符串中的空字符 vbnullchar
Public Function ReplaceStrNull(ByVal strSrc As String) As String
Dim i As Integer
Dim str As String
Dim strDesc As String
str = ""
strDesc = ""
For i = 1 To Len(strSrc)
str = Mid(strSrc, i, 1)
If Asc(str) <> 0 Then
strDesc = strDesc + str
End If
Next i
ReplaceStrNull = strDesc
End Function
调用 Super_Shell "d:\tt.txt"运行发现钩子没有设置成功,在enableHook中调用getlasterror 返回 87 -- 参数类型不匹配,那位能帮我查查原因,谢谢了