2

I need to figure out the condition when I'm ready to display the final file list in a ListView after a series of FindNextChangeNotification events.

If there are multiple events coming in quick succession (e.g. both FILE_NOTIFY_CHANGE_FILE_NAME and FILE_NOTIFY_CHANGE_SIZE), and I try to refresh my ListView with the latest file list on each of those, those multiple refreshes clash and cause errors, so I need to limit the refresh to only the last notification. But, the challenge is when to know when the last notification for that entity is complete.

For simplicity, I made my notifications Name-only, and got rid of everything else. This works for Single-Rename, Single-/Multi-Paste, and Single-/Multi-Delete. There is only 1 (Name) notification now being passed for each file in these operations, and batches work by checking for the last Name-based item in the batch only:

DWORD dwWaitStatus;
HANDLE dwChangeHandles[2];
dwChangeHandles[0] = FindFirstChangeNotification(path.c_str(), FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
dwChangeHandles[1] = FindFirstChangeNotification(path.c_str(), FALSE, FILE_NOTIFY_CHANGE_DIR_NAME);
while (TRUE) {
 dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles, FALSE, INFINITE);
 if (dwWaitStatus == WAIT_OBJECT_0) {
 // A file was created, renamed or deleted in the directory.
 refreshFunc();
 FindNextChangeNotification(dwChangeHandles[0]);
 }
 else if (dwWaitStatus == WAIT_OBJECT_0 + 1) {
 // A directory was created, renamed, or deleted.
 refreshFunc();
 FindNextChangeNotification(dwChangeHandles[1]);
 }

Refresh Func will also check for batch operations using global variables:

if (batchOperation) {
 batchOperationCurrentCount--;
 if (batchOperationCurrentCount == 0) {
 batchOperation = false; // Reset batchOperation flag
 ContentsListView_Refresh(); // Ready to refresh
 }
}
else {
 // Not a batch operation (e.g. single Rename), refresh immediately
 ContentsListView_Refresh();
}

But, there is one case that doesn't work: When I save a new non-empty file from an external application, there are 2 File-Name notifications being sent for the same file. If I open Notepad and type a new file and then Save As for the first time in that directory, I get a double File-Name notification that I have to process. Not sure why that is, maybe because creating and renaming both happen in that scenario and both correspond to a FILE_NOTIFY_CHANGE_FILE_SIZE? It's not a directory notification, it's specifically a double File one.

If I were to add FILE_NOTIFY_CHANGE_FILE_SIZE notifications on top, all those notifications would increase further. The Rename/Paste/Delete would double to 2, and this Create New File would grow to 3 notifications.

So, how do I know when I'm done? Do I need a fixed timer to check, or a queue to sequentially execute the refresh?

I would prefer to use this FindFirstFile... approach as opposed to ReadDirectoryChangesW.

Remy Lebeau
609k36 gold badges516 silver badges875 bronze badges
asked Nov 2 at 22:09
2
  • 2
    I guess you need to pick a refresh time that makes sense, say 500ms or 1 second. When you get a change notification, start the timer. If you get another change notification before the timer elapses, restart it. Otherwise do your refresh when the timer goes off. Commented Nov 3 at 2:15
  • Yes, that's what I'll do. Thanks Commented Nov 3 at 14:09

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.