求助!!!又是hook(如何截取一个窗体关闭的消息) (200分)

  • 主题发起人 主题发起人 王靖
  • 开始时间 开始时间

王靖

Unregistered / Unconfirmed
GUEST, unregistred user!
我想截取自己当前窗体的关闭消息,并阻止窗体关闭
看了钱达智的keyboard例子,我想用WH_Shell实现,里面有钩子码
HSHELL_WINDOWDESTROYED表示窗体被关
wParam :Handle to the destroyed window.
我是把钩子在自己进程实现的,没有放到dll里.但关闭本身窗体并不能触发
icode=HSHELL_WINDOWDESTROYED.
由于第一次编hook的程序,不知是设置有问题,还是设置的钩子不对
望各位大虾指出错误给出解决方法

下面是我的程序
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

function SHellHookHandler(iCode: Integer;
wParam: WPARAM;
lParam: LPARAM): LRESULT;
function EnableHotKeyHook: BOOL;
function DisableHotKeyHook: BOOL;

var
Form1: TForm1;
hNextHookProc: HHook;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
if EnableHotKeyHook then
ShowMessage('shellhooking...');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if DisableHotKeyHook then
ShowMessage('releasing hook..., DONE!!');
end;

function ShellHookHandler(iCode: Integer;
wParam: WPARAM;
lParam: LPARAM): LRESULT;
const
_KeyPressMask = $80000000;
begin
Result := 0;
If iCode < 0 Then
begin
Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);
Exit;
end;
// 侦测Form1窗口被关
if (iCode = HSHELL_WINDOWDESTROYED) then
// and (Findwindow('TForm1','Form1') = wParam) then
begin
if MessageDlg('关闭本程序吗?', mtConfirmation, mbYesNoCancel, 0) = mrYes
then Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam)
// 允许Windows关闭
else result:=1; // 阻止Windows关闭
end
else begin
Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);
end;
showmessage(inttostr(icode));
end;

function EnableHotKeyHook: BOOL;
begin
Result := False;
if hNextHookProc <> 0 then Exit;
hNextHookProc := SetWindowsHookEx(WH_SHELL,@SHellHookHandler,0, GetCurrentThreadID);
Result := hNextHookProc <> 0;
end;

function DisableHotKeyHook: BOOL; export;
begin
if hNextHookProc <> 0 then
begin
UnhookWindowshookEx(hNextHookProc); // 秆埃 Keyboard Hook
hNextHookProc := 0;
MessageBeep(0);
MessageBeep(0);
end;
Result := hNextHookProc = 0;
end;

end.
 
sorry,function ShellHookHandler中的最后一行showmessage(inttostr(icode));
应去掉
 
自己的窗体的关闭消息,干吗要Hook?
直接响应OnCLoseQuery事件不就行了?
 
1.Hook函数应该在DLL中.理论上说Hook本进程的Hook函数可以在进程中,但
Windows的DOC经常有错误的,也许Shell的Hook函数要求一定在DLL中...
2.响应本进程的窗口关闭当然应该用OnCloseQuery事件,而不是Hook.
 
这样做最简单

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if MessageDlg('关闭本程序吗??', mtConfirmation,
[mbOk, mbCancel], 0) = mrCancel then
CanClose := False;
end;
 
to everyone:
1.
大家所提的方法我早已试过,其他关闭正常,但当用ctrl+Alt+del关闭时,如果
第一次把canclose设为false,不关闭,那么第二次再用ctrl+Alt+del关闭时,系统
会告诉你该程序没有响应,此时就可以关闭了,而不会再让你设canclose.
这样不能达到不许他人关闭的要求,所以我才试用hook.

2.
另外,我也把hook加到dll中试了一下,完全仿照钱达智的hook例子,
callnexthookex也按以前相关问题进行了修改,但关闭窗口时根本没有进
code=HSHELL_WINDOWDESTROYED 分支.
我从网上找的一个hookdemo的确使用wh_shell监视了系统中任意窗体的creat
和的destory,只是这个老外没有给出源程序,所已我想可能是我的hook程序有问


3
希望大家帮我解决一下,要求就是用任务管理器之类的东西也关不掉,不一定是
任意程序,只需当前这个已运行的程序不被关掉即可,希望有时间的大虾能给出
源程序,分数可以再加.thanks

 
1.如果是为了对付Win95的Ctrl+Alt+Del再选择"关闭"按钮(不是"关机"按钮),
可以在程序启动时用RegisterServiceProcess()登记本进程为服务,这样
Ctrl+Alt+Del中就看不到这个程序了.再响应OnCloseQuery,返回false,
就没有问题了.
2.要在选择"关机"的情况下都不能关闭的话,我是不会的......理论上说,任何OS
在关机前都必须关闭所有用户进程.但95经常出现关不了机的情况.也许你可以
用某种方法把95搞成这个样子......我是不会.
 
你的程序一执行,你就骗骗windows说是屏幕保护,不就让ctrl+alt+del玩玩了
然后你响应onclosequery就可以了.
或者你自己搞定WM_COMMAND.
 
RegisterServiceProcess()在95下很爽,但NT下报错RegisterServiceProcess
KERNEL32.DLL找不到程序切入点,为何?而且它能躲开NT下的进程察看器吗?

BTW:WM_COMMAND,WM_CLOSE如何截获,我用GETMESSAGE的HOOK截获不了?
急啊:(
 
RegisterServiceProcess()和屏保的方法在NT下都行不通.
NT下没有好的方法能处理这个问题.

要截获WM_COMMAND,WM_CLOSE,何必用HOOK?直接用消息响应就可以了.
消息响应的语法很简单,看看HELP就明白了.
 
从写Delphi程序的消息循环。就可截获WM_COMMAND,WM_CLOSE;
我身边像是有一个例程,我回去给你找找看。
下一回贴给你!(我不大上网)。
 
to lhz
谢谢你,我用了消息响应截获WM_CLOSE,可惜对Ctrl+Alt+Del没用,还不如
OnCloseQuery呢,最起码也和heroes3一样,挣扎几回do u want to quit?
然后该程序忙没响应,确信要关闭吗?就没有反应的关了.
不知Ctrl+ALt+Del关窗口时发什么消息,该程序忙没响应,确信要关闭时又
发的什么消息?

to D4
谢了:)
 
Ctrl+Alt+Del发的应该是退出之类的消息,但是它并不判断你是否
返回了,而是看你是否退出了,所以,如果经过一定的时间你的程序
还没有退出,它就认为程序出问题了,并把程序强行杀死.

如果你用的是NT,那么没有甚麽好的办法.但NT一般不用Ctrl+Alt+Del
关闭程序的.如果是95/98,用RegisterServiceProcess可以让进程
在任务列表内消失,从而使Ctrl+Alt+Del失效;或者用屏保的方法,
让Ctrl+Alt+Del根本不出现.
 
; 我也想用Hook来响应键盘,但没找到例子,不知哪位能mail我一份,或告知我哪里能找得到。

多谢!
 
问题检索,键入hook,文章hook中有钱达智的例子
 
王靖:

这个问题已经很长时间没有人参加讨论,为保持版面
整洁,节约网友时间,请提问者采取必要处理措施。
关于本版管理细则,请参见<a href="http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=111927">这个</a>问题。如两天
内提问者没有响应,我将采取强制措施。

如有管理建议,请到<a href="http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=111927">这里</a>提出。谢谢!
 
多人接受答案了。
 

Similar threads

后退
顶部