type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Button1Click(Sender: TObject); private 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;
function SHNotify_Register(hWnd: Integer): Bool; var ps: IDLSTRUCT; begin {$R-} Result := False; if m_hSHNotify = 0 then begin //获取桌面文件夹的Pidl if SHGetSpecialFolderLocation(0, CSIDL_DESKTOP, m_pidlDesktop) <> NOERROR then begin form1.close; end; 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); //mmmmmmmm end else // 如果出现错误就使用 CoTaskMemFree函数来释放句柄 CoTaskMemFree(m_pidlDesktop); end; {$R+ } end;
function SHNotify_UnRegister: Bool; begin Result := False; if Boolean(m_hSHNotify) then begin //取消系统消息监视,同时释放桌面的Pidl if Boolean(SHChangeNotifyDeregister(m_hSHNotify)) then begin {$R-} m_hSHNotify := 0; CoTaskMemFree(m_pidlDesktop); Result := True; {$R-} end; end; end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin if Boolean(m_pidlDesktop) then SHNotify_Unregister; end;
procedure TForm1.Button1Click(Sender: TObject); begin m_hSHNotify := 0; if SHNotify_Register(self.Handle) then begin //注册Shell监视 ShowMessage('Shell监视程序成功注册'); Button1.Enabled := False; end else ShowMessage('Shell监视程序注册失败'); end;