Announcement

Collapse
No announcement yet.

FileWatcher Discussion

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • FileWatcher Discussion

    Discussion for the FileWatcher class found here.

    I found myself running a lot of unit tests recently and the editor I was using to view the results would only load changes when it was focused. Probabbly should have downloaded a tail utility, but thought this would likely come in useful later. It uses the ReadDirectoryChangesW API call to monitor for changes. This is my first attempt at using these API by cobbling together stuff from the documentation and found around the net. Please let me know if you see anything that needs correcting.
    Last edited by Larry Charlton; 25 Jul 2012, 11:08 AM.
    LarryC
    Website
    Sometimes life's a dream, sometimes it's a scream

  • #2
    Hey Larry,
    Thanks for the code. I've been interested in using the API for monitoring file/folder changes but haven't gotten around to doing anything with it.

    The simple code below is an example of what I've used to monitor changes to a single file. It's fairly minimal, and uses a simple timer rather than the API you're using, but does the job I want. Can you talk to why, for monitoring a single file, the API would be more beneficial?

    I'm more interested in using the API to monitor all file and folder changes, so that I could write an equivalent to the Everything application. Have you done any work with the API on monitoring any and all file/folder changes? Eventually I'll find time to look into it, so what you are doing is appreciated!



    Code:
    'Compilable Example:
    #Compiler PBWin 10
    #Compile Exe
    #Dim All
    %Unicode = 1
    #Include "Win32API.inc"
    %IDC_TextBox = 500
    %ID_Timer    = 501
    Global hDlg As Dword
    
    Function PBMain() As Long
       Dialog New Pixels, 0, "PowerBASIC",300,300,200,80, %WS_OverlappedWindow To hDlg
       Control Add TextBox, hDlg, %IDC_TextBox,"c:\_test\x.bas", 10,10,180,20
       Dialog Show Modal hDlg Call DlgProc
    End Function
    
    CallBack Function DlgProc() As Long
       Static oldFile, tempFile As DirData, temp$
       Select Case Cb.Msg
          Case %WM_InitDialog
             SetTimer hDlg, %ID_Timer, 250, ByVal %Null
             Control Get Text hDlg, %IDC_TextBox To temp$
             temp$ = Dir$(temp$, 0, To oldFile)
          Case %WM_Timer
             Dialog Set Text hDlg, Time$
             Control Get Text hDlg, %IDC_TextBox To temp$
             temp$ = Dir$(temp$, 0, To tempFile)
             If tempFile.LastWriteTime <> OldFile.LastWriteTime Then
                KillTimer hDlg, %ID_Timer
                ? "File changed!"
             End If
          Case %WM_Destroy
             KillTimer hDlg, %ID_Timer
       End Select
    End Function
    Last edited by Gary Beene; 25 Jul 2012, 01:48 PM.

    Comment


    • #3
      >Can you talk to why, for monitoring a single file, the API would be more beneficial?

      Less resources required. Why expend the resources needed to check a file on each timer hit when you can wait for something to actually change?
      Michael Mattias
      Tal Systems (retired)
      Port Washington WI USA
      [email protected]
      http://www.talsystems.com

      Comment


      • #4
        Hi MCM,
        Re:
        Why expend the resources ...
        Simplicity of the approach is the first thought that comes to mind, but your question raises a question I've never answered for myself nor seen quantified.

        Just how much of a resource hog is a timer? I seem to remember doing a test one time - pulled up Task Manager and looked at CPU usage after starting a timer. As I recall, I could see no visual change in the graph.

        ... pause for new test ...

        I made a short app that creates 1,000 timers, but I can't see any impact in Task Manager. I've read elsewhere that timer are very lightweight resources, but haven't found an upper limit mentioned online or on MSDN.

        Can you suggest a more appropriate test to quantify resource use of timers?

        Here's the test code I just used:
        Code:
        'Compilable Example:
        #Compiler PBWin 10
        #Compile Exe
        #Dim All
        #Debug Error On
        #Debug Display On
        %Unicode = 1
        #Include "Win32API.inc"
        Global hDlg As Dword
        
        Function PBMain() As Long
           Dialog New Pixels, 0, "PowerBASIC",300,300,200,80, %WS_OverlappedWindow To hDlg
           Dialog Show Modal hDlg Call DlgProc
        End Function
        
        CallBack Function DlgProc() As Long
           Local i As Long
           Select Case Cb.Msg
              Case %WM_InitDialog
                 For i = 1 To 1000
                    SetTimer hDlg, 1000 + i, 250, ByVal %Null
                 Next i
              Case %WM_Destroy
                 For i = 1 To 1000
                    KillTimer hDlg, 1000 + i
                 Next i
           End Select
        End Function

        Comment


        • #5
          Hi Larry,
          I went out to MSDN and looked at ReadDirectoryChangesW. The bWatchSubTree argument looks of interest. %True appears to allow the API to monitor subfolders. Cool beans.

          I wonder why MSDN has tossed in the term "subtree". I don't recall having seen that anywhere before. Was there a reason they don't just say Directory?

          Comment


          • #6
            I wonder why MSDN has tossed in the term "subtree". I don't recall having seen that anywhere before. Was there a reason they don't just say Directory?
            Frankly, I am surprised they do not say, "Folder."

            Just how much of a resource hog is a timer?
            Each thread in the system is routinely given CPU time, unless the thread is in a wait state.

            "How much" a good question.. I would assume the calling thread gets its normal time slice, which in this case would be used up "waiting for a message" because it's a GUI thread. (It's not only waiting for WM_TIMER, there's lots of other messages it might be getting).

            When the thread is in a wait state it gets nada until released, at which time it takes its regular turn again.

            I think you can guess how many style points you get for using a timer or otherwise 'polling for a condition' vs using synchronization objects and functions.

            MCM
            Surpreme Judge (Style Points)
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              I would like to view the testing of which process spends more resources.
              For two reasons, one for the reason that i am going to need(want) effecient code that loops and has time pauses in the loop and the second reason to possible learn to view and compare efficient processing times of different sets of source code on a running bases.

              I am not sure about to how to judge the cpu resources on code that already runs smoothly(yeah the processes that eat up the cpu are easy to see in task manager), but i was going to use the Kerneltime and Usertime values to see what they produced. I have read about other methods of timing, but i would like to start with these.

              Larry, i am not trying to distract from the subject too much bc i feel that in testing code. We try to get it to run better after it is giving results. One never knows when the code will be run on a server or a machine that resouces need to be squeezed.

              The SLEEP statement can be easily replace the timer part.
              I am asking MCM to provide the WAIT method source code.
              I will work on the kerneltime and usertime display which should take longer bc it is me doing it and learning while doing.
              p purvis

              Comment


              • #8
                >I am asking MCM to provide the WAIT method source code.

                Easy.

                Search here for "WaitForSingleObject" and/or "WaitForMultipleObjects"

                I know these posts all use one or the other ...

                GUI + Worker Thread + Abort Demo 11-24-07 (DDT syntax)
                Waitable Timer Object Demo June 2005
                Terminate Worker Threads Using Windows Events (and Using Thread Local Storage) Demo Dec 23 2005

                Probably some more, too.

                Just generically speaking? Using the "Wait" functions is more efficient than polling:
                Code:
                DO 
                   IF GlobalVar =  Quit_Value THEN 
                       EXIT DO 
                   ELSE
                      SLEEP Sleep_Interval 
                   END IF 
                LOOP
                First, there is a thread switch required to execute this thread - because it's NOT in a wait state.

                Second, every Sleep_interval the CPU must do an integer compare. Not that an integer compare is a "long" job at all.. but it's still greater than NOTHING.

                MCM
                Last edited by Michael Mattias; 25 Jul 2012, 07:06 PM.
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  FWIW... an 'early' 'File watcher' .. which actually watches a directory (folder):

                  Win32(SDK): Internet Cookie Monitor April 25, 2001
                  Michael Mattias
                  Tal Systems (retired)
                  Port Washington WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #10
                    Gary,

                    What MCM said. No resources expended unless something changes. Using the API with the provided class is pretty easy
                    Code:
                      
                      Local fw As iFileWatcher
                      Call StartFileWatcher( fw, newFile, CodePtr( OnFileChanged ) )
                    It calls a routine you write that has the following signature whenever there's a change:
                    Code:
                    Sub OnFileChanged( filename As WString )
                      ' Your code to do something when the file changes goes here.
                    End Sub
                    If you want to monitor a folder or tree, just remove some code and change one parameter. I might look into providing a variation if someone doesn't beat me to it.

                    In terms of efficiency, the approach presented will scale well particularly if you decide to monitor a directory or a directory tree. If you use a timer, everytime it goes off, you'll need to track something about every file in the tree and then scan the tree and compare for changes. That could get bad pretty quickly. For one file, I'm guessing it doesn't matter.

                    Subtree is just a shorted form of Sub directory tree refering to all of the folders from a particular location in the directory down.

                    There is a more performant method of using ReadDirectoryChangesW that involves a few more threads and a call back function. Didn't seem to fit easily into my view of PowerBASIC coding, maybe next time.

                    Edit: Oh and I updated the code to use more synchronization primitives and offload processing of the change from watching for the change. I also dealt with an issue on change if you try to use a file too quickly, you often get access denied errors...
                    LarryC
                    Website
                    Sometimes life's a dream, sometimes it's a scream

                    Comment


                    • #11
                      I've put zip files you can download at the following locations:

                      FileWatcher - includes exe. Watches for writes to a single file and then reloads it.

                      FileSystemWatcher - includes DLL for pbCC users. Watches for selected changes to a directory or directory tree and then sends a notice. Small demos of including, using an SLL, and using a DLL.
                      LarryC
                      Website
                      Sometimes life's a dream, sometimes it's a scream

                      Comment


                      • #12
                        compiled using PB 10.03
                        Ran on Win 7 Professional Version 6.1 Build 7601:Service Pack 1)
                        1st browed to a file on my C: managed by Tortoise SVN
                        It opened the file in a "notepad like" read only window with
                        "Load round 1" added to the top
                        In a seperate window with notepad I opened the file
                        Edited it
                        Saved it
                        Closed Notepad

                        I didn't get any notification.

                        Closed File Watcher.
                        Reopened it
                        Browed to c:\Temp.Txt
                        It did the same (opened it in a read only window)
                        I used notepad to edit c:\Temp.Txt then saved it
                        I didn't get any notification...

                        Using Trend Micro Client/Service Security Agent ..
                        Nathan Maddox

                        Comment


                        • #13
                          From ZIP file linked in post 11
                          Code:
                          Sub OnFileChanged( filename As WString )
                          	Local value, c As String
                          	Local i, f As Long
                          	Static cnt As Long
                          
                          	' Reload file
                          	ErrClear
                          	f = FreeFile
                          	For i=1 To 10
                          		Open filename For Binary Access Read Lock Shared As #f
                          		If Err=0 Then Exit For
                          		ErrClear
                          		Sleep 100
                          	Next
                          	Get$ #f, Lof(#f), value
                          	Close #f
                          	Incr cnt
                          	c = Format$( cnt, "#,##0" )
                          	value = Build$("Load round ", c, $CrLf, value )
                          	Control Set Text hDlg, %CTL_TEXT, value
                          End Sub
                          This procedure has no error handler when the OPEN fails ten times (FOR.. NEXT loop completes, exits fat and happy and continues without a care in the world) .

                          In the whole program, there is only one thread of execution. This can/will cause the program to hang on "no changes."

                          Suggestion:
                          Run the watcher in a separate thread of execution. When change detected, post a private message to notify the GUI thread. (That will be a lot easier than using MessageWaitForMultipleObjects in your own message loop).

                          Demo: Waitable Timer Object Demo June 2005. (Different object for the wait handle but same principle.)

                          (also handle open failure after nine retries).

                          MCM
                          Michael Mattias
                          Tal Systems (retired)
                          Port Washington WI USA
                          [email protected]
                          http://www.talsystems.com

                          Comment


                          • #14
                            Nathan
                            I've added an error message if you can't load (refresh) the file. This would happen if a program kept the file open over a 1 second and it didn't at least allow at least shared reading. If the writes are slow, extending the timeout count would help.

                            MCM
                            I'm not sure I follow the single thread of execution (I'm using two PowerThreads, not thread functions). The gui is running in a thread, the file watcher is running in a thread, change notification is running in a thread.

                            I wait for multiple objects because either the gui (signaling program exit) or the OS (signaling file change) can wake up the watcher. Watcher kicks the notifier and immediately goes back to watching.

                            I've not seen the "hang" condition you mentioned. I would be interested in an event sequence that caused the hang or steps to reproduce. Thanks again.
                            LarryC
                            Website
                            Sometimes life's a dream, sometimes it's a scream

                            Comment


                            • #15
                              > (I'm using two PowerThreads, not thread functions)

                              Not in the filewatcher.bas or filewatcher.inc I downloaded from thread # 11 there isn't. http://www.cur-ion.net/pb/FileWatcher.zip

                              Bad link to old version? Or multi-threaded code is in the other ZIP file?

                              If code is running multiple threads of execution as described, hang will not occur.

                              MCM
                              Michael Mattias
                              Tal Systems (retired)
                              Port Washington WI USA
                              [email protected]
                              http://www.talsystems.com

                              Comment


                              • #16
                                Nathan
                                Also it might be UAC. I have to run notepad or another editor as an administrator to acutally change a file in the root of C. But when I do, I'm seeing the changes in file watcher. A change to the file isn't even needed to see the change, pressing Control+S repeatedly in notepad caused the load count to increment.

                                I'll poke around and see if I can duplicate it with TortiseSVN.
                                LarryC
                                Website
                                Sometimes life's a dream, sometimes it's a scream

                                Comment


                                • #17
                                  Originally posted by Michael Mattias View Post
                                  > (I'm using two PowerThreads, not thread functions)

                                  Not in the filewatcher.bas or filewatcher.inc I downloaded from thread # 11 there isn't. http://www.cur-ion.net/pb/FileWatcher.zip

                                  Bad link to old version? Or multi-threaded code is in the other ZIP file?

                                  If code is running multiple threads of execution as described, hang will not occur.

                                  MCM
                                  filewatcher.bas is an example of using filewatcher.inc. Filewatcher.inc has two classes outlined below, both using PowerThreads. I used the link in post #11 to get the file and make the change to display the error if one occured, so I think we're using the same program.

                                  Class cFileWatcher
                                  Thread Method Main() As Long
                                  Interface iFileWatcher
                                  Inherit IPowerThread

                                  Class cFileWatchNotifier
                                  Thread Method Main() As Long
                                  Interface iFileWatchNotifier
                                  Inherit IPowerThread
                                  LarryC
                                  Website
                                  Sometimes life's a dream, sometimes it's a scream

                                  Comment


                                  • #18
                                    "inherit" not found in either file
                                    "thread" not found in either file
                                    "pow" not found in either file

                                    Sure you don't have the wrong files zipped up out there?
                                    Michael Mattias
                                    Tal Systems (retired)
                                    Port Washington WI USA
                                    [email protected]
                                    http://www.talsystems.com

                                    Comment


                                    • #19
                                      Below is the source I have from clicking the link you provided. I see all three value in Filewatcher.inc. I'm baffled.

                                      Filewatcher.bas
                                      Code:
                                      [color=#0000C0]#Compile Exe
                                      #Dim All
                                      [/color][color=#000000]%UNICODE [/color][color=#8000FF]= [/color][color=#000000]1
                                      [/color][color=#0000C0]#Include Once [/color][color=#C020C0]"win32api.inc"
                                      [/color][color=#0000C0]#Include Once [/color][color=#C020C0]"FileWatcher.inc"
                                      [/color][color=#0000C0]Global [/color][color=#000000]fw [/color][color=#0000C0]As [/color][color=#000000]iFileWatcher[/color][color=#8000FF]:  [/color][color=#007F00]' File watcher
                                      [/color][color=#0000C0]Global [/color][color=#000000]filename [/color][color=#0000C0]As WString[/color][color=#8000FF]: [/color][color=#007F00]' File we're watching
                                      [/color][color=#0000C0]Global [/color][color=#000000]hDlg [/color][color=#0000C0]As Dword[/color][color=#8000FF]:       [/color][color=#007F00]' Open dialog
                                      [/color][color=#000000]%FILE_EXIT    [/color][color=#8000FF]= [/color][color=#000000]1005
                                      %FILE_OPEN    [/color][color=#8000FF]= [/color][color=#000000]1006
                                      %CTL_TEXT     [/color][color=#8000FF]= [/color][color=#000000]1001
                                      [/color][color=#0000C0]Function PBMain[/color][color=#8000FF]()
                                        [/color][color=#0000C0]Local [/color][color=#000000]hFont[/color][color=#8000FF], [/color][color=#000000]hTopMenu[/color][color=#8000FF], [/color][color=#000000]hFileMenu[/color][color=#8000FF], [/color][color=#000000]hAccel[/color][color=#8000FF], [/color][color=#000000]hRes [/color][color=#0000C0]As Dword
                                        Dim [/color][color=#000000]menuAccel[/color][color=#8000FF]([/color][color=#000000]0[/color][color=#8000FF]) [/color][color=#0000C0]As [/color][color=#000000]ACCELAPI
                                        [/color][color=#0000C0]Dialog New Pixels[/color][color=#8000FF], [/color][color=#0000C0]%HWND_Desktop[/color][color=#8000FF], [/color][color=#C020C0]"File Watcher"[/color][color=#8000FF], [/color][color=#000000]105[/color][color=#8000FF], [/color][color=#000000]114[/color][color=#8000FF], [/color][color=#000000]607[/color][color=#8000FF], [/color][color=#000000]483[/color][color=#8000FF], [/color][color=#0000C0]%WS_OverlappedWindow[/color][color=#8000FF], [/color][color=#0000C0]To [/color][color=#000000]hDlg
                                        [/color][color=#0000C0]Control Add TextBox[/color][color=#8000FF], [/color][color=#000000]hDlg[/color][color=#8000FF], [/color][color=#000000]%CTL_TEXT[/color][color=#8000FF], [/color][color=#C020C0]""[/color][color=#8000FF], [/color][color=#000000]0[/color][color=#8000FF], [/color][color=#000000]0[/color][color=#8000FF], [/color][color=#000000]0[/color][color=#8000FF], [/color][color=#000000]0[/color][color=#8000FF], [/color][color=#0000C0]%WS_Child [/color][color=#8000FF]Or [/color][color=#0000C0]_
                                                                                                  %WS_Visible [/color][color=#8000FF]Or [/color][color=#0000C0]_
                                                                                                  %WS_Border [/color][color=#8000FF]Or [/color][color=#0000C0]_
                                                                                                  %WS_TabStop [/color][color=#8000FF]Or [/color][color=#0000C0]_
                                                                                                  %WS_VScroll [/color][color=#8000FF]Or [/color][color=#0000C0]_
                                                                                                  %WS_HScroll [/color][color=#8000FF]Or [/color][color=#0000C0]_
                                                                                                  %ES_Left [/color][color=#8000FF]Or [/color][color=#0000C0]_
                                                                                                  %ES_MultiLine [/color][color=#8000FF]Or [/color][color=#0000C0]_
                                                                                                  %ES_ReadOnly [/color][color=#8000FF]Or [/color][color=#0000C0]_
                                                                                                  %ES_AutoHScroll [/color][color=#8000FF]Or [/color][color=#0000C0]_
                                                                                                  %ES_AutoVScroll[/color][color=#8000FF],[/color][color=#0000C0]_
                                                                                                  %WS_Ex_RightScrollbar
                                        Font New [/color][color=#C020C0]"Courier New"[/color][color=#8000FF], [/color][color=#000000]10[/color][color=#8000FF], [/color][color=#000000]0[/color][color=#8000FF], [/color][color=#000000]%ANSI_CHARSET [/color][color=#0000C0]To [/color][color=#000000]hFont
                                        [/color][color=#0000C0]Control Set Font [/color][color=#000000]hDlg[/color][color=#8000FF], [/color][color=#000000]%CTL_TEXT[/color][color=#8000FF], [/color][color=#000000]hFont
                                        [/color][color=#0000C0]Menu New Bar To [/color][color=#000000]hTopMenu
                                        [/color][color=#0000C0]Menu New PopUp To [/color][color=#000000]hFileMenu
                                        [/color][color=#0000C0]Menu Add PopUp[/color][color=#8000FF], [/color][color=#000000]hTopMenu[/color][color=#8000FF], [/color][color=#C020C0]"File"[/color][color=#8000FF], [/color][color=#000000]hFileMenu[/color][color=#8000FF], [/color][color=#0000C0]%MF_Enabled
                                        Menu Add String[/color][color=#8000FF], [/color][color=#000000]hFileMenu[/color][color=#8000FF], [/color][color=#C020C0]"&Open" [/color][color=#8000FF]& [/color][color=#0000C0]$Tab [/color][color=#8000FF]& [/color][color=#C020C0]"Ctrl+O"[/color][color=#8000FF], [/color][color=#000000]%FILE_OPEN[/color][color=#8000FF], [/color][color=#0000C0]%MF_Enabled
                                        Menu Add String[/color][color=#8000FF], [/color][color=#000000]hFileMenu[/color][color=#8000FF], [/color][color=#C020C0]"-"[/color][color=#8000FF], [/color][color=#000000]0[/color][color=#8000FF], [/color][color=#000000]0
                                        [/color][color=#0000C0]Menu Add String[/color][color=#8000FF], [/color][color=#000000]hFileMenu[/color][color=#8000FF], [/color][color=#C020C0]"E&xit"[/color][color=#8000FF], [/color][color=#000000]%FILE_EXIT[/color][color=#8000FF], [/color][color=#0000C0]%MF_Enabled
                                        Menu Attach [/color][color=#000000]hTopMenu[/color][color=#8000FF], [/color][color=#000000]hDlg
                                        menuAccel[/color][color=#8000FF]([/color][color=#000000]0[/color][color=#8000FF])[/color][color=#000000].fVirt [/color][color=#8000FF]= [/color][color=#000000]%FVIRTKEY [/color][color=#8000FF]Or [/color][color=#000000]%FCONTROL [/color][color=#8000FF]Or [/color][color=#000000]%FNOINVERT
                                        menuAccel[/color][color=#8000FF]([/color][color=#000000]0[/color][color=#8000FF])[/color][color=#000000].Key [/color][color=#8000FF]= [/color][color=#0000C0]Asc[/color][color=#8000FF]([/color][color=#C020C0]"O"[/color][color=#8000FF])
                                        [/color][color=#000000]menuAccel[/color][color=#8000FF]([/color][color=#000000]0[/color][color=#8000FF])[/color][color=#000000].Cmd [/color][color=#8000FF]= [/color][color=#000000]%FILE_OPEN
                                        [/color][color=#0000C0]Accel Attach [/color][color=#000000]hDlg[/color][color=#8000FF], [/color][color=#000000]menuAccel[/color][color=#8000FF]() [/color][color=#0000C0]To [/color][color=#000000]hAccel
                                        [/color][color=#0000C0]Dialog Show Modeless [/color][color=#000000]hDlg[/color][color=#8000FF], [/color][color=#0000C0]Call [/color][color=#000000]ShowFileWatcherProc [/color][color=#0000C0]To [/color][color=#000000]hRes
                                        GetNewFile[/color][color=#8000FF]()
                                        [/color][color=#0000C0]If IsNothing[/color][color=#8000FF]( [/color][color=#000000]fw [/color][color=#8000FF]) [/color][color=#0000C0]Then Exit Function
                                        Call [/color][color=#000000]OnFileChanged[/color][color=#8000FF]( [/color][color=#000000]filename [/color][color=#8000FF]): [/color][color=#007F00]' Initial load
                                        [/color][color=#0000C0]Do
                                          Dialog DoEvents
                                        Loop While IsWin[/color][color=#8000FF]([/color][color=#000000]hDlg[/color][color=#8000FF])
                                        [/color][color=#0000C0]If IsObject[/color][color=#8000FF]( [/color][color=#000000]fw [/color][color=#8000FF]) [/color][color=#0000C0]Then [/color][color=#000000]fw.Stop[/color][color=#8000FF]()
                                        [/color][color=#0000C0]Font End [/color][color=#000000]hFont
                                      [/color][color=#0000C0]End Function
                                      CallBack Function [/color][color=#000000]ShowFileWatcherProc[/color][color=#8000FF]()
                                        [/color][color=#0000C0]Local [/color][color=#000000]w[/color][color=#8000FF], [/color][color=#000000]h [/color][color=#0000C0]As Long
                                        Select Case Const Cb.Msg
                                          Case %WM_Size
                                            Dialog Get Client [/color][color=#000000]hDlg [/color][color=#0000C0]To [/color][color=#000000]w[/color][color=#8000FF], [/color][color=#000000]h
                                            [/color][color=#0000C0]Control Set Size [/color][color=#000000]hDlg[/color][color=#8000FF], [/color][color=#000000]%CTL_TEXT[/color][color=#8000FF], [/color][color=#000000]w[/color][color=#8000FF], [/color][color=#000000]h
                                          [/color][color=#0000C0]Case %WM_Command
                                            Select Case Const Cb.Ctl
                                              Case [/color][color=#000000]%FILE_OPEN[/color][color=#8000FF]: [/color][color=#0000C0]Call [/color][color=#000000]GetNewFile[/color][color=#8000FF]():   [/color][color=#0000C0]Call [/color][color=#000000]OnFileChanged[/color][color=#8000FF]( [/color][color=#000000]filename [/color][color=#8000FF])
                                              [/color][color=#0000C0]Case [/color][color=#000000]%FILE_EXIT[/color][color=#8000FF]: [/color][color=#0000C0]Dialog End [/color][color=#000000]hDlg
                                            [/color][color=#0000C0]End Select
                                        End Select
                                      End Function
                                      Sub [/color][color=#000000]GetNewFile[/color][color=#8000FF]()
                                        [/color][color=#0000C0]Local [/color][color=#000000]newFile [/color][color=#0000C0]As WString
                                        Display Openfile [/color][color=#000000]0[/color][color=#8000FF], , , [/color][color=#C020C0]"Select File To Watch"[/color][color=#8000FF], [/color][color=#C020C0]""[/color][color=#8000FF], [/color][color=#C020C0]"All|*.*"[/color][color=#8000FF], [/color][color=#C020C0]""[/color][color=#8000FF], [/color][color=#C020C0]""[/color][color=#8000FF], [/color][color=#0000C0]%OFN_FileMustExist To [/color][color=#000000]newFile
                                        [/color][color=#0000C0]If [/color][color=#000000]newFile [/color][color=#8000FF]= [/color][color=#C020C0]"" [/color][color=#0000C0]Then Exit Sub
                                        If IsObject[/color][color=#8000FF]( [/color][color=#000000]fw [/color][color=#8000FF]) [/color][color=#0000C0]Then [/color][color=#000000]fw.Stop[/color][color=#8000FF]()
                                        [/color][color=#000000]fw [/color][color=#8000FF]= [/color][color=#0000C0]Nothing
                                        [/color][color=#000000]filename [/color][color=#8000FF]= [/color][color=#000000]newFile
                                        [/color][color=#0000C0]Call [/color][color=#000000]StartFileWatcher[/color][color=#8000FF]( [/color][color=#000000]fw[/color][color=#8000FF], [/color][color=#000000]newFile[/color][color=#8000FF], [/color][color=#0000C0]CodePtr[/color][color=#8000FF]( [/color][color=#000000]OnFileChanged [/color][color=#8000FF]) )
                                      [/color][color=#0000C0]End Sub
                                      Sub [/color][color=#000000]OnFileChanged[/color][color=#8000FF]( [/color][color=#000000]filename [/color][color=#0000C0]As WString [/color][color=#8000FF])
                                        [/color][color=#0000C0]Local [/color][color=#000000]value[/color][color=#8000FF], [/color][color=#000000]c [/color][color=#0000C0]As String
                                        Local [/color][color=#000000]i[/color][color=#8000FF], [/color][color=#000000]f [/color][color=#0000C0]As Long
                                        Static [/color][color=#000000]cnt [/color][color=#0000C0]As Long
                                        [/color][color=#007F00]' Reload file
                                        [/color][color=#0000C0]ErrClear
                                        [/color][color=#000000]f [/color][color=#8000FF]= [/color][color=#0000C0]FreeFile
                                        For [/color][color=#000000]i[/color][color=#8000FF]=[/color][color=#000000]1 [/color][color=#0000C0]To [/color][color=#000000]10
                                          [/color][color=#0000C0]Open [/color][color=#000000]filename [/color][color=#0000C0]For Binary Access Read Lock Shared As [/color][color=#000000]#f
                                          [/color][color=#0000C0]If Err[/color][color=#8000FF]=[/color][color=#000000]0 [/color][color=#0000C0]Then Exit For
                                          ErrClear
                                          Sleep [/color][color=#000000]100
                                        [/color][color=#0000C0]Next
                                        If Err[/color][color=#8000FF]<>[/color][color=#000000]0 [/color][color=#0000C0]Then
                                          Close [/color][color=#000000]#f
                                          [/color][color=#0000C0]Control Set Text [/color][color=#000000]hDlg[/color][color=#8000FF], [/color][color=#000000]%CTL_TEXT[/color][color=#8000FF], [/color][color=#C020C0]"(unable to open file " [/color][color=#8000FF]+ [/color][color=#0000C0]Error$ [/color][color=#8000FF]+ [/color][color=#C020C0]")"
                                        [/color][color=#0000C0]Else
                                          Get$ [/color][color=#000000]#f[/color][color=#8000FF], [/color][color=#0000C0]Lof[/color][color=#8000FF]([/color][color=#000000]#f[/color][color=#8000FF]), [/color][color=#000000]value
                                          [/color][color=#0000C0]Close [/color][color=#000000]#f
                                          [/color][color=#0000C0]Incr [/color][color=#000000]cnt
                                          c [/color][color=#8000FF]= [/color][color=#0000C0]Format$[/color][color=#8000FF]( [/color][color=#000000]cnt[/color][color=#8000FF], [/color][color=#C020C0]"#,##0" [/color][color=#8000FF])
                                          [/color][color=#000000]value [/color][color=#8000FF]= [/color][color=#0000C0]Build$[/color][color=#8000FF]([/color][color=#C020C0]"Load round "[/color][color=#8000FF], [/color][color=#000000]c[/color][color=#8000FF], [/color][color=#0000C0]$CrLf[/color][color=#8000FF], [/color][color=#000000]value [/color][color=#8000FF])
                                          [/color][color=#0000C0]Control Set Text [/color][color=#000000]hDlg[/color][color=#8000FF], [/color][color=#000000]%CTL_TEXT[/color][color=#8000FF], [/color][color=#000000]value
                                        [/color][color=#0000C0]End If
                                      End Sub[/color]
                                      Filewatcher.inc
                                      Code:
                                      [color=#000000]%BUFSIZE [/color][color=#8000FF]= [/color][color=#000000]1024
                                      [/color][color=#0000C0]Sub [/color][color=#000000]NewFileWatcher[/color][color=#8000FF]( [/color][color=#000000]obj [/color][color=#0000C0]As [/color][color=#000000]iFileWatcher[/color][color=#8000FF], [/color][color=#000000]filename [/color][color=#0000C0]As WString[/color][color=#8000FF], [/color][color=#0000C0]ByVal [/color][color=#000000]notifyRoutine [/color][color=#0000C0]As Dword [/color][color=#8000FF])
                                        [/color][color=#000000]obj [/color][color=#8000FF]= [/color][color=#0000C0]Class [/color][color=#C020C0]"cFileWatcher"
                                        [/color][color=#000000]obj.Initialize[/color][color=#8000FF]( [/color][color=#000000]filename[/color][color=#8000FF], [/color][color=#000000]notifyRoutine [/color][color=#8000FF])
                                      [/color][color=#0000C0]End Sub
                                      Sub [/color][color=#000000]StartFilewatcher[/color][color=#8000FF]( [/color][color=#000000]obj [/color][color=#0000C0]As [/color][color=#000000]iFileWatcher[/color][color=#8000FF], [/color][color=#000000]filename [/color][color=#0000C0]As WString[/color][color=#8000FF], [/color][color=#0000C0]ByVal [/color][color=#000000]notifyRoutine [/color][color=#0000C0]As Dword [/color][color=#8000FF])
                                        [/color][color=#0000C0]Call [/color][color=#000000]NewFileWatcher[/color][color=#8000FF]( [/color][color=#000000]obj[/color][color=#8000FF], [/color][color=#000000]filename[/color][color=#8000FF], [/color][color=#000000]notifyRoutine [/color][color=#8000FF])
                                        [/color][color=#000000]obj.Launch[/color][color=#8000FF]( [/color][color=#0000C0]ByVal [/color][color=#000000]0 [/color][color=#8000FF])
                                      [/color][color=#0000C0]End Sub
                                      Sub [/color][color=#000000]NotifyPattern[/color][color=#8000FF]( [/color][color=#000000]filename [/color][color=#0000C0]As WString [/color][color=#8000FF])
                                      [/color][color=#0000C0]End Sub
                                      Class [/color][color=#000000]cFileWatcher
                                        [/color][color=#0000C0]Instance [/color][color=#000000]ThreadParam [/color][color=#0000C0]As Long
                                        Instance [/color][color=#000000]running_ [/color][color=#0000C0]As Long
                                        Instance [/color][color=#000000]notifier_ [/color][color=#0000C0]As [/color][color=#000000]iFileWatchNotifier
                                        [/color][color=#0000C0]Instance [/color][color=#000000]notifyRoutine_ [/color][color=#0000C0]As Dword
                                        Instance [/color][color=#000000]filename_ [/color][color=#0000C0]As WString
                                        Instance [/color][color=#000000]hStop [/color][color=#0000C0]As Dword
                                        Thread Method Main[/color][color=#8000FF]() [/color][color=#0000C0]As Long
                                        #Align [/color][color=#000000]4
                                          [/color][color=#0000C0]Local [/color][color=#000000]buffer1 [/color][color=#0000C0]As StringZ [/color][color=#8000FF]* [/color][color=#000000]%BUFSIZE
                                          [/color][color=#0000C0]Local [/color][color=#000000]buffer2 [/color][color=#0000C0]As StringZ [/color][color=#8000FF]* [/color][color=#000000]%BUFSIZE
                                          [/color][color=#0000C0]Local [/color][color=#000000]hover [/color][color=#0000C0]As [/color][color=#000000]OVERLAPPED
                                          [/color][color=#0000C0]Local [/color][color=#000000]hWait[/color][color=#8000FF]() [/color][color=#0000C0]As Dword
                                          Local [/color][color=#000000]dwWaitStatus[/color][color=#8000FF], [/color][color=#000000]flags[/color][color=#8000FF], [/color][color=#000000]hDir [/color][color=#0000C0]As Dword
                                          Local [/color][color=#000000]fullPath[/color][color=#8000FF], [/color][color=#000000]modFile [/color][color=#0000C0]As WString
                                          Local [/color][color=#000000]finished[/color][color=#8000FF], [/color][color=#000000]numBytes[/color][color=#8000FF], [/color][color=#000000]cnt[/color][color=#8000FF], [/color][color=#000000]i [/color][color=#0000C0]As Long
                                          Local [/color][color=#000000]fn [/color][color=#0000C0]As WString Ptr
                                          Local [/color][color=#000000]fi [/color][color=#0000C0]As [/color][color=#000000]FILE_NOTIFY_INFORMATION
                                          [/color][color=#0000C0]ReDim [/color][color=#000000]hWait[/color][color=#8000FF]([/color][color=#000000]1[/color][color=#8000FF]) [/color][color=#0000C0]As Local Dword
                                          If [/color][color=#8000FF]IsFalse [/color][color=#0000C0]IsFile[/color][color=#8000FF]( [/color][color=#000000]filename_ [/color][color=#8000FF]) Or [/color][color=#000000]notifyRoutine_[/color][color=#8000FF]=[/color][color=#000000]0 [/color][color=#0000C0]Then Exit Method
                                          Call [/color][color=#000000]StartFileWatchNotifier[/color][color=#8000FF]( [/color][color=#000000]notifier_[/color][color=#8000FF], [/color][color=#000000]filename_[/color][color=#8000FF], [/color][color=#000000]notifyRoutine_ [/color][color=#8000FF])
                                          [/color][color=#000000]fullPath [/color][color=#8000FF]= [/color][color=#0000C0]PathScan$[/color][color=#8000FF]( [/color][color=#0000C0]Path[/color][color=#8000FF], [/color][color=#000000]filename_ [/color][color=#8000FF])
                                          [/color][color=#007F00]' Other things we can watch for
                                          '%FILE_NOTIFY_CHANGE_FILE_NAME
                                          '%FILE_NOTIFY_CHANGE_DIR_NAME
                                          '%FILE_NOTIFY_CHANGE_ATTRIBUTES
                                          '%FILE_NOTIFY_CHANGE_SIZE
                                          '%FILE_NOTIFY_CHANGE_SECURITY
                                          [/color][color=#000000]flags [/color][color=#8000FF]= [/color][color=#000000]%FILE_NOTIFY_CHANGE_LAST_WRITE[/color][color=#8000FF]: [/color][color=#007F00]' Watching for file changes/writes
                                          [/color][color=#000000]hDir [/color][color=#8000FF]= [/color][color=#000000]CreateFile[/color][color=#8000FF]( [/color][color=#0000C0]ByVal StrPtr[/color][color=#8000FF]([/color][color=#000000]fullPath[/color][color=#8000FF]), [/color][color=#000000]%FILE_LIST_DIRECTORY[/color][color=#8000FF], [/color][color=#000000]%FILE_SHARE_READ [/color][color=#8000FF]Or [/color][color=#000000]%FILE_SHARE_WRITE [/color][color=#8000FF]Or [/color][color=#000000]%FILE_SHARE_DELETE[/color][color=#8000FF], [/color][color=#0000C0]ByVal [/color][color=#000000]%NULL[/color][color=#8000FF], [/color][color=#000000]%OPEN_EXISTING[/color][color=#8000FF], [/color][color=#000000]%FILE_FLAG_BACKUP_SEMANTICS [/color][color=#8000FF]Or [/color][color=#000000]%FILE_FLAG_OVERLAPPED [/color][color=#8000FF], [/color][color=#000000]%NULL[/color][color=#8000FF])
                                          [/color][color=#000000]hWait[/color][color=#8000FF]([/color][color=#000000]0[/color][color=#8000FF]) = [/color][color=#000000]CreateEvent[/color][color=#8000FF]( [/color][color=#0000C0]ByVal [/color][color=#000000]%NULL[/color][color=#8000FF], [/color][color=#000000]0[/color][color=#8000FF], [/color][color=#000000]0[/color][color=#8000FF], [/color][color=#0000C0]ByVal [/color][color=#000000]%NULL [/color][color=#8000FF])
                                          [/color][color=#000000]hWait[/color][color=#8000FF]([/color][color=#000000]1[/color][color=#8000FF]) = [/color][color=#000000]CreateEvent[/color][color=#8000FF]( [/color][color=#0000C0]ByVal [/color][color=#000000]%NULL[/color][color=#8000FF], [/color][color=#000000]0[/color][color=#8000FF], [/color][color=#000000]0[/color][color=#8000FF], [/color][color=#0000C0]ByVal [/color][color=#000000]%NULL [/color][color=#8000FF])
                                          [/color][color=#000000]hStop [/color][color=#8000FF]= [/color][color=#000000]hWait[/color][color=#8000FF]([/color][color=#000000]1[/color][color=#8000FF])
                                          [/color][color=#000000]hover.hEvent [/color][color=#8000FF]= [/color][color=#000000]hWait[/color][color=#8000FF]([/color][color=#000000]0[/color][color=#8000FF])
                                          [/color][color=#0000C0]Do While [/color][color=#8000FF]-[/color][color=#000000]1
                                            [/color][color=#0000C0]Memory Fill VarPtr[/color][color=#8000FF]( [/color][color=#000000]buffer1 [/color][color=#8000FF]), [/color][color=#000000]%BUFSIZE[/color][color=#8000FF], [/color][color=#0000C0]Byte [/color][color=#000000]0
                                            ResetEvent[/color][color=#8000FF]( [/color][color=#000000]hover.hEvent [/color][color=#8000FF])
                                            [/color][color=#0000C0]If [/color][color=#000000]ReadDirectoryChangesW[/color][color=#8000FF]( [/color][color=#000000]hDir[/color][color=#8000FF], [/color][color=#0000C0]VarPtr[/color][color=#8000FF]([/color][color=#000000]buffer1[/color][color=#8000FF]), [/color][color=#000000]%BUFSIZE[/color][color=#8000FF], [/color][color=#000000]%FALSE[/color][color=#8000FF], [/color][color=#000000]flags[/color][color=#8000FF], [/color][color=#000000]%NULL[/color][color=#8000FF], [/color][color=#000000]hover[/color][color=#8000FF], [/color][color=#000000]%NULL[/color][color=#8000FF]) [/color][color=#0000C0]Then
                                              [/color][color=#000000]dwWaitStatus [/color][color=#8000FF]= [/color][color=#000000]WaitForMultipleObjects[/color][color=#8000FF]( [/color][color=#000000]2[/color][color=#8000FF], [/color][color=#000000]hWait[/color][color=#8000FF]([/color][color=#000000]0[/color][color=#8000FF]), [/color][color=#000000]%FALSE[/color][color=#8000FF], [/color][color=#000000]%INFINITE [/color][color=#8000FF])
                                              [/color][color=#0000C0]Select Case Const [/color][color=#000000]dwWaitStatus [/color][color=#8000FF]- [/color][color=#000000]%WAIT_OBJECT_0
                                                [/color][color=#0000C0]Case [/color][color=#000000]0[/color][color=#8000FF]: [/color][color=#007F00]' Directory change signaled
                                                  'If returnedBytes>0 Then
                                                    [/color][color=#0000C0]Memory Copy VarPtr[/color][color=#8000FF]( [/color][color=#000000]buffer1 [/color][color=#8000FF]), [/color][color=#0000C0]VarPtr[/color][color=#8000FF]( [/color][color=#000000]buffer2 [/color][color=#8000FF]), [/color][color=#000000]%BUFSIZE
                                                    notifier_.Changed[/color][color=#8000FF]( [/color][color=#0000C0]VarPtr[/color][color=#8000FF]( [/color][color=#000000]buffer2 [/color][color=#8000FF]) )
                                                  [/color][color=#007F00]'End If
                                                [/color][color=#0000C0]Case [/color][color=#000000]1[/color][color=#8000FF]: [/color][color=#007F00]' hStop signaled
                                                  [/color][color=#0000C0]Exit Loop
                                              End Select
                                            End If
                                          Loop
                                          [/color][color=#000000]hStop [/color][color=#8000FF]= [/color][color=#000000]0
                                          CloseHandle[/color][color=#8000FF]( [/color][color=#000000]hWait[/color][color=#8000FF]([/color][color=#000000]0[/color][color=#8000FF]) )
                                          [/color][color=#000000]CloseHandle[/color][color=#8000FF]( [/color][color=#000000]hWait[/color][color=#8000FF]([/color][color=#000000]1[/color][color=#8000FF]) )
                                          [/color][color=#000000]CloseHandle[/color][color=#8000FF]( [/color][color=#000000]hDir [/color][color=#8000FF])
                                          [/color][color=#000000]notifier_.Stop[/color][color=#8000FF]()
                                          [/color][color=#000000]notifier_ [/color][color=#8000FF]= [/color][color=#0000C0]Nothing
                                        End Method
                                        Interface [/color][color=#000000]iFileWatcher
                                          [/color][color=#0000C0]Inherit IPowerThread
                                          Method [/color][color=#000000]Initialize[/color][color=#8000FF]( [/color][color=#000000]filename [/color][color=#0000C0]As WString[/color][color=#8000FF], [/color][color=#000000]notifyRoutine [/color][color=#0000C0]As Dword [/color][color=#8000FF])
                                            [/color][color=#0000C0]If [/color][color=#000000]filename[/color][color=#8000FF]=[/color][color=#C020C0]"" [/color][color=#8000FF]Or [/color][color=#000000]notifyRoutine[/color][color=#8000FF]=[/color][color=#000000]0 [/color][color=#0000C0]Then Exit Method
                                            If [/color][color=#000000]filename_ [/color][color=#8000FF]= [/color][color=#C020C0]"" [/color][color=#8000FF]Or [/color][color=#000000]notifyRoutine_ [/color][color=#8000FF]= [/color][color=#000000]0 [/color][color=#0000C0]Then
                                              [/color][color=#000000]filename_ [/color][color=#8000FF]= [/color][color=#000000]filename
                                              notifyRoutine_ [/color][color=#8000FF]= [/color][color=#000000]notifyRoutine
                                            [/color][color=#0000C0]End If
                                          End Method
                                          Property Get [/color][color=#000000]Running[/color][color=#8000FF]() [/color][color=#0000C0]As Long
                                            Property [/color][color=#8000FF]= [/color][color=#000000]running_
                                          [/color][color=#0000C0]End Property
                                          Property Get [/color][color=#000000]Filename[/color][color=#8000FF]() [/color][color=#0000C0]As WString
                                            Property [/color][color=#8000FF]= [/color][color=#000000]filename_
                                          [/color][color=#0000C0]End Property
                                          Property Get [/color][color=#000000]NotifyRoutine[/color][color=#8000FF]() [/color][color=#0000C0]As Dword
                                            Property [/color][color=#8000FF]= [/color][color=#000000]notifyRoutine_
                                          [/color][color=#0000C0]End Property
                                          Method Stop[/color][color=#8000FF]()
                                            [/color][color=#0000C0]Local [/color][color=#000000]fw [/color][color=#0000C0]As [/color][color=#000000]iFileWatcher
                                            fw [/color][color=#8000FF]= [/color][color=#0000C0]Me
                                            [/color][color=#000000]SetEvent[/color][color=#8000FF]( [/color][color=#000000]hStop [/color][color=#8000FF])
                                            [/color][color=#000000]fw.Join[/color][color=#8000FF]( [/color][color=#000000]fw[/color][color=#8000FF], [/color][color=#000000]0 [/color][color=#8000FF])
                                            [/color][color=#000000]fw [/color][color=#8000FF]= [/color][color=#0000C0]Nothing
                                          End Method
                                        End Interface
                                      End Class
                                      Sub [/color][color=#000000]StartFileWatchNotifier[/color][color=#8000FF]( [/color][color=#000000]obj [/color][color=#0000C0]As [/color][color=#000000]iFileWatchNotifier[/color][color=#8000FF], [/color][color=#000000]filename [/color][color=#0000C0]As WString[/color][color=#8000FF], [/color][color=#0000C0]ByVal [/color][color=#000000]notifyRoutine [/color][color=#0000C0]As Dword [/color][color=#8000FF])
                                        [/color][color=#000000]obj [/color][color=#8000FF]= [/color][color=#0000C0]Class [/color][color=#C020C0]"cFileWatchNotifier"
                                        [/color][color=#000000]obj.Initialize[/color][color=#8000FF]( [/color][color=#000000]filename[/color][color=#8000FF], [/color][color=#000000]notifyRoutine [/color][color=#8000FF])
                                        [/color][color=#000000]obj.Launch[/color][color=#8000FF]( [/color][color=#0000C0]ByVal [/color][color=#000000]0 [/color][color=#8000FF])
                                      [/color][color=#0000C0]End Sub
                                      Class [/color][color=#000000]cFileWatchNotifier
                                        [/color][color=#0000C0]Instance [/color][color=#000000]ThreadParam [/color][color=#0000C0]As Long
                                        Instance [/color][color=#000000]changed_ [/color][color=#0000C0]As Dword
                                        Instance [/color][color=#000000]stopped_ [/color][color=#0000C0]As Dword
                                        Instance [/color][color=#000000]notifyRoutine_ [/color][color=#0000C0]As Dword
                                        Instance [/color][color=#000000]filename_ [/color][color=#0000C0]As WString
                                        Instance [/color][color=#000000]fni [/color][color=#0000C0]As [/color][color=#000000]FILE_NOTIFY_INFORMATION [/color][color=#0000C0]Ptr
                                        Thread Method Main[/color][color=#8000FF]() [/color][color=#0000C0]As Long
                                          Local [/color][color=#000000]cnt [/color][color=#0000C0]As Long
                                          Local [/color][color=#000000]fi [/color][color=#0000C0]As [/color][color=#000000]FILE_NOTIFY_INFORMATION [/color][color=#0000C0]Ptr
                                          Local [/color][color=#000000]filename[/color][color=#8000FF], [/color][color=#000000]fullPath[/color][color=#8000FF], [/color][color=#000000]modFile [/color][color=#0000C0]As WString
                                          Local [/color][color=#000000]i[/color][color=#8000FF], [/color][color=#000000]finished [/color][color=#0000C0]As Long
                                          Local [/color][color=#000000]hWait[/color][color=#8000FF]() [/color][color=#0000C0]As Dword
                                          Local [/color][color=#000000]ofs [/color][color=#0000C0]As Long
                                          Dim [/color][color=#000000]hWait[/color][color=#8000FF]([/color][color=#000000]1[/color][color=#8000FF]) [/color][color=#0000C0]As Local Dword
                                          Local [/color][color=#000000]dwWaitStatus [/color][color=#0000C0]As Dword
                                          [/color][color=#000000]hWait[/color][color=#8000FF]([/color][color=#000000]0[/color][color=#8000FF]) = [/color][color=#000000]CreateEvent[/color][color=#8000FF]( [/color][color=#0000C0]ByVal [/color][color=#000000]%NULL[/color][color=#8000FF], [/color][color=#000000]0[/color][color=#8000FF], [/color][color=#000000]0[/color][color=#8000FF], [/color][color=#0000C0]ByVal [/color][color=#000000]%NULL [/color][color=#8000FF])
                                          [/color][color=#000000]hWait[/color][color=#8000FF]([/color][color=#000000]1[/color][color=#8000FF]) = [/color][color=#000000]CreateEvent[/color][color=#8000FF]( [/color][color=#0000C0]ByVal [/color][color=#000000]%NULL[/color][color=#8000FF], [/color][color=#000000]0[/color][color=#8000FF], [/color][color=#000000]0[/color][color=#8000FF], [/color][color=#0000C0]ByVal [/color][color=#000000]%NULL [/color][color=#8000FF])
                                          [/color][color=#000000]changed_ [/color][color=#8000FF]= [/color][color=#000000]hWait[/color][color=#8000FF]([/color][color=#000000]0[/color][color=#8000FF])
                                          [/color][color=#000000]stopped_ [/color][color=#8000FF]= [/color][color=#000000]hWait[/color][color=#8000FF]([/color][color=#000000]1[/color][color=#8000FF])
                                          [/color][color=#000000]fullPath [/color][color=#8000FF]= [/color][color=#0000C0]PathScan$[/color][color=#8000FF]( [/color][color=#0000C0]Path[/color][color=#8000FF], [/color][color=#000000]filename_ [/color][color=#8000FF])
                                          [/color][color=#000000]filename [/color][color=#8000FF]= [/color][color=#0000C0]LCase$[/color][color=#8000FF]( [/color][color=#0000C0]PathScan$[/color][color=#8000FF]( [/color][color=#0000C0]Namex[/color][color=#8000FF], [/color][color=#000000]filename_ [/color][color=#8000FF]) )
                                          [/color][color=#0000C0]Do While [/color][color=#8000FF]-[/color][color=#000000]1
                                            ResetEvent[/color][color=#8000FF]( [/color][color=#000000]changed_ [/color][color=#8000FF])
                                            [/color][color=#000000]dwWaitStatus [/color][color=#8000FF]= [/color][color=#000000]WaitForMultipleObjects[/color][color=#8000FF]( [/color][color=#000000]2[/color][color=#8000FF], [/color][color=#000000]hWait[/color][color=#8000FF]([/color][color=#000000]0[/color][color=#8000FF]), [/color][color=#000000]%FALSE[/color][color=#8000FF], [/color][color=#000000]%INFINITE [/color][color=#8000FF])
                                            [/color][color=#0000C0]Select Case Const [/color][color=#000000]dwWaitStatus [/color][color=#8000FF]- [/color][color=#000000]%WAIT_OBJECT_0
                                              [/color][color=#0000C0]Case [/color][color=#000000]0[/color][color=#8000FF]: [/color][color=#007F00]' Changed
                                                [/color][color=#000000]fi [/color][color=#8000FF]= [/color][color=#000000]fni
                                                finished [/color][color=#8000FF]= [/color][color=#000000]0
                                                [/color][color=#0000C0]While [/color][color=#8000FF]Not [/color][color=#000000]finished
                                                  finished [/color][color=#8000FF]= ( @[/color][color=#000000]fi.NextEntryOffset [/color][color=#8000FF]= [/color][color=#000000]0 [/color][color=#8000FF])
                                                  [/color][color=#0000C0]If [/color][color=#8000FF]@[/color][color=#000000]fi.Action [/color][color=#8000FF]= [/color][color=#000000]%FILE_ACTION_MODIFIED [/color][color=#8000FF]And @[/color][color=#000000]fi.FileNameLength [/color][color=#0000C0]Then
                                                    [/color][color=#000000]modFile [/color][color=#8000FF]= [/color][color=#0000C0]Peek$$[/color][color=#8000FF]( [/color][color=#0000C0]VarPtr[/color][color=#8000FF]( @[/color][color=#000000]fi.FileName [/color][color=#8000FF]), @[/color][color=#000000]fi.FileNameLength [/color][color=#8000FF])
                                                    [/color][color=#000000]i [/color][color=#8000FF]= [/color][color=#0000C0]Len[/color][color=#8000FF]([/color][color=#000000]modFile[/color][color=#8000FF])
                                                    [/color][color=#0000C0]While [/color][color=#000000]i[/color][color=#8000FF]>[/color][color=#000000]1 [/color][color=#8000FF]And [/color][color=#0000C0]Asc[/color][color=#8000FF]([/color][color=#000000]modFile[/color][color=#8000FF],[/color][color=#000000]i[/color][color=#8000FF])<=[/color][color=#000000]32
                                                      [/color][color=#0000C0]Decr [/color][color=#000000]i
                                                    [/color][color=#0000C0]Wend
                                                    [/color][color=#000000]modFile[/color][color=#8000FF]=[/color][color=#0000C0]Left$[/color][color=#8000FF]([/color][color=#000000]modFile[/color][color=#8000FF],[/color][color=#000000]i[/color][color=#8000FF])
                                                    [/color][color=#000000]modFile [/color][color=#8000FF]= [/color][color=#0000C0]LCase$[/color][color=#8000FF]( [/color][color=#0000C0]Dir$[/color][color=#8000FF]( [/color][color=#000000]fullPath [/color][color=#8000FF]+ [/color][color=#000000]modFile [/color][color=#8000FF]) )
                                                    [/color][color=#0000C0]If [/color][color=#000000]modFile [/color][color=#8000FF]= [/color][color=#0000C0]LCase$[/color][color=#8000FF]( [/color][color=#000000]filename [/color][color=#8000FF]) [/color][color=#0000C0]Then
                                                      Call Dword [/color][color=#000000]notifyRoutine_ [/color][color=#0000C0]Using [/color][color=#000000]NotifyPattern[/color][color=#8000FF]( [/color][color=#000000]filename_ [/color][color=#8000FF])
                                                    [/color][color=#0000C0]End If
                                                  End If
                                                  [/color][color=#000000]fi [/color][color=#8000FF]+= @[/color][color=#000000]fi.NextEntryOffset
                                                [/color][color=#0000C0]Wend
                                              Case [/color][color=#000000]1[/color][color=#8000FF]: [/color][color=#007F00]' Stopped
                                                [/color][color=#0000C0]Exit Loop
                                            End Select
                                          Loop
                                        End Method
                                        Interface [/color][color=#000000]iFileWatchNotifier
                                          [/color][color=#0000C0]Inherit IPowerThread
                                          Method [/color][color=#000000]Initialize[/color][color=#8000FF]( [/color][color=#000000]filename [/color][color=#0000C0]As WString[/color][color=#8000FF], [/color][color=#000000]notifyRoutine [/color][color=#0000C0]As Dword [/color][color=#8000FF])
                                            [/color][color=#0000C0]If [/color][color=#000000]filename_[/color][color=#8000FF]<>[/color][color=#C020C0]"" [/color][color=#8000FF]Or [/color][color=#000000]notifyRoutine_ [/color][color=#0000C0]Then Exit Method
                                            [/color][color=#000000]filename_ [/color][color=#8000FF]= [/color][color=#000000]filename
                                            notifyRoutine_ [/color][color=#8000FF]= [/color][color=#000000]notifyRoutine
                                          [/color][color=#0000C0]End Method
                                          Method Stop[/color][color=#8000FF]()
                                            [/color][color=#0000C0]Local [/color][color=#000000]fwn [/color][color=#0000C0]As [/color][color=#000000]iFileWatchNotifier
                                            SetEvent[/color][color=#8000FF]( [/color][color=#000000]stopped_ [/color][color=#8000FF])
                                            [/color][color=#000000]fwn [/color][color=#8000FF]= [/color][color=#0000C0]Me
                                            [/color][color=#000000]fwn.Join[/color][color=#8000FF]( [/color][color=#000000]fwn[/color][color=#8000FF], [/color][color=#000000]0 [/color][color=#8000FF])
                                            [/color][color=#000000]fwn [/color][color=#8000FF]= [/color][color=#0000C0]Nothing
                                          End Method
                                          Method [/color][color=#000000]Changed[/color][color=#8000FF]( [/color][color=#0000C0]ByVal [/color][color=#000000]fi [/color][color=#0000C0]As Dword [/color][color=#8000FF])
                                            [/color][color=#000000]fni [/color][color=#8000FF]= [/color][color=#000000]fi
                                            SetEvent[/color][color=#8000FF]( [/color][color=#000000]changed_ [/color][color=#8000FF])
                                          [/color][color=#0000C0]End Method
                                        End Interface
                                      End Class[/color]
                                      LarryC
                                      Website
                                      Sometimes life's a dream, sometimes it's a scream

                                      Comment


                                      • #20


                                        Did you know...

                                        In Ultra-Edit if you check the "Match Case" box on the "find", neither "pow" nor "thread" will match "IPowerThread?"
                                        Michael Mattias
                                        Tal Systems (retired)
                                        Port Washington WI USA
                                        [email protected]
                                        http://www.talsystems.com

                                        Comment

                                        Working...
                                        X