首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 网络编程-> 移动开发教程
利用未公开函数实现shell操作监视_delphi教程
作者:网友供稿 点击:0
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
   在Windows下有一个未公开函数SHChangeNotifyRegister可以吧你的窗口添加到系统的系统消息监视链中,该函数在Delphi
中的定义如下:
Function SHChangeNotifyRegister(hWnd,uFlags,dwEventID,uMSG,cItems:LongWord;
         lpps:PIDLSTRUCT):integer;stdcall;external Shell32.dll index 2;
其中参数hWnd定义了监视系统操作的窗口得句柄,参数uFlags dwEventID定义监视操作参数,参数uMsg定义操作消息,参数cItems
定义附加参数,参数lpps指定一个PIDLSTRUCT结构,该结构指定监视的目录。
    当函数调用成功之后,函数会返回一个监视操作句柄,同时系统就会将hWnd指定的窗口加入到操作监视链中,当有文件操作发生
时,系统会向hWnd发送uMsg指定的消息,我们只要在程序中加入该消息的处理函数就可以实现对系统操作的监视了。
如果要退出程序监视,就要调用另外一个未公开得函数SHChangeNotifyDeregister来取消程序监视。
    下面是使用Delphi编写的具体程序实现范例,首先建立一个新的工程文件,然后在Form1中加入一个Button控件和一个Memo控件,
程序的代码如下:

unit Unit1;

interface

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

const
  SHCNE_RENAMEITEM = $1;
  SHCNE_CREATE = $2;
  SHCNE_DELETE = $4;
  SHCNE_MKDIR = $8;
  SHCNE_RMDIR = $10;
  SHCNE_MEDIAINSERTED = $20;
  SHCNE_MEDIAREMOVED = $40;
  SHCNE_DRIVEREMOVED = $80;
  SHCNE_DRIVEADD = $100;
  SHCNE_NETSHARE = $200;
  SHCNE_NETUNSHARE = $400;
  SHCNE_ATTRIBUTES = $800;
  SHCNE_UPDATEDIR = $1000;
  SHCNE_UPDATEITEM = $2000;
  SHCNE_SERVERDISCONNECT = $4000;
  SHCNE_UPDATEIMAGE = $8000;
  SHCNE_DRIVEADDGUI = $10000;
  SHCNE_RENAMEFOLDER = $20000;
  SHCNE_FREESPACE = $40000;
  SHCNE_ASSOCCHANGED = $8000000;
  SHCNE_DISKEVENTS = $2381F;
  SHCNE_GLOBALEVENTS = $C0581E0;
  SHCNE_ALLEVENTS = $7FFFFFFF;
  SHCNE_INTERRUPT = $80000000;

  SHCNF_IDLIST = 0;               //  LPITEMIDLIST
  SHCNF_PATHA = $1;               // path name
  SHCNF_PRINTERA = $2;            // printer friendly name
  SHCNF_DWORD = $3;               // DWORD
  SHCNF_PATHW = $5;               // path name
  SHCNF_PRINTERW = $6;            // printer friendly name
  SHCNF_TYPE = $FF;

  SHCNF_FLUSH = $1000;

  SHCNF_FLUSHNOWAIT = $2000;
  SHCNF_PATH = SHCNF_PATHW;
  SHCNF_PRINTER = SHCNF_PRINTERW;

  WM_SHNOTIFY = $401;
  NOERROR = 0;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure WMShellReg(var Message:TMessage);message WM_SHNOTIFY;
  public
    { Public declarations }
  end;

type PSHNOTIFYSTRUCT=^SHNOTIFYSTRUCT;
  SHNOTIFYSTRUCT = record
    dwItem1 : PItemIDList;
    dwItem2 : PItemIDList;
  end;

Type PSHFileInfoByte=^SHFileInfoByte;
  _SHFileInfoByte = record
    hIcon :Integer;
    iIcon :Integer;
    dwAttributes : Integer;
    szDisplayName : array [0..259] of char;
    szTypeName : array [0..79] of char;
  end;
  SHFileInfoByte=_SHFileInfoByte;

Type PIDLSTRUCT = ^IDLSTRUCT;
  _IDLSTRUCT = record
    pidl : PItemIDList;
    bWatchSubFolders : Integer;
  end;
  IDLSTRUCT =_IDLSTRUCT;


function SHNotify_Register(hWnd : Integer) : Bool;
function SHNotify_UnRegister:Bool;
function SHEventName(strPath1,strPath2:string;lParam:Integer):string;

Function SHChangeNotifyDeregister(hNotify:integer):integer;stdcall;
         external Shell32.dll index 4;
Function SHChangeNotifyRegister(hWnd,uFlags,dwEventID,uMSG,cItems:LongWord;
         lpps:PIDLSTRUCT):integer;stdcall;external Shell32.dll index 2;
Function SHGetFileInfoPidl(pidl : PItemIDList;
         dwFileAttributes : Integer;
         psfib : PSHFILEINFOBYTE;
         cbFileInfo : Integer;
         uFlags : Integer):Integer;stdcall;
         external Shell32.dll name SHGetFileInfoA;

var
  Form1: TForm1;
  m_hSHNotify:Integer;
  m_pidlDesktop : PItemIDList;

implementation

{$R *.DFM}

function SHEventName(strPath1,strPath2:string;lParam:Integer):string;
var
  sEvent:String;
begin
  case lParam of        file://根据参数设置提示消息
    SHCNE_RENAMEITEM: sEvent := 重命名文件+strPath1+为+strpath2;
    SHCNE_CREATE: sEvent := 建立文件 文件名:+strPath1;
    SHCNE_DELETE: sEvent := 删除文件 文件名:+strPath1;
    SHCNE_MKDIR: sEvent := 新建目录 目录名:+strPath1;
    SHCNE_RMDIR: sEvent := 删除目录 目录名:+strPath1;
    SHCNE_MEDIAINSERTED: sEvent := strPath1+中插入可移动存储介质;
    SHCNE_MEDIAREMOVED: sEvent := strPath1+中移去可移动存储介质+strPath1+ +strpath2;
    SHCNE_DRIVEREMOVED: sEvent := 移去驱动器+strPath1;
    SHCNE_DRIVEADD: sEvent := 添加驱动器+strPath1;
    SHCNE_NETSHARE: sEvent := 改变目录+strPath1+的共享属性;

    SHCNE_ATTRIBUTES: sEvent := 改变文件目录属性 文件名+strPath1;
    SHCNE_UPDATEDIR: sEvent := 更新目录+strPath1;
    SHCNE_UPDATEITEM: sEvent := 更新文件 文件名:+strPath1;
    SHCNE_SERVERDISCONNECT: sEvent := 断开与服务器的连接+strPath1+ +strpath2;
    SHCNE_UPDATEIMAGE: sEvent := SHCNE_UPDATEIMAGE;
    SHCNE_DRIVEADDGUI: sEvent := SHCNE_DRIVEADDGUI;
    SHCNE_RENAMEFOLDER: sEvent := 重命名文件夹+strPath1+为+strpath2;
    SHCNE_FREESPACE: sEvent := 磁盘空间大小改变;
    SHCNE_ASSOCCHANGED: sEvent := 改变文件关联;
  else
    sEvent:=未知操作+IntToStr(lParam);
  end;
  Result:=sEvent;
end;

function SHNotify_Register(hWnd : Integer) : Bool;
var
  ps:PIDLSTRUCT;
begin
  {$R-}
  Result:=False;
  If m_hSHNotify = 0 then begin
    file://获取桌面文件夹的Pidl
    if SHGetSpecialFolderLocation(0, CSIDL_DESKTOP,
        m_pidlDesktop)<> NOERROR then
        Form1.close;
    if Boolean(m_pidlDesktop) then begin
      ps.bWatchSubFolders := 1;
      ps.pidl := m_pidlDesktop;

      // 利用SHChangeNotifyRegister函数注册系统消息处理
      m_hSHNotify := SHChangeNotifyRegister(hWnd, (SHCNF_TYPE Or SHCNF_IDLIST),
                                          (SHCNE_ALLEVENTS Or SHCNE_INTERRUPT),
                                          WM_SHNOTIFY, 1, ps);
      Result := Boolean(m_hSHNotify);
    end
    Else
      // 如果出现错误就使用 CoTaskMemFree函数来释放句柄
      CoTaskMemFree(m_pidlDesktop);
  End;
  {$R+}
end;

function SHNotify_UnRegister:Bool;
begin
  Result:=False;
  If Boolean(m_hSHNotify) Then
    file://取消系统消息监视,同时释放桌面的Pidl
    If Boolean(SHChangeNotifyDeregister(m_hSHNotify)) Then begin
      {$R-}
      m_hSHNotify := 0;
      CoTaskMemFree(m_pidlDesktop);
      Result := True;
      {$R-}
    End;
end;

procedure TForm1.WMShellReg(var Message:TMessage);      file://系统消息处理函数
var
  strPath1,strPath2:String;
  charPath:array[0..259]of char;
  pidlItem:PSHNOTIFYSTRUCT;
begin
  pidlItem:=PSHNOTIFYSTRUCT(Message.wParam);
  file://获得系统消息相关得路径
  SHGetPathFromIDList(pidlItem.dwItem1,charPath);
  strPath1:=charPath;
  SHGetPathFromIDList(pidlItem.dwItem2,charPath);
  strPath2:=charPath;

  Memo1.Lines.Add(SHEvEntName(strPath1,strPath2,Message.lParam)+chr(13)+chr(10));
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  file://在程序退出的同时删除监视
  if Boolean(m_pidlDesktop) then
    SHNotify_Unregister;
end;

procedure TForm1.Button1Click(Sender: TObject); file://Button1的Click消息
begin
  m_hSHNotify:=0;
  if SHNotify_Register(Form1.Handle) then begin file://注册Shell监视
    ShowMessage(Shell监视程序成功注册);
    Button1.Enabled := False;
  end
  else
    ShowMessage(Shell监视程序注册失败);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Button1.Caption := 打开监视;
end;

end.

    运行程序,点击“打开监视”按钮,如果出现一个显示“Shell监视程序成功注册”的对话框,说明Form1已经加入到系统操作监视链中了,
你可以试着在资源管理器中建立、删除文件夹,移动文件等操作,你可以发现这些操作都被纪录下来并显示在文本框中。
    在上面的程序中多次使用到了一个PItemIDList的结构,这个数据结构指定Windows下得一个“项目”,在Windows下资源实现统一管理
一个“项目”可以是一个文件或者一个文件夹,也可以是一个打印机等资源。另外一些API函数也涉及到了Shell(Windows外壳)操作,各位
读者可以参考相应的参考资料。


文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·ems图片格式转换(java)程序
·使用hashtable实现的购物车-ASP教程,ASP应用
·Java中数据库事务处理的实现-JSP教程,Java技巧及代码
·Oracle数据库操作类(c#)-.NET教程,C#语言
·移动短消息技术演进与业务发展浅析
·ASP生成静态网页,学习CASE的用法,以及“权限”的一种控制方法-ASP教程,组件开发
·中国电信发展移动通信的制式与频段选择
·ASP中access数据库的路径问题-ASP教程,数据库相关
·td-scdma系统移动台接入过程浅析
·JAVA与数据库连接方法(三)-JSP教程,数据库相关
最新文章
·fireworks表现vista毛玻璃朦胧效果_fireworks教程
·google adsense哪些情况会被k号_网赚技巧
·减少google adsense展示单元并不能提高收入_网赚技巧
·google adsense“允许域名”新功能很有用_网赚技巧
·于源:办南京人“淘宝”的大三学生_站长访谈
·谈谈网站策划和网站运营方面的点滴经验_站长心得
·美国网站兵败中国的10大思路性执行错误_站长心得
·付款流程中的电话确认_google推广
·google adsense的部分规则的背面_google推广
·googleadsense富翁排行榜最猛每月赚30万美元_google推广
相关主题
西部数码虚拟主机

友情链接
CNNIC 西部数码
万网 自助建站
虚拟主机 asp空间
域名注册 域名
域名申请 主页空间
论坛空间 网站空间
国际域名 虚拟空间
空间租用 DDOS防火墙
成都主机托管 四川主机托管
主机租用 服务器租用
网站目录 自助建站
虚拟主机 网址大全
软件下载
自助链接
虚拟主机资讯 特价虚拟主机
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
发表评论 打印  刷新     关闭