in previous thread http://www.purebasic.fr/english/viewtop ... rychangesw I've postet a example for ReadDirectoryChangesW. Due to conflicts in a current project I changed the function call because my previous version didn't work well. Now here is the new code as a simple sample.
What does the code?
The code creates a thread that executes the ReadDirectoryChangesW synchronous for a non-blocking app. The main app is a simple window loop with a listbox that displays the changes. The observed dir is C:\Test (you can simply change it in the test code).
What was wrong with the previous version?
Simply all. The buffer (*lpBufer) must not declared as FILE_NOTIFY_INFORMATION. The Buffer should simple be a allocated pointer of the size <= 64K. When a change happens the ReadDirectoryChangesW return. The filled buffer is structured as FILE_NOTIFY_INFORMATION. One Entry - One Change.
Code: Select all
; Notify filter values
#FILE_NOTIFY_CHANGE_FILE_NAME = 1
#FILE_NOTIFY_CHANGE_DIR_NAME = 2
#FILE_NOTIFY_CHANGE_ATTRIBUTES = 4
#FILE_NOTIFY_CHANGE_SIZE = 8
#FILE_NOTIFY_CHANGE_LAST_WRITE = $10
#FILE_NOTIFY_CHANGE_LAST_ACCESS = $20
#FILE_NOTIFY_CHANGE_CREATION = $40
#FILE_NOTIFY_CHANGE_SECURITY = $100
#FILE_NOTIFY_CHANGE_ALL = $17F
; not defined in purebasic
#FILE_SHARE_DELETE = 4
; Notify events
Enumeration
#FILE_ACTION_ADDED = 1
#FILE_ACTION_REMOVED
#FILE_ACTION_MODIFIED
#FILE_ACTION_RENAMED_OLD_NAME
#FILE_ACTION_RENAMED_NEW_NAME
EndEnumeration
; Needed for creating a watching thread
Structure WatchFSParam_t
Directory.s
Filter.l
EndStructure
; structure for the needed
Structure FILE_NOTIFY_INFORMATION
NextEntryOffset.l
Action.l
FileNameLength.l
Filename.s{512}
EndStructure
Import "kernel32.lib"
ReadDirectoryChangesW(hDirectory.l, *lpBuffer, nbBufferLen.l, bWatchSubTree.b, dwNotifyFilter.l, *lpBytesReturned.l, *lpOverlapped.OVERLAPPED, lpCompletitionRoutine)
EndImport
Procedure WatchDirOrFile(*params.WatchFSParam_t)
Protected *buffer = AllocateMemory(32*1024)
Protected *ovlp.OVERLAPPED = AllocateMemory(SizeOf(OVERLAPPED))
Protected dwOffset.l = 0
Protected *pInfo.FILE_NOTIFY_INFORMATION
hDir = CreateFile_(*params\Directory, #FILE_LIST_DIRECTORY, #FILE_SHARE_READ | #FILE_SHARE_WRITE | #FILE_SHARE_DELETE, #Null, #OPEN_EXISTING, #FILE_FLAG_BACKUP_SEMANTICS, #Null)
While ReadDirectoryChangesW(hDir, *buffer, MemorySize(*buffer), #True, *params\Filter, bytesRead, *ovlp, #Null)
dwOffset = 0
Repeat
*pInfo = *buffer + dwOffset
filename$ = PeekS(@*pInfo\Filename, *pInfo\FileNameLength, #PB_Unicode)
action$ = #NULL$
Select *pInfo\Action
Case #FILE_ACTION_ADDED
action$ = "ADDED"
Case #FILE_ACTION_MODIFIED
action$ = "MODIFIED"
Case #FILE_ACTION_REMOVED
action$ = "REMOVED"
Case #FILE_ACTION_RENAMED_NEW_NAME
action$ = "RENAMED_NEWNAME"
Case #FILE_ACTION_RENAMED_OLD_NAME
action$ = "RENAMED_OLDNAME"
EndSelect
AddGadgetItem (0, -1, filename$ + " " + action$)
dwOffset + *pInfo\NextEntryOffset
Until *pInfo\NextEntryOffset = 0
Wend
EndProcedure
Procedure.l WatchFileSystem(DirectoryName.s, NotifyFilter.l = #FILE_NOTIFY_CHANGE_FILE_NAME)
*watcherparams.WatchFSParam_t = AllocateMemory(SizeOf(WatchFSParam_t))
*watcherparams\Directory = DirectoryName
*watcherparams\Filter = NotifyFilter
CreateThread(@WatchDirOrFile(), *watcherparams)
EndProcedure
; USAGE
If OpenWindow(0, 0, 0, 320, 240, "FileSystemWatch", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListViewGadget(0, 10, 10, 300, 200)
WatchFileSystem("C:\Test")
Repeat
Event = WaitWindowEvent()
Delay(5)
Until Event = #PB_Event_CloseWindow
EndIf
Enjoy the code