200分。如何分别知道Windows关机、重新启动、还是注销?不要废话,来段代码吧。(无)(200分)

  • 主题发起人 主题发起人 jingtao
  • 开始时间 开始时间
控制WINDOWS的开关:如关闭WINDOWS,重新启动WINDOWS等,
ExitWindowsEx(UINT uFlags,DWORD dwReserved);是实现这一功能的API函数首先定义常数const
EWX_FORCE=4; //关闭所有程序并以其他用户身份登录EWX_LOGOFF=0; //重新启动计算机并切换到MS-DOS方式
EWX_REBOOT=2; //重新启动计算机EWX_SHUTDOWN=1;//关闭计算机
运行时给How赋值,让他等于EWX_SHUTDOWN或其他,调用以下语句ExitWindowsEx(How,0);
 
实现这一功能用API函数
ExitWindowsEx(UINT uFlags,DWORD dwReserved);
EWX_FORCE=4; //关闭所有程序并以其他用户身份登录
EWX_LOGOFF=0; //重新启动计算机并切换到MS-DOS方式
EWX_REBOOT=2; //重新启动计算机
EWX_SHUTDOWN=1;//关闭计算机
 
procedure WMQUERYENDSESSION(var message:Tmessage);message WM_QUERYENDSESSION;
可以截获系统关闭时的消息message.lparam代表关机的类型,具体是什么我不清楚,你可以
分别用关机,重启,注销来检测其值!
我刚试了一下,关机和重启都是0,注销是-2147483648(如果检测lparamhi则为32768)
(d5+winme)
下面是我的测试代码:
TForm1 = class(TForm)
private
procedure WMQUERYENDSESSION(var msg:Tmessage);message WM_QUERYENDSESSION;
{ Private declarations }
public
{ Public declarations }
end;

procedure tform1.WMQUERYENDSESSION(var msg:Tmessage);
begin
showmessage(inttostr(msg.lparamlo)+chr(13)+chr(10)+inttostr(msg.lparamhi));
msg.Result :=0;
end;
 
各位大哥,我知道更好的关机方法.我问的是如何知道Windows关机到底是
关机、重新启动、还是注销.
 
如何分别知道Windows关机时是想关机、重新启动、还是注销?
 
不太明白你的问题呀,要知道这些做什么?看来只有截获消息了。
 
要截WM_QUERYENDSESSION消息的,判断lParam
 
你想要什么,我给你的答案已经可以检测出注销windows的操作了,只是关机和重启没有分
出来,你可以再想想办法!
 
WM_QUERYENDSESSION 消息只能分辨 关机/注销 ,重启和退出到 Console 无法知道。
 
我在 Win 2000 上测试过,WM_QUERYENDSESSION.lParam :
注销:-2147483648
关机:0
重启:0
确实没办法分辨。
 
我想重启和退出可以利用注册表来解决吧
 
利用句柄查找的方法得到关机/注销对话框上哪个复选钮被选中了,就知道了
 
下面是一个搞硬件的朋友的意见,不过我觉得太浪费系统资源。:)

看到你的标题我现在能想到的解决方法有两种 (168字)(jhj9 今天6:43 阅读 3)
1. 截获WindowExitEx这个API即可,它位于USER32.DLL里
2. 开个timer查"关闭 Windows"这个窗口是否存在,如果存在继续获得其选项信息
我认为第二种方案简单些,我有空再给代码吧。
我刚实验了一下,第二种方案不行 (33字)(jhj9 今天6:51 阅读 3)
处于选择关闭状态时,timer被停掉了
搞定了,差点被系统骗,并不是timer不运行了,而是windows把窗口刷新暂停了 (1千字)(jhj9 今天7:28 阅读 7)
顺便说一句,你既然是问问题的,说话的口气应该客气些 (空)(jhj9 今天7:30 阅读 2)

差点以为是timer不行。
你建一个form,包含一个timer, 一个label,然后在timer里写:

procedure TForm1.Timer1Timer(Sender: TObject);
var
r,h:integer;
buff:pchar;
s:string;
begin
h:=findwindow(nil,'关闭 Windows');
if h<>0 then
begin
h:=getwindow(h,GW_CHILD);
while h<>0 do
begin
r:=sendmessage(h,BM_GETCHECK,0,0);
if (r=BST_CHECKED) then
begin
getmem(buff,256);
getwindowtext(h,buff,256);
s:=strpas(buff);
if s='将您的计算机转入睡眠状态(&E)' then
begin
label1.caption:='1';
label1.refresh;
end
else if s='关闭计算机(&S)' then
begin
label1.caption:='2';
label1.refresh;
end
else if s='重新启动计算机(&R)' then
begin
label1.caption:='3';
label1.refresh;
end
else if s='重新启动计算机并切换到 MS-DOS 方式(&M)' then
begin
label1.caption:='4';
label1.refresh;
end;
freemem(buff);
end;
h:=getwindow(h,GW_HWNDNEXT);
end;
end;
end;

这样你在运行程序后,在'关闭系统'中选择的项就会记录到label1中(当然,为了测试你得点取消关闭,否则你怎么看呀?)
有了这个程序,相信你不难把它改成你所需要的用途。
----------------------------------------------
 
这位搞硬件的朋友很幽默。
用 Timer 不停地看有没有标题为“关闭 Windows ”的窗口出现,如果发现了,再看看哪个
圆按钮被选中了... ...
比较有想象力啊。
 
多人接受答案了。
 
后退
顶部