New Lexer:
;Function WatchDirectory()
;
;Parameters
;      WatchFolder         - Specify a valid path to watch for changes in.
;                     - can be directory or drive (e.g. c:\ or c:\Temp)
;                     - can be network path e.g. \\192.168.2.101\Shared)
;                     - can include last backslash. e.g. C:\Temp\ (will be reported same form)
;
;      WatchSubDirs      - Specify whether to search in subfolders
;
;StopWatching   -   THIS SHOULD BE DONE BEFORE EXITING SCRIPT AT LEAST (OnExit)
;      Call WatchDirectory() without parameters to stop watching all directories
;
;ReportChanges
;      Call WatchDirectory("ReportingFunctionName") to process registered changes.
;      Syntax of ReportingFunctionName(Action,Folder,File)
;
;      Example
/*
      #Persistent
      OnExit,Exit
      WatchDirectory("C:\Windows",1)
      SetTimer,WatchFolder,100
      Return
      WatchFolder:
         WatchDirectory("RegisterChanges")
      Return
      RegisterChanges(action,folder,file){
         static
         #1:="New File", #2:="Deleted", #3:="Modified", #4:="Renamed From", #5:="Renamed To"
         ToolTip % #%Action% "`n" folder . (SubStr(folder,0)="\" ? "" : "\") . file
      }   
      Exit:
         WatchDirectory()
      ExitApp
*/

WatchDirectory(WatchFolder="", WatchSubDirs=true)
{
   static
   local hDir, hEvent, r, Action, FileNameLen, pFileName, Restart, CurrentFolder, PointerFNI, _SizeOf_FNI_=65536
   nReadLen := 0
   If !(WatchFolder){
      Gosub, StopWatchingDirectories
    } else if IsFunc(WatchFolder) {
      r := DllCall("MsgWaitForMultipleObjectsEx", UInt, DirIdx, UInt, &DirEvents, UInt, -1, UInt, 0x4FF, UInt, 0x6) ;Timeout=-1
      if !(r >= 0 && r < DirIdx)
         Return
      r += 1
      CurrentFolder := Dir%r%Path
      PointerFNI := &Dir%r%FNI
      DllCall( "GetOverlappedResult", UInt, hDir, UInt, &Dir%r%Overlapped, UIntP, nReadLen, Int, true )
      Loop {
          pNext      := NumGet( PointerFNI + 0  )
         Action      := NumGet( PointerFNI + 4  )
         FileNameLen := NumGet( PointerFNI + 8  )
         pFileName :=       ( PointerFNI + 12 )
         If (Action < 0x6){
            VarSetCapacity( FileNameANSI, FileNameLen )
            DllCall( "WideCharToMultiByte",UInt,0,UInt,0,UInt,pFileName,UInt,FileNameLen,Str,FileNameANSI,UInt,FileNameLen,UInt,0,UInt,0)
            %WatchFolder%(Action,CurrentFolder,SubStr( FileNameANSI, 1, FileNameLen/2 ))
         }
         If (!pNext or pNext = 4129024)
            Break
          Else
            PointerFNI := (PointerFNI + pNext)
      }
      DllCall( "ResetEvent", UInt,NumGet( Dir%r%Overlapped, 16 ) )
      Gosub, ReadDirectoryChanges
       return r
   } else {
      Loop % (DirIdx) {
         If InStr(WatchFolder, Dir%A_Index%Path){
            If (Dir%A_Index%Subdirs)
               Return
         } else if InStr(Dir%A_Index%Path, WatchFolder) {
            If (WatchSubDirs){
               DllCall( "CloseHandle", UInt,Dir%A_Index% )
               DllCall( "CloseHandle", UInt,NumGet(Dir%A_Index%Overlapped, 16) )
               Restart := DirIdx, DirIdx := A_Index
            }
         }
      }
      If !Restart
         DirIdx += 1
      r:=DirIdx
      hDir := DllCall( "CreateFile"
                , Str  , WatchFolder
                , UInt , ( FILE_LIST_DIRECTORY := 0x1 )
                , UInt , ( FILE_SHARE_READ     := 0x1 )
                     | ( FILE_SHARE_WRITE    := 0x2 )
                     | ( FILE_SHARE_DELETE   := 0x4 )
                , UInt , 0
                , UInt , ( OPEN_EXISTING := 0x3 )
                , UInt , ( FILE_FLAG_BACKUP_SEMANTICS := 0x2000000  )
                     | ( FILE_FLAG_OVERLAPPED       := 0x40000000 )
                , UInt , 0 )
      Dir%r%         := hDir
      Dir%r%Path     := WatchFolder
      Dir%r%Subdirs  := WatchSubDirs
      VarSetCapacity( Dir%r%FNI, _SizeOf_FNI_ )
      VarSetCapacity( Dir%r%Overlapped, 20, 0 )
      DllCall( "CloseHandle", UInt,hEvent )
      hEvent := DllCall( "CreateEvent", UInt,0, Int,true, Int,false, UInt,0 )
      NumPut( hEvent, Dir%r%Overlapped, 16 )
      if ( VarSetCapacity(DirEvents) < DirIdx*4 and VarSetCapacity(DirEvents, DirIdx*4 + 60))
         Loop %DirIdx%
          {
            If (SubStr(Dir%A_Index%Path,1,1)!="-"){
               action++
               NumPut( NumGet( Dir%action%Overlapped, 16 ), DirEvents, action*4-4 )
             }
         }
      NumPut( hEvent, DirEvents, DirIdx*4-4)
      Gosub, ReadDirectoryChanges
       If Restart
         DirIdx = %Restart%
   }
   Return
   StopWatchingDirectories:
      Loop % (DirIdx) {
         DllCall( "CloseHandle", UInt,Dir%A_Index% )
         DllCall( "CloseHandle", UInt,NumGet(Dir%A_Index%Overlapped, 16) )
         Dir%A_Index%=
         Dir%A_Index%Path=
         Dir%A_Index%Subdirs=
         Dir%A_Index%FNI=
         DllCall( "CloseHandle", UInt, NumGet(Dir%A_Index%Overlapped,16) )
         VarSetCapacity(Dir%A_Index%Overlapped,0)
      }
      DirIdx=
      VarSetCapacity(DirEvents,0)
   Return
   ReadDirectoryChanges:
      DllCall( "ReadDirectoryChangesW"
         , UInt , Dir%r%
         , UInt , &Dir%r%FNI
         , UInt , _SizeOf_FNI_
         , UInt , Dir%r%SubDirs
         , UInt , ( FILE_NOTIFY_CHANGE_FILE_NAME   := 0x1   )
               | ( FILE_NOTIFY_CHANGE_DIR_NAME    := 0x2   )
               | ( FILE_NOTIFY_CHANGE_ATTRIBUTES  := 0x4   )
               | ( FILE_NOTIFY_CHANGE_SIZE        := 0x8   )
               | ( FILE_NOTIFY_CHANGE_LAST_WRITE  := 0x10  )
               | ( FILE_NOTIFY_CHANGE_CREATION    := 0x40  )
               | ( FILE_NOTIFY_CHANGE_SECURITY    := 0x100 )
         , UInt , 0
         , UInt , &Dir%r%Overlapped
         , UInt , 0  )
   Return
}