◆◆◆ 为什么这段程序只能在Windows98/2000下运行,而在WinXP下却无效???如何解决?◆◆◆ (200分)

  • 主题发起人 主题发起人 iArtist
  • 开始时间 开始时间
I

iArtist

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1;

interface

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

type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
procedure SubClassWndProc(var Message: TMessage);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Msg_id : longint;

Const HSHELL_WINDOWCREATED = 1; {系统级的窗体被创建 }
Const HSHELL_WINDOWDESTROYED = 2; {系统级的窗体即将被关闭}
Const HSHELL_ACTIVATESHELLWINDOW = 3; {SHELL 的主窗体将被激活(本例未用)}
Const HSHELL_WINDOWACTIVATED = 4; {系统级的窗体被激活}
Const HSHELL_GETMINRECT = 5; {窗体被最大化或最小化(本例未用)}
Const HSHELL_REDRAW = 6; {Windows 任务栏被刷新(本例未用)}
Const HSHELL_TASKMAN = 7; {任务列表的内容被选中(本例未用)}
Const HSHELL_LANGUAGE = 8; {中英文切换或输入法切换(本例未用)}

function RegisterShellHook(hwnd : HWND;action : longint):longint;stdcall; external 'shell32.dll' index 181;
implementation
{$R *.DFM}
procedure TForm1.SubClassWndProc(var Message: TMessage);
var
s_title,s_action : string;
i : integer;
begin
i := 255;
setLength(s_title,i);
if Message.Msg = msg_id then
begin
getWindowText(message.lparam,pchar(s_title),i);
case message.WParam of
HSHELL_WINDOWCREATED : s_action := '创建';
HSHELL_WINDOWDESTROYED : s_action := '关闭';
HSHELL_ACTIVATESHELLWINDOW : s_action := 'SHELL 的主窗体将被激活';
HSHELL_WINDOWACTIVATED : s_action := '系统级的窗体被激活';
HSHELL_GETMINRECT : s_action := '最大化或最小化';
HSHELL_REDRAW : s_action := 'Windows 任务栏被刷新';
HSHELL_TASKMAN : s_action := '任务列表被选中';
HSHELL_LANGUAGE : s_action := '切换输入法';
end;
memo1.lines.add(datetimeToStr(now())+ ' > ' + s_action + ' : ' + s_title);
代码:
else
WndProc(Message);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
//将日志程序的名称从 CTRL+ALT+DEL 列表中清除
//Timer1.Interval = 60000 ' 定时器的作用是每隔一分钟将日志存盘
//定义一个新的系统级的消息类型
Msg_ID := RegisterWindowMessage('SHELLHOOK');
RegisterShellHook(form1.Handle, 1); {调用未公开的函数(进行注册)}
//实施拦截:在存储了原入口地址的同时,将新地址指向自定义的函数WindowProc
form1.WindowProc := SubClassWndProc;
button2.Enabled := true;
button1.Enabled := false;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
RegisterShellHook(form1.handle, 0); { 调用未公开的函数(取消注册)}
form1.windowproc := wndProc;
button1.Enabled := true;
button2.Enabled := false;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

end.
 


RegisterShellHook这个函数在DLL中并没有名字,而是通过索引号调用的。

 
你用动态导入函数办法试试看
 
既然是未公开的,就不能保证一定可以用。
还要情系统级的大师来解答。
 
怎样动态导入函数?
 
如果在XP里用2000的Shell32.dll 则还是可以的。但是XP的Shell32.dll就不行了!!

而且,在XP里,if Message.Msg = msg_id then 他们两个值并不相等!!这是为什么?
 
后退
顶部