给你个好东西,用类做的。可监视多种文件操作动作。<br>http://www.howtodothings.com/showarticle.asp?article=314<br>那上面还有许多可学习的,如果你的英文够好。<br><br>If you have ever needed to know when the shell issues an event here is a<br> wrapper around SHChangeNotifyRegister wich allows you to know the kind of <br>event and the file(s) affected, this component is in stage 1 of developement <br>however it offers the whole functionality.<br><br>The component itself is composed of enhancements made to TSHChangeNotify <br>component by Elliott Shevin (shevine@aol.com)<br><br>By the way here is a list of things you should be aware when using this <br>component for instance restoring an item from the recycle bin to the original <br>location turn on a rename event, while you get a notification over an event <br>you cannot stop it you just get notified of it.<br><br>Deleting an Item causes 3 events: OnFileDelete (When the dialog, or the lack<br> of, is displayed normally this is before the deletion of the file) an<br> OnFolderUpdate (after the element is removed and the folder refreshes) and <br>surprise yet another OnFileDelete (after the file has completely been deleted)<br> this behavior is not of the component but of the api it relies on.<br><br>Also according to some documentation I read the apis used on this article are <br>entirely undocumented, perhaps it can be possible to stop the event however <br>due to lack of documentation, it is unknown to me.<br><br><-------------- Begin UNIT code ----------------------------><br>{$IFNDEF VER80} {$IFNDEF VER90} {$IFNDEF VER93}<br> {$DEFINE Delphi3orHigher}<br>{$ENDIF} {$ENDIF} {$ENDIF}<br><br>unit ShellNotify;<br>interface<br><br>uses Windows, Messages, SysUtils, Classes, Controls, Forms, Dialogs,<br> {$IFNDEF Delphi3orHigher} OLE2, {$ELSE} ActiveX, ComObj, {$ENDIF}<br> ShlObj;<br><br>type<br> NOTIFYREGISTER = record<br> pidlPath : PItemIDList;<br> bWatchSubtree : boolean;<br> end;<br> PNOTIFYREGISTER = ^NOTIFYREGISTER;<br><br>const<br> SNM_SHELLNOTIFICATION = WM_USER +1;<br> SHCNF_ACCEPT_INTERRUPTS = $0001;<br> SHCNF_ACCEPT_NON_INTERRUPTS = $0002;<br> SHCNF_NO_PROXY = $8000;<br><br>type<br> TNotificationEvent = (neAssociationChange, neAttributesChange,<br> neFileChange, neFileCreate, neFileDelete, neFileRename,<br> neDriveAdd, neDriveRemove, neShellDriveAdd, neDriveSpaceChange,<br> neMediaInsert, neMediaRemove, neFolderCreate, neFolderDelete,<br> neFolderRename, neFolderUpdate, neNetShare, neNetUnShare,<br> neServerDisconnect, neImageListChange);<br> TNotificationEvents = set of TNotificationEvent;<br><br> TShellNotificationEvent1 = procedure(Sender: TObject;<br> Path: String)of Object;<br> TShellNotificationEvent2 = procedure(Sender: TObject;<br> path1, path2: String) of Object;<br><br> TShellNotification = class(TComponent)<br> private<br> fWatchEvents: TNotificationEvents;<br> fPath: String;<br> fActive, fWatch: Boolean;<br><br> prevPath1, prevPath2: String;<br> PrevEvent: Integer;<br><br> Handle, NotifyHandle: HWND;<br><br> fOnAssociationChange: TNotifyEvent;<br> fOnAttribChange: TShellNotificationEvent2;<br> FOnCreate: TShellNotificationEvent1;<br> FOnDelete: TShellNotificationEvent1;<br> FOnDriveAdd: TShellNotificationEvent1;<br> FOnDriveAddGui: TShellNotificationEvent1;<br> FOnDriveRemove: TShellNotificationEvent1;<br> FOnMediaInsert: TShellNotificationEvent1;<br> FOnMediaRemove: TShellNotificationEvent1;<br> FOnDirCreate: TShellNotificationEvent1;<br> FOnNetShare: TShellNotificationEvent1;<br> FOnNetUnShare: TShellNotificationEvent1;<br> FOnRenameFolder: TShellNotificationEvent2;<br> FOnItemRename: TShellNotificationEvent2;<br> FOnFolderRemove: TShellNotificationEvent1;<br> FOnServerDisconnect: TShellNotificationEvent1;<br> FOnFolderUpdate: TShellNotificationEvent1;<br><br> function PathFromPidl(Pidl: PItemIDList): String;<br> procedure SetWatchEvents(const Value: TNotificationEvents);<br><br> function GetActive: Boolean;<br> procedure SetActive(const Value: Boolean);<br><br> procedure SetPath(const Value: String);<br> procedure SetWatch(const Value: Boolean);<br> protected<br> procedure ShellNotifyRegister;<br> procedure ShellNotifyUnregister;<br> procedure WndProc(var Message: TMessage);<br><br> procedure DoAssociationChange; dynamic;<br> procedure DoAttributesChange(Path1, Path2: String); dynamic;<br> procedure DoCreateFile(Path: String); dynamic;<br> procedure DoDeleteFile(Path: String); dynamic;<br> procedure DoDriveAdd(Path:String); dynamic;<br> procedure DoDriveAddGui(Path: String); dynamic;<br> procedure DoDriveRemove(Path: String); dynamic;<br> procedure DoMediaInsert(Path: String); dynamic;<br> procedure DoMediaRemove(Path: String); dynamic;<br> procedure DoDirCreate(Path: String); dynamic;<br> procedure DoNetShare(Path: String); dynamic;<br> procedure DoNetUnShare(Path: String); dynamic;<br> procedure DoRenameFolder(Path1, Path2: String); dynamic;<br> procedure DoRenameItem(Path1, Path2: String); dynamic;<br> procedure DoFolderRemove(Path: String); dynamic;<br> procedure DoServerDisconnect(Path: String); dynamic;<br> procedure DoDirUpdate(Path: String); dynamic;<br> public<br> constructor Create(AOwner: TComponent); override;<br> destructor Destroy; override;<br> published<br> property Path: String read fPath write SetPath;<br> property Active: Boolean read GetActive write SetActive;<br> property WatchSubTree: Boolean read fWatch write SetWatch;<br><br> property WatchEvents: TNotificationEvents<br> read fWatchEvents write SetWatchEvents;<br><br> property OnAssociationChange: TNotifyEvent<br> read fOnAssociationChange write FOnAssociationChange;<br><br> property OnAttributesChange: TShellNotificationEvent2<br> read fOnAttribChange write fOnAttribChange;<br><br> property OnFileCreate: TShellNotificationEvent1<br> read FOnCreate write FOnCreate;<br><br> property OnFolderRename: TShellNotificationEvent2<br> read FOnRenameFolder write FOnRenameFolder;<br><br> property OnFolderUpdate: TShellNotificationEvent1<br> read FOnFolderUpdate write FOnFolderUpdate;<br><br> property OnFileDelete: TShellNotificationEvent1<br> read FOnDelete write FOnDelete;<br><br> property OnDriveAdd: TShellNotificationEvent1<br> read FOnDriveAdd write FOnDriveAdd;<br><br> property OnFolderRemove: TShellNotificationEvent1<br> read FOnFolderRemove write FOnFolderRemove;<br><br> property OnItemRename: TShellNotificationEvent2<br> read FOnItemRename write FOnItemRename;<br><br> property OnDriveAddGui: TShellNotificationEvent1<br> read FOnDriveAddGui write FOnDriveAddGui;<br><br> property OnDriveRemove: TShellNotificationEvent1<br> read FOnDriveRemove write FOnDriveRemove;<br><br> property OnMediaInserted: TShellNotificationEvent1<br> read FOnMediaInsert write FOnMediaInsert;<br><br> property OnMediaRemove: TShellNotificationEvent1<br> read FOnMediaRemove write FOnMediaRemove;<br><br> property OnDirCreate: TShellNotificationEvent1<br> read FOnDirCreate write FOnDirCreate;<br><br> property OnNetShare: TShellNotificationEvent1<br> read FOnNetShare write FOnNetShare;<br><br> property OnNetUnShare: TShellNotificationEvent1<br> read FOnNetUnShare write FOnNetUnShare;<br><br> property OnServerDisconnect: TShellNotificationEvent1<br> read FOnServerDisconnect write FOnServerDisconnect;<br> end;<br><br> function SHChangeNotifyRegister( hWnd: HWND; dwFlags: integer;<br> wEventMask : cardinal; uMsg: UINT; cItems : integer;<br> lpItems : PNOTIFYREGISTER) : HWND; stdcall;<br> function SHChangeNotifyDeregister(hWnd: HWND) : boolean; stdcall;<br> function SHILCreateFromPath(Path: Pointer; PIDL: PItemIDList;<br> var Attributes: ULONG):HResult; stdcall;<br><br> procedure Register;<br><br>implementation<br><br>const Shell32DLL = 'shell32.dll';<br><br> function SHChangeNotifyRegister; external Shell32DLL index 2;<br> function SHChangeNotifyDeregister; external Shell32DLL index 4;<br> function SHILCreateFromPath; external Shell32DLL index 28;<br><br>{ TShellNotification }<br><br>constructor TShellNotification.Create(AOwner: TComponent);<br>begin<br> inherited Create( AOwner );<br> if not (csDesigning in ComponentState) then<br> Handle := AllocateHWnd(WndProc);<br> PrevEvent := 0;<br> fWatchEvents := [neAssociationChange, neAttributesChange,<br> neFileChange, neFileCreate, neFileDelete, neFileRename,<br> neDriveAdd, neDriveRemove, neShellDriveAdd, neDriveSpaceChange,<br> neMediaInsert, neMediaRemove, neFolderCreate, neFolderDelete,<br> neFolderRename, neFolderUpdate, neNetShare, neNetUnShare,<br> neServerDisconnect, neImageListChange];<br>end;<br><br>destructor TShellNotification.Destroy;<br>begin<br> if not (csDesigning in ComponentState) then<br> Active := False;<br> if Handle <> 0 then DeallocateHWnd( Handle );<br> inherited Destroy;<br>end;<br><br>procedure TShellNotification.DoAssociationChange;<br>begin<br> if Assigned( fOnAssociationChange ) and (neAssociationChange in fWatchEvents) then<br> fOnAssociationChange( Self );<br>end;<br><br>procedure TShellNotification.DoAttributesChange;<br>begin<br> if Assigned( fOnAttribChange ) then<br> fOnAttribChange( Self, Path1, Path2 );<br>end;<br><br>procedure TShellNotification.DoCreateFile(Path: String);<br>begin<br> if Assigned( fOnCreate ) then<br> FOnCreate(Self, Path)<br>end;<br><br>procedure TShellNotification.DoDeleteFile(Path: String);<br>begin<br> if Assigned( FOnDelete ) then<br> FOnDelete(Self, Path);<br>end;<br><br>procedure TShellNotification.DoDirCreate(Path: String);<br>begin<br> if Assigned( FOnDirCreate ) then<br> FOnDirCreate( Self, Path );<br>end;<br><br>procedure TShellNotification.DoDirUpdate(Path: String);<br>begin<br> if Assigned( FOnFolderUpdate ) then<br> FOnFolderUpdate(Self, Path);<br>end;<br><br>procedure TShellNotification.DoDriveAdd(Path: String);<br>begin<br> if Assigned( FOnDriveAdd ) then<br> FOnDriveAdd(Self, Path);<br>end;<br><br>procedure TShellNotification.DoDriveAddGui(Path: String);<br>begin<br> if Assigned( FOnDriveAddGui ) then<br> FOnDriveAdd(Self, Path);<br>end;<br><br>procedure TShellNotification.DoDriveRemove(Path: String);<br>begin<br> if Assigned( FOnDriveRemove ) then<br> FOnDriveRemove(Self, Path);<br>end;<br><br>procedure TShellNotification.DoFolderRemove(Path: String);<br>begin<br> if Assigned(FOnFolderRemove) then<br> FOnFolderRemove( Self, Path );<br>end;<br><br>procedure TShellNotification.DoMediaInsert(Path: String);<br>begin<br> if Assigned( FOnMediaInsert ) then<br> FOnMediaInsert(Self, Path);<br>end;<br><br>procedure TShellNotification.DoMediaRemove(Path: String);<br>begin<br> if Assigned(FOnMediaRemove) then<br> FOnMediaRemove(Self, Path);<br>end;<br><br>procedure TShellNotification.DoNetShare(Path: String);<br>begin<br> if Assigned(FOnNetShare) then<br> FOnNetShare(Self, Path);<br>end;<br><br>procedure TShellNotification.DoNetUnShare(Path: String);<br>begin<br> if Assigned(FOnNetUnShare) then<br> FOnNetUnShare(Self, Path);<br>end;<br><br>procedure TShellNotification.DoRenameFolder(Path1, Path2: String);<br>begin<br> if Assigned( FOnRenameFolder ) then<br> FOnRenameFolder(Self, Path1, Path2);<br>end;<br><br>procedure TShellNotification.DoRenameItem(Path1, Path2: String);<br>begin<br> if Assigned( FOnItemRename ) then<br> FonItemRename(Self, Path1, Path2);<br>end;<br><br>procedure TShellNotification.DoServerDisconnect(Path: String);<br>begin<br> if Assigned( FOnServerDisconnect ) then<br> FOnServerDisconnect(Self, Path);<br>end;<br><br>function TShellNotification.GetActive: Boolean;<br>begin<br> Result := (NotifyHandle <> 0) and (fActive);<br>end;<br><br>function TShellNotification.PathFromPidl(Pidl: PItemIDList): String;<br>begin<br> SetLength(Result, Max_Path);<br> if not SHGetPathFromIDList(Pidl, PChar(Result)) then Result := '';<br> if pos(#0, Result) > 0 then<br> SetLength(Result, pos(#0, Result));<br>end;<br><br>procedure TShellNotification.SetActive(const Value: Boolean);<br>begin<br> if (Value <> fActive) then<br> begin<br> fActive := Value;<br> if fActive then ShellNotifyRegister else ShellNotifyUnregister;<br> end;<br>end;<br><br>procedure TShellNotification.SetPath(const Value: String);<br>begin<br> if fPath <> Value then<br> begin<br> fPath := Value;<br> ShellNotifyRegister;<br> end;<br>end;<br><br>procedure TShellNotification.SetWatch(const Value: Boolean);<br>begin<br> if fWatch <> Value then<br> begin<br> fWatch := Value;<br> ShellNotifyRegister;<br> end;<br>end;<br><br>procedure TShellNotification.SetWatchEvents(<br> const Value: TNotificationEvents);<br>begin<br> if fWatchEvents <> Value then<br> begin<br> fWatchEvents := Value;<br> ShellNotifyRegister;<br> end;<br>end;<br><br>procedure TShellNotification.ShellNotifyRegister;<br>var<br> Option: TNotificationEvent;<br> NotifyRecord: NOTIFYREGISTER;<br> Flags: DWORD;<br> Pidl: PItemIDList;<br> Attributes: ULONG;<br>const<br> NotifyFlags: array[TNotificationEvent] of DWORD = (<br> SHCNE_ASSOCCHANGED, SHCNE_ATTRIBUTES, SHCNE_UPDATEITEM,<br> SHCNE_CREATE, SHCNE_DELETE, SHCNE_RENAMEITEM, SHCNE_DRIVEADD,<br> SHCNE_DRIVEREMOVED, SHCNE_DRIVEADDGUI, SHCNE_FREESPACE,<br> SHCNE_MEDIAINSERTED, SHCNE_MEDIAREMOVED, SHCNE_MKDIR,<br> SHCNE_RMDIR, SHCNE_RENAMEFOLDER, SHCNE_UPDATEDIR,<br> SHCNE_NETSHARE, SHCNE_NETUNSHARE, SHCNE_SERVERDISCONNECT,<br> SHCNE_UPDATEIMAGE);<br>begin<br> ShellNotifyUnregister;<br> if not (csDesigning in ComponentState) and<br> not (csLoading in ComponentState) then<br> begin<br> SHILCreatefromPath( PChar(fPath), Addr(Pidl), Attributes);<br> NotifyRecord.pidlPath := Pidl;<br> NotifyRecord.bWatchSubtree := fWatch;<br><br> Flags := 0;<br> for Option := Low(Option) to High(Option) do<br> if (Option in FWatchEvents) then<br> Flags := Flags or NotifyFlags[Option];<br><br> NotifyHandle := SHChangeNotifyRegister(Handle,<br> SHCNF_ACCEPT_INTERRUPTS or SHCNF_ACCEPT_NON_INTERRUPTS,<br> Flags, SNM_SHELLNOTIFICATION, 1, @NotifyRecord);<br> end;<br>end;<br><br>procedure TShellNotification.ShellNotifyUnregister;<br>begin<br> if NotifyHandle <> 0 then<br> SHChangeNotifyDeregister(NotifyHandle);<br>end;<br><br>procedure TShellNotification.WndProc(var Message: TMessage);<br>type<br> TPIDLLIST = record<br> pidlist : array[1..2] of PITEMIDLIST;<br> end;<br> PIDARRAY = ^TPIDLLIST;<br>var<br> Path1 : string;<br> Path2 : string;<br> ptr : PIDARRAY;<br> repeated : boolean;<br> event : longint;<br><br>begin<br> case Message.Msg of<br> SNM_SHELLNOTIFICATION:<br> begin<br> event := Message.LParam and ($7FFFFFFF);<br> Ptr := PIDARRAY(Message.WParam);<br><br> Path1 := PathFromPidl( Ptr^.pidlist[1] );<br> Path2 := PathFromPidl( Ptr^.pidList[2] );<br><br> repeated := (PrevEvent = event)<br> and (uppercase(prevpath1) = uppercase(Path1))<br> and (uppercase(prevpath2) = uppercase(Path2));<br><br> if Repeated then exit;<br><br> PrevEvent := Message.Msg;<br> prevPath1 := Path1;<br> prevPath2 := Path2;<br><br> case event of<br> SHCNE_ASSOCCHANGED : DoAssociationChange;<br> SHCNE_ATTRIBUTES : DoAttributesChange( Path1, Path2);<br> SHCNE_CREATE : DoCreateFile(Path1);<br> SHCNE_DELETE : DoDeleteFile(Path1);<br> SHCNE_DRIVEADD : DoDriveAdd(Path1);<br> SHCNE_DRIVEADDGUI : DoDriveAddGui(path1);<br> SHCNE_DRIVEREMOVED : DoDriveRemove(Path1);<br> SHCNE_MEDIAINSERTED : DoMediaInsert(Path1);<br> SHCNE_MEDIAREMOVED : DoMediaRemove(Path1);<br> SHCNE_MKDIR : DoDirCreate(Path1);<br> SHCNE_NETSHARE : DoNetShare(Path1);<br> SHCNE_NETUNSHARE : DoNetUnShare(Path1);<br> SHCNE_RENAMEFOLDER : DoRenameFolder(Path1, Path2);<br> SHCNE_RENAMEITEM : DoRenameItem(Path1, Path2);<br> SHCNE_RMDIR : DoFolderRemove(Path1);<br> SHCNE_SERVERDISCONNECT : DoServerDisconnect(Path);<br> SHCNE_UPDATEDIR : DoDirUpdate(Path);<br> SHCNE_UPDATEIMAGE : ;<br> SHCNE_UPDATEITEM : ;<br> end;//Case event of<br> end;//SNM_SHELLNOTIFICATION<br> end; //case<br>end;<br><br>procedure Register;<br>begin<br> RegisterComponents('Shell', [TShellNotification]);<br>end;<br><br>end.<br><------------------ End Unit Code --------------------------><br><br>还有下面的。。。<br><br>你是否想为你的Windows加上一双眼睛,察看使用者在机器上所做的各种操作(例如建立、删除文件;改变文件或目录名字)呢?<br><br> 这里介绍一种利用Windows未公开函数实现这个功能的方法。<br><br> 在Windows下有一个未公开函数SHChangeNotifyRegister可以把你的窗口添加到系统的系统消息监视链中,该函数在Delphi中的定义如下:<br><br> Function SHChangeNotifyRegister(hWnd,uFlags,dwEventID,uMSG,cItems:LongWord;<br> lpps
IDLSTRUCT):integer;stdcall;external 'Shell32.dll' index 2;<br><br> 其中参数hWnd定义了监视系统操作的窗口得句柄,参数uFlags dwEventID定义监视操作参数,参数uMsg定义操作消息,参数cItems定义附加参数,参数lpps指定一个PIDLSTRUCT结构,该结构指定监视的目录。<br><br> 当函数调用成功之后,函数会返回一个监视操作句柄,同时系统就会将hWnd指定的窗口加入到操作监视链中,当有文件操作发生时,系统会向hWnd发送uMsg指定的消息,我们只要在程序中加入该消息的处理函数就可以实现对系统操作的监视了。<br><br> 如果要退出程序监视,就要调用另外一个未公开得函数SHChangeNotifyDeregister来取消程序监视。<br><br> 下面是使用Delphi编写的具体程序实现范例,首先建立一个新的工程文件,然后在Form1中加入一个Button控件和一个Memo控件,<br><br> 程序的代码如下:<br><br> unit Unit1;<br> interface<br> uses<br> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br> StdCtrls,shlobj,Activex;<br> const<br> SHCNE_RENAMEITEM = $1;<br> SHCNE_CREATE = $2;<br> SHCNE_DELETE = $4;<br> SHCNE_MKDIR = $8;<br> SHCNE_RMDIR = $10;<br> SHCNE_MEDIAINSERTED = $20;<br> SHCNE_MEDIAREMOVED = $40;<br> SHCNE_DRIVEREMOVED = $80;<br> SHCNE_DRIVEADD = $100;<br> SHCNE_NETSHARE = $200;<br> SHCNE_NETUNSHARE = $400;<br> SHCNE_ATTRIBUTES = $800;<br> SHCNE_UPDATEDIR = $1000;<br> SHCNE_UPDATEITEM = $2000;<br> SHCNE_SERVERDISCONNECT = $4000;<br> SHCNE_UPDATEIMAGE = $8000;<br> SHCNE_DRIVEADDGUI = $10000;<br> SHCNE_RENAMEFOLDER = $20000;<br> SHCNE_FREESPACE = $40000;<br> SHCNE_ASSOCCHANGED = $8000000;<br> SHCNE_DISKEVENTS = $2381F;<br> SHCNE_GLOBALEVENTS = $C0581E0;<br> SHCNE_ALLEVENTS = $7FFFFFFF;<br> SHCNE_INTERRUPT = $80000000;<br> SHCNF_IDLIST = 0;<br> // LPITEMIDLIST<br> SHCNF_PATHA = $1;<br> // path name<br> SHCNF_PRINTERA = $2;<br> // printer friendly name<br> SHCNF_DWORD = $3;<br> // DWORD<br> SHCNF_PATHW = $5;<br> // path name<br> SHCNF_PRINTERW = $6;<br> // printer friendly name<br> SHCNF_TYPE = $FF;<br> SHCNF_FLUSH = $1000;<br> SHCNF_FLUSHNOWAIT = $2000;<br> SHCNF_PATH = SHCNF_PATHW;<br> SHCNF_PRINTER = SHCNF_PRINTERW;<br> WM_SHNOTIFY = $401;<br> NOERROR = 0;<br> type<br> TForm1 = class(TForm)<br> Button1: TButton;<br> Memo1: TMemo;<br> procedure FormClose(Sender: TObject; var Action: TCloseAction);<br> procedure Button1Click(Sender: TObject);<br> procedure FormCreate(Sender: TObject);<br> private<br> { Private declarations }<br> procedure WMShellReg(var Message:TMessage);message WM_SHNOTIFY;<br> public<br> { Public declarations }<br> end;<br> type PSHNOTIFYSTRUCT=^SHNOTIFYSTRUCT;<br> SHNOTIFYSTRUCT = record<br> dwItem1 : PItemIDList;<br> dwItem2 : PItemIDList;<br> end;<br> Type PSHFileInfoByte=^SHFileInfoByte;<br> _SHFileInfoByte = record<br> hIcon :Integer;<br> iIcon :Integer;<br> dwAttributes : Integer;<br> szDisplayName : array [0..259] of char;<br> szTypeName : array [0..79] of char;<br> end;<br> SHFileInfoByte=_SHFileInfoByte;<br> Type PIDLSTRUCT = ^IDLSTRUCT;<br> _IDLSTRUCT = record<br> pidl : PItemIDList;<br> bWatchSubFolders : Integer;<br> end;<br> IDLSTRUCT =_IDLSTRUCT;<br> function SHNotify_Register(hWnd : Integer) : Bool;<br> function SHNotify_UnRegister:Bool;<br> function SHEventName(strPath1,strPath2:string;lParam:Integer):string;<br> Function SHChangeNotifyDeregister(hNotify:integer):integer;stdcall;<br> external 'Shell32.dll' index 4;<br> Function SHChangeNotifyRegister(hWnd,uFlags,dwEventID,uMSG,cItems:LongWord;<br> lpps
IDLSTRUCT):integer;stdcall;external 'Shell32.dll' index 2;<br> Function SHGetFileInfoPidl(pidl : PItemIDList;<br> dwFileAttributes : Integer;<br> psfib : PSHFILEINFOBYTE;<br> cbFileInfo : Integer;<br> uFlags : Integer):Integer;stdcall;<br> external 'Shell32.dll' name 'SHGetFileInfoA';<br> var<br> Form1: TForm1;<br> m_hSHNotify:Integer;<br> m_pidlDesktop : PItemIDList;<br> implementation<br> {$R *.DFM}<br> function SHEventName(strPath1,strPath2:string;lParam:Integer):string;<br> var<br> sEvent:String;<br> begin<br> case lParam of //根据参数设置提示消息<br> SHCNE_RENAMEITEM: sEvent := '重命名文件'+strPath1+'为'+strpath2;<br> SHCNE_CREATE: sEvent := '建立文件 文件名:'+strPath1;<br> SHCNE_DELETE: sEvent := '删除文件 文件名:'+strPath1;<br> SHCNE_MKDIR: sEvent := '新建目录 目录名:'+strPath1;<br> SHCNE_RMDIR: sEvent := '删除目录 目录名:'+strPath1;<br> SHCNE_MEDIAINSERTED: sEvent := strPath1+'中插入可移动存储介质';<br> SHCNE_MEDIAREMOVED: sEvent := strPath1+'中移去可移动存储介质'+strPath1+' '+strpath2;<br> SHCNE_DRIVEREMOVED: sEvent := '移去驱动器'+strPath1;<br> SHCNE_DRIVEADD: sEvent := '添加驱动器'+strPath1;<br> SHCNE_NETSHARE: sEvent := '改变目录'+strPath1+'的共享属性';<br> SHCNE_ATTRIBUTES: sEvent := '改变文件目录属性 文件名'+strPath1;<br> SHCNE_UPDATEDIR: sEvent := '更新目录'+strPath1;<br> SHCNE_UPDATEITEM: sEvent := '更新文件 文件名:'+strPath1;<br> SHCNE_SERVERDISCONNECT: sEvent := '断开与服务器的连接'+strPath1+' '+strpath2;<br> SHCNE_UPDATEIMAGE: sEvent := 'SHCNE_UPDATEIMAGE';<br> SHCNE_DRIVEADDGUI: sEvent := 'SHCNE_DRIVEADDGUI';<br> SHCNE_RENAMEFOLDER: sEvent := '重命名文件夹'+strPath1+'为'+strpath2;<br> SHCNE_FREESPACE: sEvent := '磁盘空间大小改变';<br> SHCNE_ASSOCCHANGED: sEvent := '改变文件关联';<br> else<br> sEvent:='未知操作'+IntToStr(lParam);<br> end;<br> Result:=sEvent;<br> end;<br> function SHNotify_Register(hWnd : Integer) : Bool;<br> var<br> ps
IDLSTRUCT;<br> begin<br> {$R-}<br> Result:=False;<br> If m_hSHNotify = 0 then begin<br> //获取桌面文件夹的Pidl<br> if SHGetSpecialFolderLocation(0, CSIDL_DESKTOP,<br> m_pidlDesktop)<> NOERROR then<br> Form1.close;<br> if Boolean(m_pidlDesktop) then begin<br> ps.bWatchSubFolders := 1;<br> ps.pidl := m_pidlDesktop;<br> // 利用SHChangeNotifyRegister函数注册系统消息处理<br> m_hSHNotify := SHChangeNotifyRegister(hWnd, (SHCNF_TYPE Or SHCNF_IDLIST),<br> (SHCNE_ALLEVENTS Or SHCNE_INTERRUPT),<br> WM_SHNOTIFY, 1, ps);<br> Result := Boolean(m_hSHNotify);<br> end<br> Else<br> // 如果出现错误就使用 CoTaskMemFree函数来释放句柄<br> CoTaskMemFree(m_pidlDesktop);<br> End;<br> {$R+}<br> end;<br> function SHNotify_UnRegister:Bool;<br> begin<br> Result:=False;<br> If Boolean(m_hSHNotify) Then<br> //取消系统消息监视,同时释放桌面的Pidl<br> If Boolean(SHChangeNotifyDeregister(m_hSHNotify)) Then begin<br> {$R-}<br> m_hSHNotify := 0;<br> CoTaskMemFree(m_pidlDesktop);<br> Result := True;<br> {$R-}<br> End;<br> end;<br> procedure TForm1.WMShellReg(var Message:TMessage); //系统消息处理函数<br> var<br> strPath1,strPath2:String;<br>charPath:array[0..259]of char;<br> pidlItem
SHNOTIFYSTRUCT;<br> begin<br> pidlItem:=PSHNOTIFYSTRUCT(Message.wParam);<br> //获得系统消息相关得路径<br> SHGetPathFromIDList(pidlItem.dwItem1,charPath);<br> strPath1:=charPath;<br> SHGetPathFromIDList(pidlItem.dwItem2,charPath);<br> strPath2:=charPath;<br> Memo1.Lines.Add(SHEvEntName(strPath1,strPath2,Message.lParam)+chr(13)+chr(10));<br> end;<br> procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);<br> begin<br> //在程序退出的同时删除监视<br> if Boolean(m_pidlDesktop) then<br> SHNotify_Unregister;<br> end;<br> procedure TForm1.Button1Click(Sender: TObject); //Button1的Click消息<br> begin<br> m_hSHNotify:=0;<br> if SHNotify_Register(Form1.Handle) then begin //注册Shell监视<br> ShowMessage('Shell监视程序成功注册');<br> Button1.Enabled := False;<br> end<br> else<br> ShowMessage('Shell监视程序注册失败');<br> end;<br> procedure TForm1.FormCreate(Sender: TObject);<br> begin<br> Button1.Caption := '打开监视';<br> end;<br> end.<br><br> 运行程序,点击“打开监视”按钮,如果出现一个显示“Shell监视程序成功注册”的对话框,说明Form1已经加入到系统操作监视链中了,你可以试着在资源管理器中建立、删除文件夹,移动文件等操作,你可以发现这些操作都被记录下来并显示在文本框中。<br><br> 在上面的程序中多次使用到了一个PItemIDList的结构,这个数据结构指定Windows下得一个“项目”,在Windows下资源实现统一管理一个“项目”可以是一个文件或者一个文件夹,也可以是一个打印机等资源。另外一些API函数也涉及到了Shell(Windows外壳)操作,各位读者可以参考相应的参考资料。<br><br> 由于使用到了Windows的未公开函数,没有相关得参考资料,所以有一些未知得操作(在Memo1中会显示“未知操作”)。如果哪位读者有兴趣, http://member.netease.com/~blackcat 有实现该功能的VB程序下载。<br><br> 以上程序在Windows98、Windows2000、Delphi5下运行通过。<br><br><br>