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. Sending windows message from worker thread

Sending windows message from worker thread

Scheduled Pinned Locked Moved C / C++ / MFC
c++helptutorialquestion
7 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.
  • G Offline
    G Offline
    GC104
    wrote on last edited by
    #1

    Hello, I am currently getting to grips with MFC, VC++, VS2010 and threading. In particular I am trying to start a thread from a CMainFrame object, then post a windows message from the thread back to he CMainFrame object such that a messagebox can be displayed indicating the progress of the thread. In this example the uses starts the thread from a drop-down menu item (CreateWorkerThread function is called) the thread code executes and sends a single windows message towards the end of the thread. The problem I have is that CMainFrame doesn't seem to respond to the message unless the function that starts the thread uses a ::WaitForSingleObject() call. Why do I need to effectively pause the execution of the function creating the thread? Mayby naively, I assumed the following actions: -User selects Menu item -CreateWorkerThread() is called -Thread executes in parallel with the remains of CreateWorkerThread() -Worker thread generates a windows message (using ::PostMessage()) -By now CreateWorkerThread() would have completed. -CMainFrame Message map processes Worker Thread' message 'WM_THREAD1MSG' -Messagebox created and presented to user.

    void CMainFrame::CreateWorkerThread(void)
    // Created 25FEB2011
    {

    HWND hWnd = GetSafeHwnd();
    if (hWnd == NULL)
    {
    	TRACE0("Window pointer is invalid!");
    }
    
    
    hWnd = GetSafeHwnd();	//hWnd has been made a 'public' member
    
    pThread1 = AfxBeginThread(mcProc, static\_cast<LPVOID>(&hWnd), THREAD\_PRIORITY\_NORMAL, 0, CREATE\_SUSPENDED);	
    pThread1 ->ResumeThread(); 
    
    DWORD ThreadExitCodeValue = 0;
    LPDWORD pDWord = NULL;
    pDWord = &ThreadExitCodeValue;
    
    //Need a handle for the thread:
    HANDLE pThreadHandle = pThread1->m\_hThread;
    
    
    ::WaitForSingleObject(pThreadHandle,INFINITE); //stops this 'thread' until worker thread exits.
    

    }

    BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
    ON_WM_CREATE()

    ON\_MESSAGE(WM\_THREAD1MSG, Respond2ThreadMsg)  //#define WM\_THREAD1MSG WM\_APP + 0x10 <- this line included in stdafx.h
    
    ON\_COMMAND(ID\_VIEW\_CUSTOMIZE, &CMainFrame::OnViewCustomize)
    ON\_REGISTERED\_MESSAGE(AFX\_WM\_CREATETOOLBAR, &CMainFrame::OnToolbarCreateNew)
    ON\_COMMAND\_RANGE(ID\_VIEW\_APPLOOK\_WIN\_2000, ID\_VIEW\_APPLOOK\_WINDOWS\_7, &CMainFrame::OnApplicationLook)
    ON\_UPDATE\_COMMAND\_UI\_RANGE(ID\_VIEW\_APPLOOK\_WIN\_2000, ID\_VIEW\_APPLOOK\_WINDOWS\_7, &CMainFrame::OnUpdateApplicationLook)
    
    ON\_COMMAND(ID\_GCCODEDVMT\_TESTCOMMAND, TestCommand)		//GC added 23FEB2011
    ON\_COMMAND(ID\_GCCODEDVMT\_CREATEWORKERTHREAD, C
    
    C P 2 Replies Last reply
    0
    • G GC104

      Hello, I am currently getting to grips with MFC, VC++, VS2010 and threading. In particular I am trying to start a thread from a CMainFrame object, then post a windows message from the thread back to he CMainFrame object such that a messagebox can be displayed indicating the progress of the thread. In this example the uses starts the thread from a drop-down menu item (CreateWorkerThread function is called) the thread code executes and sends a single windows message towards the end of the thread. The problem I have is that CMainFrame doesn't seem to respond to the message unless the function that starts the thread uses a ::WaitForSingleObject() call. Why do I need to effectively pause the execution of the function creating the thread? Mayby naively, I assumed the following actions: -User selects Menu item -CreateWorkerThread() is called -Thread executes in parallel with the remains of CreateWorkerThread() -Worker thread generates a windows message (using ::PostMessage()) -By now CreateWorkerThread() would have completed. -CMainFrame Message map processes Worker Thread' message 'WM_THREAD1MSG' -Messagebox created and presented to user.

      void CMainFrame::CreateWorkerThread(void)
      // Created 25FEB2011
      {

      HWND hWnd = GetSafeHwnd();
      if (hWnd == NULL)
      {
      	TRACE0("Window pointer is invalid!");
      }
      
      
      hWnd = GetSafeHwnd();	//hWnd has been made a 'public' member
      
      pThread1 = AfxBeginThread(mcProc, static\_cast<LPVOID>(&hWnd), THREAD\_PRIORITY\_NORMAL, 0, CREATE\_SUSPENDED);	
      pThread1 ->ResumeThread(); 
      
      DWORD ThreadExitCodeValue = 0;
      LPDWORD pDWord = NULL;
      pDWord = &ThreadExitCodeValue;
      
      //Need a handle for the thread:
      HANDLE pThreadHandle = pThread1->m\_hThread;
      
      
      ::WaitForSingleObject(pThreadHandle,INFINITE); //stops this 'thread' until worker thread exits.
      

      }

      BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
      ON_WM_CREATE()

      ON\_MESSAGE(WM\_THREAD1MSG, Respond2ThreadMsg)  //#define WM\_THREAD1MSG WM\_APP + 0x10 <- this line included in stdafx.h
      
      ON\_COMMAND(ID\_VIEW\_CUSTOMIZE, &CMainFrame::OnViewCustomize)
      ON\_REGISTERED\_MESSAGE(AFX\_WM\_CREATETOOLBAR, &CMainFrame::OnToolbarCreateNew)
      ON\_COMMAND\_RANGE(ID\_VIEW\_APPLOOK\_WIN\_2000, ID\_VIEW\_APPLOOK\_WINDOWS\_7, &CMainFrame::OnApplicationLook)
      ON\_UPDATE\_COMMAND\_UI\_RANGE(ID\_VIEW\_APPLOOK\_WIN\_2000, ID\_VIEW\_APPLOOK\_WINDOWS\_7, &CMainFrame::OnUpdateApplicationLook)
      
      ON\_COMMAND(ID\_GCCODEDVMT\_TESTCOMMAND, TestCommand)		//GC added 23FEB2011
      ON\_COMMAND(ID\_GCCODEDVMT\_CREATEWORKERTHREAD, C
      
      C Offline
      C Offline
      CPallini
      wrote on last edited by
      #2

      You're passing the address of a temporary variable to the thread: when CreateWorkerThread exits, hWnd goes out of scope. BTW: There is really no need to pass a pointer to the HWND, just pass the HWND value. :)

      If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
      This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
      [My articles]

      G 1 Reply Last reply
      0
      • C CPallini

        You're passing the address of a temporary variable to the thread: when CreateWorkerThread exits, hWnd goes out of scope. BTW: There is really no need to pass a pointer to the HWND, just pass the HWND value. :)

        If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
        This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
        [My articles]

        G Offline
        G Offline
        GC104
        wrote on last edited by
        #3

        Many thanks for feedback :) Since posting this message I realised that I have been using the WINAPI PostMessage() function call rather than the MFC wrapper CWnd::PostMessage(). Which is the preferred method? regards Geoff

        P C 2 Replies Last reply
        0
        • G GC104

          Hello, I am currently getting to grips with MFC, VC++, VS2010 and threading. In particular I am trying to start a thread from a CMainFrame object, then post a windows message from the thread back to he CMainFrame object such that a messagebox can be displayed indicating the progress of the thread. In this example the uses starts the thread from a drop-down menu item (CreateWorkerThread function is called) the thread code executes and sends a single windows message towards the end of the thread. The problem I have is that CMainFrame doesn't seem to respond to the message unless the function that starts the thread uses a ::WaitForSingleObject() call. Why do I need to effectively pause the execution of the function creating the thread? Mayby naively, I assumed the following actions: -User selects Menu item -CreateWorkerThread() is called -Thread executes in parallel with the remains of CreateWorkerThread() -Worker thread generates a windows message (using ::PostMessage()) -By now CreateWorkerThread() would have completed. -CMainFrame Message map processes Worker Thread' message 'WM_THREAD1MSG' -Messagebox created and presented to user.

          void CMainFrame::CreateWorkerThread(void)
          // Created 25FEB2011
          {

          HWND hWnd = GetSafeHwnd();
          if (hWnd == NULL)
          {
          	TRACE0("Window pointer is invalid!");
          }
          
          
          hWnd = GetSafeHwnd();	//hWnd has been made a 'public' member
          
          pThread1 = AfxBeginThread(mcProc, static\_cast<LPVOID>(&hWnd), THREAD\_PRIORITY\_NORMAL, 0, CREATE\_SUSPENDED);	
          pThread1 ->ResumeThread(); 
          
          DWORD ThreadExitCodeValue = 0;
          LPDWORD pDWord = NULL;
          pDWord = &ThreadExitCodeValue;
          
          //Need a handle for the thread:
          HANDLE pThreadHandle = pThread1->m\_hThread;
          
          
          ::WaitForSingleObject(pThreadHandle,INFINITE); //stops this 'thread' until worker thread exits.
          

          }

          BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
          ON_WM_CREATE()

          ON\_MESSAGE(WM\_THREAD1MSG, Respond2ThreadMsg)  //#define WM\_THREAD1MSG WM\_APP + 0x10 <- this line included in stdafx.h
          
          ON\_COMMAND(ID\_VIEW\_CUSTOMIZE, &CMainFrame::OnViewCustomize)
          ON\_REGISTERED\_MESSAGE(AFX\_WM\_CREATETOOLBAR, &CMainFrame::OnToolbarCreateNew)
          ON\_COMMAND\_RANGE(ID\_VIEW\_APPLOOK\_WIN\_2000, ID\_VIEW\_APPLOOK\_WINDOWS\_7, &CMainFrame::OnApplicationLook)
          ON\_UPDATE\_COMMAND\_UI\_RANGE(ID\_VIEW\_APPLOOK\_WIN\_2000, ID\_VIEW\_APPLOOK\_WINDOWS\_7, &CMainFrame::OnUpdateApplicationLook)
          
          ON\_COMMAND(ID\_GCCODEDVMT\_TESTCOMMAND, TestCommand)		//GC added 23FEB2011
          ON\_COMMAND(ID\_GCCODEDVMT\_CREATEWORKERTHREAD, C
          
          P Offline
          P Offline
          prasad_som
          wrote on last edited by
          #4

          You already got answer in earlier post. If you want to pass pointer to handle, use address of m_hHandle member variable, which is handle of CMainFrame. No need to call GetSafeHwnd.

          1 Reply Last reply
          0
          • G GC104

            Many thanks for feedback :) Since posting this message I realised that I have been using the WINAPI PostMessage() function call rather than the MFC wrapper CWnd::PostMessage(). Which is the preferred method? regards Geoff

            P Offline
            P Offline
            prasad_som
            wrote on last edited by
            #5

            CWnd::PostMessage internally calls win32 ::PostMessage. I'll use CWnd::PostMessage, if I've CWnd object(no need to wrap window handle, specially to use this version), and ::PostMessage, if I've window handle.

            C 1 Reply Last reply
            0
            • G GC104

              Many thanks for feedback :) Since posting this message I realised that I have been using the WINAPI PostMessage() function call rather than the MFC wrapper CWnd::PostMessage(). Which is the preferred method? regards Geoff

              C Offline
              C Offline
              CPallini
              wrote on last edited by
              #6

              GC104 wrote:

              I have been using the WINAPI PostMessage() function call rather than the MFC wrapper CWnd::PostMessage()

              You have to use the Windows API function. Worker threads aren't CWnd. :)

              If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
              This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
              [My articles]

              1 Reply Last reply
              0
              • P prasad_som

                CWnd::PostMessage internally calls win32 ::PostMessage. I'll use CWnd::PostMessage, if I've CWnd object(no need to wrap window handle, specially to use this version), and ::PostMessage, if I've window handle.

                C Offline
                C Offline
                CPallini
                wrote on last edited by
                #7

                prasad_som wrote:

                I'll use CWnd::PostMessage, if I've CWnd object(no need to wrap window handle, specially to use this version), and ::PostMessage, if I've window handle.

                So you'll use both at the same time when you have a CWnd object... :rolleyes: Pardon the silly humour...

                If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
                This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
                [My articles]

                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