利用hook禁止系统关机的程序,在线等.急用.

shazi_pig 2005-05-19 09:40:35
小弟初学api,但有一作业今天晚上急要,所有请大家帮忙解决.
'窗体
Private Sub Form_Load()
Call EnableKBDHook

End Sub

Private Sub Form_Unload(Cancel As Integer)
Call UnHookKBD
End Sub


'模板
Option Explicit
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 CallNextHookEx Lib "user32" _
(ByVal hHook As Long, _
ByVal ncode As Long, _
ByVal wParam As Long, _
lParam As Any) As Long


Public Declare Function UnhookWindowsHookEx Lib "user32" _
(ByVal hHook As Long) As Long
Public Declare Function ExitWindowsEx Lib "user32" _
(ByVal uFlags As Long, ByVal dwReserved As Long) As Long
Public Const WH_SYSMSGFILTER = 6
Public Const EWX_SHUTDOWN = 1
Public hHook As Long
Public hnexthookproc As Long

Public Const WH_CALLWNDPROC = 4
Public Sub UnHookKBD()
If hnexthookproc <> 0 Then
UnhookWindowsHookEx hHook
hHook = 0
End If
End Sub

Public Function EnableKBDHook()
If hHook <> 0 Then
Exit Function
End If
hHook = SetWindowsHookEx(WH_CALLWNDPROC, AddressOf _
WindowProc, App.hInstance, 0)
End Function


Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If (uMsg = WM_QUERYENDSESSION) Then
WindowProc = 0
WindowProc = CallWindowProc(hHook, hw, uMsg, wParam, lParam)
Else
WindowProc = CallWindowProc(hHook, hw, uMsg, wParam, lParam)
End If
End Function
怎么可以实现让我的系统无法关机.
先谢谢各位了.里面的错误尽管指出,不胜感激.
...全文
394 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
shazi_pig 2005-05-25
  • 打赏
  • 举报
回复
问题虽然还没有解决,先谢谢大家了。
zj1244 2005-05-21
  • 打赏
  • 举报
回复
关机消息的拦截

在关机或Logff前信息的拦截

  如果我们关机或Logoff时,我们的程序有时会因而无法按正常程序结束,一般我们会在Form的Unload中一段程序结束时要做什么事,但是,如果使用者直接用开始功能菜单的关机,会使UnLoad的部份没有做到,我们现在就想办法来拦截关机(或Logoff)时的信息。

  一般来说,关机或Logff后,Windows会传依序送出WM_QUERYENDSESSION的信息给每个Process,如果中间有一个Process不能顺利结束(例如:Word修改后未存档,而出现是否存档,但我们按取消),这时该信息执行的结果会传回False(0),这时Windows也就不再继续送WM_QUERYENDSESSION给下一个Proccess。反之,如果所有的Process都可以顺利结束(也就是每个送出的WM_QUERYENDSESSION都传回True),那才代表以以顺利结束。

  不管WM_QUERYENDSESSION最后的结果是可以顺利结束或不能顺利结束,Windows会再送一个WM_ENDSESSION的信息给所有的Process,而wParam的内容便是指出是否可以顺利结束(True菜单可以,False菜单不行,在vb中则CheckwParam = 0 菜单False ,0菜单True),说到这里大概就知道该如何做啦,程序如下:
  
’以下在Form
Private Sub Form_Load()
 Dim ret As Long

 ’记录原来的Window Procedure的位址
 preWinProc = GetWindowLong(Me.hwnd, GWL_WNDPROC)
 ’设定form的window Procedure到wndproc
 ret = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf wndproc)
End Sub
  
Private Sub Form_Unload(Cancel As Integer)
 Dim ret As Long
 Dim fno As Long

 ’取消Message的截取,而使之又只送往原来的Window Procedure
 ret = SetWindowLong(Me.hwnd, GWL_WNDPROC, preWinProc)

 ’这里只是要看看用关机的方式结束程序时,会不会执行到这里
 fno = FreeFile
 Open "c:\tt2" For Append As fno
 Print #fno, "ccc" + vbCrLf
 Close #fno
End Sub
  
’以下在.Bas
Option Explicit
  
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
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 Const GWL_WNDPROC = (-4)
Public Const WM_ENDSESSION = &H16
Public Const WM_QUERYENDSESSION = &H11
  
Public preWinProc As Long
  
Public Function wndproc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
 If Msg = WM_QUERYENDSESSION Then
   Debug.Print "QryEnd", wParam, lParam
 Else
  If Msg = WM_ENDSESSION Then
   If wParam 0 Then ’代表将顺利关机或LogOff,这时便得做正常结束程序的操作
     Dim fno As Long
     Open "c:\ttt" For Output As #1
     Print #1, "hahcccc5"
     Close #1
   End If
  End If
 End If

 ’将之送往原来的Window Procedure
 wndproc = CallWindowProc(preWinProc, hwnd, Msg, wParam, lParam)
End Function
shazi_pig 2005-05-20
  • 打赏
  • 举报
回复
大家都还在嘛??
帮我看看.
还没有解决呀
还想懒够 2005-05-19
  • 打赏
  • 举报
回复
我记得我以前在2000平台下,如果碰上了误关机,就趁着还没有关机的时候,赶紧打开一个NotePad,然后就几个空格下去。在关闭它的时候,就会给出提示,要求保存,点击“取消”就可以不关机了:)

不知道其它的系统怎么样,没有试过。



========================================
写字楼里写字间,写字间里程序员;
程序人员写程序,又拿程序换酒钱。
酒醒只在网上坐,酒醉还来网下眠;
酒醉酒醒日复日,网上网下年复年。
但愿老死电脑间,不愿鞠躬老板前;
奔驰宝马贵者趣,公交自行程序员。
别人笑我忒疯癫,我笑自己命太贱;
不见满街漂亮妹,哪个归得程序员。
shazi_pig 2005-05-19
  • 打赏
  • 举报
回复
我想知道可不可以利用exitwindowsex函数来测试.
如果系统调用了exitwindowsex函数我们就取消这个动作.
shazi_pig 2005-05-19
  • 打赏
  • 举报
回复
HotUs(H-) :
你还在吗??
我的电脑还是关掉了,可以再帮我看看不.
大家帮忙,多少分不是问题,我还有大几百分.
Hotus 2005-05-19
  • 打赏
  • 举报
回复
form 里面

Private Sub Form_Load()
gHW = Me.hwnd
Hook
End Sub

Private Sub Form_Unload(Cancel As Integer)
Unhook
End Sub

模块里面


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
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function GetMessage Lib "user32" Alias "GetMessageA" (lpMsg As MSG, ByVal hwnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long) As Long

Type POINTAPI
x As Long
y As Long
End Type

Type MSG
hwnd As Long
message As Long
wParam As Long
lParam As Long
time As Long
pt As POINTAPI
End Type

Public Const GWL_WNDPROC = -4
Public Const WM_QUERYENDSESSION = &H11
Global Const WM_CANCELMODE = &H1F

Public SDAttempted As Long
Global lpPrevWndProc As Long
Global gHW As Long

Public Sub Hook()
lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Public Sub Unhook()
Dim temp As Long
temp = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc)
End Sub
Function WindowProc(ByVal hw As Long, ByVal uMsg As _
Long, ByVal wParam As Long, ByVal lParam As Long) As _
Long
Dim a As Long
If uMsg = WM_QUERYENDSESSION Then
SDAttempted = SDAttempted + 1
frmMain.lblSDs.Caption = SDAttempted & " Time(s)."
WindowProc = CallWindowProc(lpPrevWndProc, hw, _
WM_CANCELMODE, wParam, wParam)
MsgBox "Windows made an attempt to shutdown !", vbInformation, "Shutdown-Attempt"
Exit Function
End If
WindowProc = CallWindowProc(lpPrevWndProc, hw, _
uMsg, wParam, lParam)
End Function

shazi_pig 2005-05-19
  • 打赏
  • 举报
回复
系统是NT
补充一下.

1,486

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧