#include #include ; ; IMPORTANT NOTE: To use v1.1 (with the corrections), you must download v1.1 from post # 3 ; (at https://www.autoitscript.com/forum/topic/167024-rdc-udf-readdirectorychanges-wrapper/?do=findComment&comment=1331694) ; and save it to your local development directory. Do NOT specify #include , since that's version 1.0 which has ; a bug in the _RDC_GetData() function. Instead, store v1.1 in your development folder and use #include "RDC.au3" ; #include "RDC.au3" Opt("MustDeclareVars", 1) Opt("GUICloseOnESC", 1) Opt("GUIOnEventMode", 1) ; Enable Event Mode Opt("TrayAutoPause", 0) Global $G_hWnd, $G_bActionsOccurred, $G_sEventDesc[50], $G_iEventDescIndex=0, $G_iTotalRDCmsgCount=0 Global Const $CsAppTitle = "RDC v1.1 Test Script with GUI" Local $iStat, $sPath1, $sPath2, $iRDCid1, $iRDCid2, $sOutMsg ;= = = = ; ; This first part creates two different directories (if they don't already exist) that will be independently ; monitored for changes. This is done to test that capability of the RDC UDF. ; ; To test this capability with this example app, the user needs to make test changes to the directories being ; monitored, probably by using Windows Explorer to copy files to them, delete these copies, or rename them. ; Otherwise, nothing will happen. ; $sPath1 = @ScriptDir & "\Monitored Directory One" If Not FileExists( $sPath1 ) Then $iStat = DirCreate( $sPath1 ) If $iStat <> 1 Then MsgBox($MB_ICONERROR, $CsAppTitle, "Error: Unable to create test folder 1 - Exiting") Exit EndIf EndIf $sPath2 = @ScriptDir & "\Monitored Directory Two" If Not FileExists( $sPath2 ) Then $iStat = DirCreate( $sPath2 ) If $iStat <> 1 Then MsgBox($MB_ICONERROR, $CsAppTitle, "Error: Unable to create test folder 2 - Exiting") Exit EndIf EndIf ;= = = = ; ; The main part of the example script begins here... ; ; $G_bActionsOccurred = False ; This flag will only be set true when changes to any monitored directory occurr _RDC_OpenDll() If @error <> 0 Then MsgBox($MB_ICONERROR, $CsAppTitle, "Error: _RDC_OpenDll() - @error = " & @error & " - Exiting") Exit EndIf $G_hWnd = GUICreate($CsAppTitle) ; A GUI (even though not visible) must be created in order to register the RDC handler If $G_hWnd = 0 Then MsgBox($MB_ICONERROR, $CsAppTitle, "Error: GUICreate() Failed! - Exiting") Exit EndIf HotKeySet("{ESC}", "_ExitApp") ; Allow exit when user presses escape $iStat = GUIRegisterMsg($WM_RDC, "WM_RDC") ; Register the RDC event handler If $iStat <> 1 Then MsgBox($MB_ICONERROR, $CsAppTitle, "Error: GUIRegisterMsg() failed - Exiting") Exit EndIf ; ; Note that the $G_hWnd paramter MUST be specified in the following _RDC_Create() calls so that the WM_RDC event handler ; is invoked! Consequently, the code must enable "GUIOnEventMode" for this to happen as well. Otherwise, in ordinary ; message mode the event handler will never be called. ; ; At a minimum, this first _RDC_Create() call must specify True as the $fWait (penultimate) parameter so that the second ; _RDC_Create() call has a chance to establish monitoring of the second directory before general monitoring begins. ; $iRDCid1 = _RDC_Create($sPath1, True, _ BitOR($FILE_NOTIFY_CHANGE_FILE_NAME, $FILE_NOTIFY_CHANGE_DIR_NAME, $FILE_NOTIFY_CHANGE_SIZE), True, $G_hWnd) If $iRDCid1 = -1 Then MsgBox($MB_ICONERROR, $CsAppTitle, "Error: _RDC_Create() - @error = " & @error & " @extended = " & @extended & " -- Exiting") Exit EndIf $iRDCid2 = _RDC_Create($sPath2, True, _ BitOR($FILE_NOTIFY_CHANGE_FILE_NAME, $FILE_NOTIFY_CHANGE_DIR_NAME, $FILE_NOTIFY_CHANGE_SIZE), False, $G_hWnd) If $iRDCid2 = -1 Then MsgBox($MB_ICONERROR, $CsAppTitle, "Error: _RDC_Create() - @error = " & @error & " @extended = " & @extended & " -- Exiting") Exit EndIf $iStat = _RDC_Resume( $iRDCid1 ) ; Now we can enable monitoring of directory 1 as well If ($iStat <> 1) Or (@error <> 0) Then MsgBox($MB_ICONERROR, $CsAppTitle, "Error: _RDC_Resume() failed. @error = " & @error & " @extended = " & @extended & " -- Exiting") Exit EndIf ; ; The main loop begins here. Nothing is done until the $G_bActionsOccurred flag is set true, which indicates that some ; change has occurred to one of the directories being monitored. ; While True If $G_bActionsOccurred Then $iStat = GUIRegisterMsg($WM_RDC, "") ; Unregister this event handler to avoid being interrupted until done If $iStat <> 1 Then MsgBox($MB_ICONERROR, $CsAppTitle, "Error from GUIRegisterMsg() call to disable WM_RDC - Exiting") Exit EndIf $sOutMsg = "" For $i = 1 To $G_iEventDescIndex -1 $sOutMsg &= "Event # " & $i & " : " & $G_sEventDesc[$i] & @CRLF Next MsgBox($MB_OK, $CsAppTitle, "Total number of WM_RDC invocations thus far = " & $G_iTotalRDCmsgCount & @CRLF _ & "The changes occurred in directory : " & $G_sEventDesc[0] & @CRLF & @CRLF _ & "Number of Action Events this pass = " & $G_iEventDescIndex -1 & " -- Here's the list..." & @CRLF & $sOutMsg) $G_bActionsOccurred = False ; Reset this flag so we won"t be triggered until there are more events $iStat = GUIRegisterMsg($WM_RDC, "WM_RDC") ; Re-register this event handler If $iStat <> 1 Then MsgBox($MB_ICONERROR, $CsAppTitle, "Error from GUIRegisterMsg() call to re-enable WM_RDC - Exiting") Exit EndIf Else Sleep(500) EndIf WEnd Func WM_RDC($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam ; ; Upon entry, the RDC dll will provide the RDC ID/Thread ID for the associated directory being watched in $lParam. ; This fact is not documented anywhere else. ; Local $sName, $iActionCount, $iEventType $G_iTotalRDCmsgCount += 1 Local $aData = _RDC_GetData($lParam) If @error = 0 Then $sName = _RDC_GetDirectory($lParam) If @error <> 0 Then MsgBox($MB_ICONERROR, $CsAppTitle, "Error: _RDC_GetDirectory() failed. @error = " & @error & " @extended = " _ & @extended & " -- Exiting") Exit EndIf Else MsgBox($MB_ICONERROR, $CsAppTitle, "Error: _RDC_GetData() - @error = " & @error & " @extended = " & @extended _ & @CRLF & " Directory = " & $sName & " -- Exiting") _RDC_Delete($lParam) Exit EndIf $iActionCount = $aData[0][0] If $iActionCount < 1 Then Return 0 $G_sEventDesc[0] = $sName ; Record the directory or root of directory tree that saw the changes. $G_iEventDescIndex = 1 ; The actual list of changes begins with element 1 For $i = 1 To $iActionCount $iEventType = $aData[$i][0] $sName = $aData[$i][1] Switch $iEventType Case $FILE_ACTION_ADDED $G_sEventDesc[$G_iEventDescIndex] = "Item Added = " & $sName Case $FILE_ACTION_REMOVED $G_sEventDesc[$G_iEventDescIndex] = "Item Removed = " & $sName Case $FILE_ACTION_MODIFIED $G_sEventDesc[$G_iEventDescIndex] = "Item Modified = " & $sName Case $FILE_ACTION_RENAMED_OLD_NAME $G_sEventDesc[$G_iEventDescIndex] = "Old item named " & $sName & " will be renamed" Case $FILE_ACTION_RENAMED_NEW_NAME $G_sEventDesc[$G_iEventDescIndex] = "Item renamed to " & $sName Case Else $G_sEventDesc[$G_iEventDescIndex] = "INVALID ACTION!" EndSwitch $G_iEventDescIndex += 1 If $G_iEventDescIndex >= 50 Then MsgBox($MB_ICONERROR, $CsAppTitle, "Error in WM_RDC: Too many events! - Exiting") Exit EndIf Next $G_bActionsOccurred = True Return 0 EndFunc ;==>WM_RDC Func _ExitApp() Exit EndFunc