注册 登录
编程论坛 VB6论坛

VB6在win7怎么写程序判断用户执行重启还是关机?

不懂才问 发布于 2022-09-14 16:43, 2866 次点击
如题,谢谢
16 回复
#2
不懂才问2022-09-14 16:44
要用哪个API,谢谢
#3
时光流逝2022-09-16 20:16
ExitWindows
#4
yuma2022-09-17 10:16


[此贴子已经被作者于2022-9-17 13:29编辑过]

#5
不懂才问2022-09-19 08:38
回复 3楼 时光流逝
这个可以拦截到关机的消息,并判断是重启还是关机吗?
#6
yuma2022-09-20 10:40
一般用ExitWindowsEx关机、重启、注销,没见有人用ExitWindows,或许ExitWindows也可以实现吧。

ExitWindows和ExitWindowsEx的API声明如下:

Declare Function ExitWindows Lib "user32" (ByVal dwReserved As Long, ByVal uReturnCode As Long) As Long
Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long

[此贴子已经被作者于2022-9-20 11:15编辑过]

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

Public Const WM_QUERYENDSESSION = &H11  '关机,注销,重新启动时或其他程序调用了ExitWindows API函数,系统依次发送给所有程序的消息
Public Const WM_ENDSESSION = &H16  '当系统发出WM_QUERYENDSESSION消息后,等待检查WM_QUERYENDSESSION消息的返回值, 再接着发送此消息给应用程序,系统并根据返回值决定是否关机,注销或重启

楼主,这个你怎么拦截消息并区分是重启还是关机?

[此贴子已经被作者于2022-9-20 13:54编辑过]

#8
不懂才问2022-09-21 14:29
回复 7楼 yuma
RegisterWindowsMessagea,百度了一下,那些C或者C++的代码,有点看不懂,这个可以给个VB的声明和示例吗?谢谢!
#9
吹水佬2022-09-21 17:16
XP拦截WM_QUERYENDSESSION应该就可以(顶层窗口)
之后的版本就复杂点,相关主要的:
ShutdownBlockReasonCreate()
ShutdownBlockReasonDestroy()
WM_QUERYENDSESSION
WM_ENDSESSION
#10
yuma2022-09-21 17:48
回复 9楼 吹水佬
重启、注销、关机 发的都是相同的消息。
#11
吹水佬2022-09-21 20:13
以下是引用yuma在2022-9-21 17:48:24的发言:

重启、注销、关机 发的都是相同的消息。

Msg相同,wParam区分
#12
yuma2022-09-21 22:03
以下是引用吹水佬在2022-9-21 20:13:35的发言:


Msg相同,wParam区分



系统给应用程序发Msg是有优先级先后顺序的,wparam是应用程序返回的。先拦截谁比较好呢?
#13
吹水佬2022-09-22 07:34
以下是引用yuma在2022-9-21 22:03:37的发言:

系统给应用程序发Msg是有优先级先后顺序的,wparam是应用程序返回的。先拦截谁比较好呢?

我搞错了,是lParam
只有本站会员才能查看附件,请 登录

#14
yuma2022-09-22 09:36
也是无法区分

只有本站会员才能查看附件,请 登录
#15
吹水佬2022-09-22 09:47
回复 14楼 yuma
有时限的,过时无效。
能拦截到再测试吧
#16
yuma2022-09-22 11:33
目前只能这样:

拦截消息有点扯淡。


程序代码:
Private Declare Function SetProcessShutdownParameters Lib "kernel32" (ByVal dwLevel As Long, ByVal dwFlags As Long) As Long

Private Sub Form_Load()
Call SetProcessShutdownParameters(1279, 0&)  '&H4FF = 1279,即本程序被系统最先通知关闭以便触发Form_QueryUnload事件,这样才能最先发现电脑关机、重启、注销事件
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
If UnloadMode = vbAppWindows Then
Cancel = 1  '该语句能让系统不能顺利关机、重启、注销,这样你才有机会反悔并看到后面的对话框。
MsgBox "检测到你的电脑正在准备关机、重启、注销!"
End If
End Sub
#17
时光流逝2022-09-25 14:04
ExitWindowsEx时uFlags传EWX_FORCE你就拦不到了
1