Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Change value to a thread

Change value to a thread

Scheduled Pinned Locked Moved C / C++ / MFC
questioncareer
14 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • _ Offline
    _ Offline
    _Flaviu
    wrote on last edited by
    #1

    I indent to use FindFirstChangeNotification in a class static method in order to use it in a thread, something like this:

    DWORD WINAPI FilesWatchDogThread(LPVOID lpParam)
    {
    HANDLE hFileChange = ::FindFirstChangeNotification((LPCTSTR)lpParam, // folder path
    TRUE,
    FILE_NOTIFY_CHANGE_FILE_NAME);
    if(INVALID_HANDLE_VALUE == hFileChange)
    {
    DWORD dwError = ::GetLastError();
    return dwError;
    }

    while(TRUE)
    {
    ::WaitForSingleObject(hFileChange, INFINITE);
    // do my job
    ::FindNextChangeNotification(hFileChange);
    }
    return 0;
    }

    // somewhere …
    ::CreateThread(NULL, 0, &CMyClass::FilesWatchDogThread, _T("c:\\temp"), 0, NULL);

    but how can Itell the thread when a folder to watch has been changed (I mean _T("c:\\temp") change to _T("e:\\whatever")) ? What should I use for that ? CreateEvent or what ?

    V 1 Reply Last reply
    0
    • _ _Flaviu

      I indent to use FindFirstChangeNotification in a class static method in order to use it in a thread, something like this:

      DWORD WINAPI FilesWatchDogThread(LPVOID lpParam)
      {
      HANDLE hFileChange = ::FindFirstChangeNotification((LPCTSTR)lpParam, // folder path
      TRUE,
      FILE_NOTIFY_CHANGE_FILE_NAME);
      if(INVALID_HANDLE_VALUE == hFileChange)
      {
      DWORD dwError = ::GetLastError();
      return dwError;
      }

      while(TRUE)
      {
      ::WaitForSingleObject(hFileChange, INFINITE);
      // do my job
      ::FindNextChangeNotification(hFileChange);
      }
      return 0;
      }

      // somewhere …
      ::CreateThread(NULL, 0, &CMyClass::FilesWatchDogThread, _T("c:\\temp"), 0, NULL);

      but how can Itell the thread when a folder to watch has been changed (I mean _T("c:\\temp") change to _T("e:\\whatever")) ? What should I use for that ? CreateEvent or what ?

      V Offline
      V Offline
      Victor Nijegorodov
      wrote on last edited by
      #2

      Yes, you can use CreateEvent, change the folder, set its value in lpParam, then SetEvent to let the thread to reread lpParam and continue to work with a new folder. Note, that thread must now wait for multiple objects!

      _ 2 Replies Last reply
      0
      • V Victor Nijegorodov

        Yes, you can use CreateEvent, change the folder, set its value in lpParam, then SetEvent to let the thread to reread lpParam and continue to work with a new folder. Note, that thread must now wait for multiple objects!

        _ Offline
        _ Offline
        _Flaviu
        wrote on last edited by
        #3

        Thank you Victor, can you elaborate a little bit ? Even some pseudo-code will be good :)

        V 1 Reply Last reply
        0
        • _ _Flaviu

          Thank you Victor, can you elaborate a little bit ? Even some pseudo-code will be good :)

          V Offline
          V Offline
          Victor Nijegorodov
          wrote on last edited by
          #4

          Have a look at the [WorkerThreads](http://www.flounder.com/workerthreads.htm) essay of Joe Newcomer. It is MFC issue, but the main concept is the same as for plain Win32 API. Just look at the sections: Pausing a Thread and Thread Shutdown Shutting down a thread from a view or main frame Thread Shutdown Without Polling (Well, you would need something similar to "Pausing" event.

          _ 2 Replies Last reply
          0
          • V Victor Nijegorodov

            Have a look at the [WorkerThreads](http://www.flounder.com/workerthreads.htm) essay of Joe Newcomer. It is MFC issue, but the main concept is the same as for plain Win32 API. Just look at the sections: Pausing a Thread and Thread Shutdown Shutting down a thread from a view or main frame Thread Shutdown Without Polling (Well, you would need something similar to "Pausing" event.

            _ Offline
            _ Offline
            _Flaviu
            wrote on last edited by
            #5

            I have two questions: 1. Why should I use CreateEvent, and if I should, where ? 2. Why should I use WaitForMultipleObjects instead of WaitForSingleObject ?

            V 1 Reply Last reply
            0
            • V Victor Nijegorodov

              Have a look at the [WorkerThreads](http://www.flounder.com/workerthreads.htm) essay of Joe Newcomer. It is MFC issue, but the main concept is the same as for plain Win32 API. Just look at the sections: Pausing a Thread and Thread Shutdown Shutting down a thread from a view or main frame Thread Shutdown Without Polling (Well, you would need something similar to "Pausing" event.

              _ Offline
              _ Offline
              _Flaviu
              wrote on last edited by
              #6

              There will be ideal a little code :)

              L 1 Reply Last reply
              0
              • _ _Flaviu

                I have two questions: 1. Why should I use CreateEvent, and if I should, where ? 2. Why should I use WaitForMultipleObjects instead of WaitForSingleObject ?

                V Offline
                V Offline
                Victor Nijegorodov
                wrote on last edited by
                #7

                1. to inform the worker thread that it must do something (to change the folder in your case). CreateEvent/SetEvent - in the main thread. 2. Because there is already one object: hFileChange. However the thread should react also to the second object created/set by CreateEvent/SetEvent in the main thread.

                1 Reply Last reply
                0
                • _ _Flaviu

                  There will be ideal a little code :)

                  L Offline
                  L Offline
                  leon de boer
                  wrote on last edited by
                  #8

                  Ask and you shall receive .. that is it straight on the windows API. GitHub - LdB-ECM/FolderWatcher[^] There is both the detailed and basic thread monitor code. There is a compiled exe in release/debug if you just want to run and see it.

                  In vino veritas

                  1 Reply Last reply
                  0
                  • V Victor Nijegorodov

                    Yes, you can use CreateEvent, change the folder, set its value in lpParam, then SetEvent to let the thread to reread lpParam and continue to work with a new folder. Note, that thread must now wait for multiple objects!

                    _ Offline
                    _ Offline
                    _Flaviu
                    wrote on last edited by
                    #9

                    Here is what I've done:

                    // TestFileView.h : interface of the CTestFileView class

                    protected:
                    CEvent m_event;
                    CString m_sFolder;
                    CWinThread* m_pWinThread;

                    /*static*/UINT CTestFileView::FilesWatchDogThread(LPVOID lpParam)
                    {
                    CTestFileView* pView = (CTestFileView*)lpParam;

                    if (NULL == pView->GetSafeHwnd())
                    	return 1;
                    
                    HANDLE hChange = FindFirstChangeNotification(pView->GetFolder(), FALSE,	FILE\_NOTIFY\_CHANGE\_FILE\_NAME);
                    
                    if (INVALID\_HANDLE\_VALUE == hChange)
                    	return 1;
                    
                    HANDLE aHandles\[2\];
                    aHandles\[0\] = hChange;
                    aHandles\[1\] = pView->m\_event.m\_hObject;
                    
                    BOOL bContinue = TRUE;
                    while (bContinue)
                    {
                    	DWORD dwResult = WaitForMultipleObjects(2, aHandles, FALSE, INFINITE);
                    	switch (dwResult)
                    	{
                    	case WAIT\_OBJECT\_0:
                    		::PostMessage(pView->GetSafeHwnd(), WMU\_NOTIFY\_FOLDERCHANGED, 0, (LPARAM)0);
                    		FindNextChangeNotification(hChange);
                    		break;
                    	case WAIT\_OBJECT\_0 + 1:
                    		bContinue = FALSE;
                    		break;
                    	}
                    }
                    
                    FindCloseChangeNotification(hChange);
                    
                    return 0;
                    

                    }

                    and

                    void CTestFileView::StopThread()
                    {
                    m_event.SetEvent();
                    WaitForSingleObject(&m_event, INFINITE);
                    }

                    and

                    void CTestFileView::OnEditStartthread()
                    {
                    // TODO: Add your command handler code here

                    m\_event.ResetEvent();
                    m\_sFolder.Format(\_T("D:\\\\Tempx\\\\"));
                    m\_pWinThread = AfxBeginThread(&CTestFileView::FilesWatchDogThread, (LPVOID)this, THREAD\_PRIORITY\_NORMAL, CREATE\_SUSPENDED, 0, NULL);
                    

                    }

                    there is remain one thing to do: to change the folder (m_sFolder) how can I complete this with CreateEvent/SetEvent ?

                    _ 1 Reply Last reply
                    0
                    • _ _Flaviu

                      Here is what I've done:

                      // TestFileView.h : interface of the CTestFileView class

                      protected:
                      CEvent m_event;
                      CString m_sFolder;
                      CWinThread* m_pWinThread;

                      /*static*/UINT CTestFileView::FilesWatchDogThread(LPVOID lpParam)
                      {
                      CTestFileView* pView = (CTestFileView*)lpParam;

                      if (NULL == pView->GetSafeHwnd())
                      	return 1;
                      
                      HANDLE hChange = FindFirstChangeNotification(pView->GetFolder(), FALSE,	FILE\_NOTIFY\_CHANGE\_FILE\_NAME);
                      
                      if (INVALID\_HANDLE\_VALUE == hChange)
                      	return 1;
                      
                      HANDLE aHandles\[2\];
                      aHandles\[0\] = hChange;
                      aHandles\[1\] = pView->m\_event.m\_hObject;
                      
                      BOOL bContinue = TRUE;
                      while (bContinue)
                      {
                      	DWORD dwResult = WaitForMultipleObjects(2, aHandles, FALSE, INFINITE);
                      	switch (dwResult)
                      	{
                      	case WAIT\_OBJECT\_0:
                      		::PostMessage(pView->GetSafeHwnd(), WMU\_NOTIFY\_FOLDERCHANGED, 0, (LPARAM)0);
                      		FindNextChangeNotification(hChange);
                      		break;
                      	case WAIT\_OBJECT\_0 + 1:
                      		bContinue = FALSE;
                      		break;
                      	}
                      }
                      
                      FindCloseChangeNotification(hChange);
                      
                      return 0;
                      

                      }

                      and

                      void CTestFileView::StopThread()
                      {
                      m_event.SetEvent();
                      WaitForSingleObject(&m_event, INFINITE);
                      }

                      and

                      void CTestFileView::OnEditStartthread()
                      {
                      // TODO: Add your command handler code here

                      m\_event.ResetEvent();
                      m\_sFolder.Format(\_T("D:\\\\Tempx\\\\"));
                      m\_pWinThread = AfxBeginThread(&CTestFileView::FilesWatchDogThread, (LPVOID)this, THREAD\_PRIORITY\_NORMAL, CREATE\_SUSPENDED, 0, NULL);
                      

                      }

                      there is remain one thing to do: to change the folder (m_sFolder) how can I complete this with CreateEvent/SetEvent ?

                      _ Offline
                      _ Offline
                      _Flaviu
                      wrote on last edited by
                      #10

                      "Go to ParentYes, you can use CreateEvent, change the folder, set its value in lpParam, then SetEvent to let the thread to reread lpParam and continue to work with a new folder" To create a third event which stop the thread and restart FilesWatchDogThread method with new folder value ?

                      V 1 Reply Last reply
                      0
                      • _ _Flaviu

                        "Go to ParentYes, you can use CreateEvent, change the folder, set its value in lpParam, then SetEvent to let the thread to reread lpParam and continue to work with a new folder" To create a third event which stop the thread and restart FilesWatchDogThread method with new folder value ?

                        V Offline
                        V Offline
                        Victor Nijegorodov
                        wrote on last edited by
                        #11

                        yes, you create the third event and NOT to stop thread, but to change the folder! Something like:

                        case WAIT\_OBJECT\_0 + 2:
                        	FindCloseChangeNotification(hChange);
                        	hChange = FindFirstChangeNotification(pView->GetFolder(), FALSE,	FILE\_NOTIFY\_CHANGE\_FILE\_NAME);
                        	aHandles\[1\] = pView->m\_event.m\_hObject;
                        

                        And don't forget to set the new folder from the main thread BEFORE setting this event!

                        _ 2 Replies Last reply
                        0
                        • V Victor Nijegorodov

                          yes, you create the third event and NOT to stop thread, but to change the folder! Something like:

                          case WAIT\_OBJECT\_0 + 2:
                          	FindCloseChangeNotification(hChange);
                          	hChange = FindFirstChangeNotification(pView->GetFolder(), FALSE,	FILE\_NOTIFY\_CHANGE\_FILE\_NAME);
                          	aHandles\[1\] = pView->m\_event.m\_hObject;
                          

                          And don't forget to set the new folder from the main thread BEFORE setting this event!

                          _ Offline
                          _ Offline
                          _Flaviu
                          wrote on last edited by
                          #12

                          Yes, has been done. Thank you all of you.

                          1 Reply Last reply
                          0
                          • V Victor Nijegorodov

                            yes, you create the third event and NOT to stop thread, but to change the folder! Something like:

                            case WAIT\_OBJECT\_0 + 2:
                            	FindCloseChangeNotification(hChange);
                            	hChange = FindFirstChangeNotification(pView->GetFolder(), FALSE,	FILE\_NOTIFY\_CHANGE\_FILE\_NAME);
                            	aHandles\[1\] = pView->m\_event.m\_hObject;
                            

                            And don't forget to set the new folder from the main thread BEFORE setting this event!

                            _ Offline
                            _ Offline
                            _Flaviu
                            wrote on last edited by
                            #13

                            Do you meant

                            aHandles[0] = hChange;

                            instead of

                            aHandles[1] = pView->m_event.m_hObject;

                            ?

                            V 1 Reply Last reply
                            0
                            • _ _Flaviu

                              Do you meant

                              aHandles[0] = hChange;

                              instead of

                              aHandles[1] = pView->m_event.m_hObject;

                              ?

                              V Offline
                              V Offline
                              Victor Nijegorodov
                              wrote on last edited by
                              #14

                              Yes! Sorry for the typo! :sigh:

                              1 Reply Last reply
                              0
                              Reply
                              • Reply as topic
                              Log in to reply
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes


                              • Login

                              • Don't have an account? Register

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • World
                              • Users
                              • Groups