//changeNotification 监听资源管理器 import fsys; namespace win.util; class changeNotification { ctor( winform ){ if(!winform){ winform = ..win.form( {} ); winform.messageOnly(); } this._form = winform; this.notifyEntrys = {}; ..table.gc(this,"deregister"); }; clear = function(){ this.notifyEntrys = {}; this.deregister(); return this; }; watch = function(watchPath,recursive){ var shEntry = SHChangeNotifyEntry(); if( type(watchPath) == type.number ){ shEntry.pidl = ..fsys.getSpecial(watchPath,false) } else{ shEntry.pidl = watchPath ? ..fsys.idListFromPath(watchPath) } shEntry.fRecursive = recursive?1:0; ..table.push( this.notifyEntrys,shEntry); return this; }; register = function( message = 0x8F00/* _WM_USERDEF_FILECHANGED */,flags=0x1003/*_SHCNRF_InterruptLevel|_SHCNRF_ShellLevel|_SHCNRF_RecursiveInterrupt*/ ){ this.deregister(); var events = 0; for(e,name in _mapProcName){ if(this[name]) events = events | e ; } if( !events ) { error("请先指定需要启用的监视回调函数(函数名前缀为on)",2) } var size = #this.notifyEntrys; if( ! size ){ error("请先调用watch() 函数指定要监视的目录",2) } this.hDevNotify = SHChangeNotifyRegister(winform.hwnd, flags ,events,0x8F00/* _WM_USERDEF_FILECHANGED */,size, {struct entrys[] = this.notifyEntrys } ) if(!this.hDevNotify){ return; } //在回调消息表里插入新的消息处理,比直接新增回调函数有更好的效率 winform.wndproc = { [message] = function(hwnd,message,wParam,lParam){ if(!wParam)return 1; var procName = _mapProcName[lParam]; if(procName && this[procName] ){ var item1,item2; var shNotify = ..raw.convert( topointer(wParam),SHNOTIFYSTRUCT() ) if( shNotify.dwItem1 ){ item1 = ..fsys.pathFromIdList(shNotify.dwItem1); } if( shNotify.dwItem2 ){ item2 = ..fsys.pathFromIdList(shNotify.dwItem2); } return invoke(this[procName],this,item1,item2 ); } } [0x2/*_WM_DESTROY*/] = function(hwnd,message,wParam,lParam){ this.deregister(); } } }; deregister = function(){ if( this.hDevNotify ){ SHChangeNotifyDeregister(this.hDevNotify); this.hDevNotify = null; } }; } namespace changeNotification{ SHChangeNotifyRegister = ::Shell32.api(2,"pointer(int hwnd, int fSources,int fEvents,INT wMsg,int cEntries, struct pshcne)" ) SHChangeNotifyDeregister = ::Shell32.api(4,"bool(pointer ulID)" ) class SHChangeNotifyEntry{ pointer pidl; INT fRecursive; } class SHNOTIFYSTRUCT{ pointer dwItem1; pointer dwItem2; } _mapProcName = { [1/*_SHCNE_RENAMEITEM*/] = "onRenameItem"; [2/*_SHCNE_CREATE*/] = "onCreate"; [4/*_SHCNE_DELETE*/] = "onDelete"; [8/*_SHCNE_MKDIR*/] = "onMakeDir"; [0x10/*_SHCNE_RMDIR*/] = "onRemoveDir"; [0x20/*_SHCNE_MEDIAINSERTED*/] = "onMediaInserted"; [0x40/*_SHCNE_MEDIAREMOVED*/] = "onMediaRemoved"; [0x80/*_SHCNE_DRIVEREMOVED*/] = "onDriveRemoved"; [0x100/*_SHCNE_DRIVEADD*/] = "onDriveAdd"; [0x200/*_SHCNE_NETSHARE*/] = "onNetShare"; [0x400/*_SHCNE_NETUNSHARE*/] = "onNetUnShare"; [0x800/*_SHCNE_ATTRIBUTES*/] = "onAttributes"; [0x1000/*_SHCNE_UPDATEDIR*/] = "onUpdateDir"; [0x2000/*_SHCNE_UPDATEITEM*/] = "onUpdateItem"; [0x4000/*_SHCNE_SERVERDISCONNECT*/] = "onSeverDisconnect"; [0x8000/*_SHCNE_UPDATEIMAGE*/] = "onUpdateImage"; [0x10000/*_SHCNE_DRIVEADDGUI*/] = "onDriveAddGui"; [0x20000/*_SHCNE_RENAMEFOLDER*/] = "onRenameFolder"; [0x40000/*_SHCNE_FREESPACE*/] = "onFreeSpace"; [0x8000000/*_SHCNE_ASSOCCHANGED*/] = "onAssocChanged"; } } /**intellisense() win.util.changeNotification = 监听用户对资源管理器的操作 win.util.changeNotification(.(窗口对象) = 注册文件监听窗口\监听用户对资源管理器的操作,\n省略参数则创建 message only window win.util.changeNotification() = !wuChangeNotification. !wuChangeNotification._form = !winform. !wuChangeNotification.clear() = 清空所有监视路径并停止监视目录,返回对象自身\n!wuChangeNotification. !wuChangeNotification.watch() = !wuChangeNotification. !wuChangeNotification.watch(.(监视路径,是否监视子目录) = 添加监视路径,路径可以使用_CSIDL_开头的常量表示\n参数2为可选参数,返回对象自身 !wuChangeNotification.register(.(自定义消息,选项) = 注册并启用文件监视功能,\n所有参数都可以省略,默认使用 _WM_USERDEF_FILECHANGED 消息\n调用此函数以前,必须指定所有需要启用的事件回调函数 !wuChangeNotification.deregister() = 注销并关闭文件监听 !wuChangeNotification.onAttributes = @.onAttributes = function(srcPath,dstPath){\n __/*文件属性被改变*/\n} !wuChangeNotification.onRenameItem = @.onRenameItem = function(srcPath,dstPath){\n __/*非文件外壳对象名称被改变*/\n} !wuChangeNotification.onCreate = @.onCreate = function(srcPath,dstPath){\n __/*文件夹的外壳成员创建了*/\n} !wuChangeNotification.onDelete = @.onDelete = function(srcPath,dstPath){\n __/*非文件夹的外壳成员删除了*/\n} !wuChangeNotification.onMakeDir = @.onMakeDir = function(srcPath,dstPath){\n __/*目录被创建*/\n} !wuChangeNotification.onRemoveDir = @.onRemoveDir = function(srcPath,dstPath){\n __/*文件夹中的内容被改变*/\n} !wuChangeNotification.onMediaInserted = @.onMediaInserted = function(srcPath,dstPath){\n __/*存储介质被插入*/\n} !wuChangeNotification.onMediaRemoved = @.onMediaRemoved = function(srcPath,dstPath){\n __/*存储介质被删除*/\n} !wuChangeNotification.onDriveRemoved = @.onDriveRemoved = function(srcPath,dstPath){\n __/*驱动器被删除了*/\n} !wuChangeNotification.onDriveAdd = @.onDriveAdd = function(srcPath,dstPath){\n __/*添加了驱动器*/\n} !wuChangeNotification.onNetShare = @.onNetShare = function(srcPath,dstPath){\n __/*本地的目录被共享*/\n} !wuChangeNotification.onNetUnShare = @.onNetShare = function(srcPath,dstPath){\n __/*本地的目录取消共享*/\n} !wuChangeNotification.onUpdateDir = @.onUpdateDir = function(srcPath,dstPath){\n __/*文件夹中的内容被改变\n此目录下的较多文件变更可能被合并为此事件*/\n} !wuChangeNotification.onUpdateItem = @.onUpdateItem = function(srcPath,dstPath){\n __/*非文件夹外壳对象的名称被改变*/\n} !wuChangeNotification.onSeverDisconnect = @.onSeverDisconnect = function(srcPath,dstPath){\n __/*计算机被服务器断开*/\n} !wuChangeNotification.onUpdateImage = @.onUpdateImage = function(srcPath,dstPath){\n __/*系统图像列表中的图像被改变*/\n} !wuChangeNotification.onDriveAddGui = @.onDriveAddGui = function(srcPath,dstPath){\n __/*通过外壳添加的驱动器*/\n} !wuChangeNotification.onRenameFolder = @.onRenameFolder = function(srcPath,dstPath){\n __/*文件夹名称被改变*/\n} !wuChangeNotification.onFreeSpace = @.onFreeSpace = function(srcPath,dstPath){\n __/*驱动器剩余空间数变化*/\n} !wuChangeNotification.onAssocChanged = @.onAssocChanged = function(srcPath,dstPath){\n _/*文件关联被改变了*/\n} _WM_USERDEF_FILECHANGED = @0x8F00/* _WM_USERDEF_FILECHANGED */ _SHCNRF_InterruptLevel=@1/*_SHCNRF_InterruptLevel*/ _SHCNRF_ShellLevel=@2/*_SHCNRF_ShellLevel*/ _SHCNRF_RecursiveInterrupt=@0x1000/*_SHCNRF_RecursiveInterrupt*/ _SHCNRF_NewDelivery=@0x8000/*_SHCNRF_NewDelivery*/ _SHCNE_RENAMEITEM=@1/*_SHCNE_RENAMEITEM*/ _SHCNE_CREATE=@2/*_SHCNE_CREATE*/ _SHCNE_DELETE=@4/*_SHCNE_DELETE*/ _SHCNE_MKDIR=@8/*_SHCNE_MKDIR*/ _SHCNE_RMDIR=@0x10/*_SHCNE_RMDIR*/ _SHCNE_MEDIAINSERTED=@0x20/*_SHCNE_MEDIAINSERTED*/ _SHCNE_MEDIAREMOVED=@0x40/*_SHCNE_MEDIAREMOVED*/ _SHCNE_DRIVEREMOVED=@0x80/*_SHCNE_DRIVEREMOVED*/ _SHCNE_DRIVEADD=@0x100/*_SHCNE_DRIVEADD*/ _SHCNE_NETSHARE=@0x200/*_SHCNE_NETSHARE*/ _SHCNE_NETUNSHARE=@0x400/*_SHCNE_NETUNSHARE*/ _SHCNE_ATTRIBUTES=@0x800/*_SHCNE_ATTRIBUTES*/ _SHCNE_UPDATEDIR=@0x1000/*_SHCNE_UPDATEDIR*/ _SHCNE_UPDATEITEM=@0x2000/*_SHCNE_UPDATEITEM*/ _SHCNE_SERVERDISCONNECT=@0x4000/*_SHCNE_SERVERDISCONNECT*/ _SHCNE_UPDATEIMAGE=@0x8000/*_SHCNE_UPDATEIMAGE*/ _SHCNE_DRIVEADDGUI=@0x10000/*_SHCNE_DRIVEADDGUI*/ _SHCNE_RENAMEFOLDER=@0x20000/*_SHCNE_RENAMEFOLDER*/ _SHCNE_FREESPACE=@0x40000/*_SHCNE_FREESPACE*/ _SHCNE_ASSOCCHANGED=@0x8000000/*_SHCNE_ASSOCCHANGED*/ _SHCNE_DISKEVENTS=@0x2381F/*_SHCNE_DISKEVENTS*/ _SHCNE_GLOBALEVENTS=@0xC0581E0/*_SHCNE_GLOBALEVENTS*/ _SHCNE_ALLEVENTS=@0x7FFFFFFF/*_SHCNE_ALLEVENTS*/ _SHCNE_INTERRUPT=@0x80000000/*_SHCNE_INTERRUPT*/ _SHCNEE_ORDERCHANGED=@2/*_SHCNEE_ORDERCHANGED*/ _SHCNEE_MSI_CHANGE=@4/*_SHCNEE_MSI_CHANGE*/ _SHCNEE_MSI_UNINSTALL=@5/*_SHCNEE_MSI_UNINSTALL*/ _SHCNF_IDLIST=@0/*_SHCNF_IDLIST*/ _SHCNF_srcPath=@5/*_SHCNF_srcPath*/ _SHCNF_PRINTER=@2/*_SHCNF_PRINTER*/ _SHCNF_DWORD=@3/*_SHCNF_DWORD*/ _SHCNF_TYPE=@0xFF/*_SHCNF_TYPE*/ _SHCNF_FLUSH=@0x1000/*_SHCNF_FLUSH*/ _SHCNF_FLUSHNOWAIT=@0x3000/*_SHCNF_FLUSHNOWAIT*/ _SHCNF_NOTIFYRECURSIVE=@0x10000/*_SHCNF_NOTIFYRECURSIVE*/ end intellisense**/