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. UI-thread with both message pump and an infinite loop

UI-thread with both message pump and an infinite loop

Scheduled Pinned Locked Moved C / C++ / MFC
designtutorial
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.
  • G GameProfessor

    It doesn't work. I defined my message handler using ON_THREAD_MESSAG macro. And it seems that I must left the CMyThread::Run intact then these message handler can work. How can I have my thread keep on running my send/recv loop while still be able to handle message from the main thread ?

    K Offline
    K Offline
    kasturi_haribabu
    wrote on last edited by
    #5

    I think that you also introduce atleast a Sleep(0) after the DispatchMessage statement.

    S G 2 Replies Last reply
    0
    • G GameProfessor

      It doesn't work. I defined my message handler using ON_THREAD_MESSAG macro. And it seems that I must left the CMyThread::Run intact then these message handler can work. How can I have my thread keep on running my send/recv loop while still be able to handle message from the main thread ?

      S Offline
      S Offline
      Stephen Hewitt
      wrote on last edited by
      #6

      That's because by implementing your own message pump instead of using CWinThread’s you’re bypassing MFC’s message routing architecture. There are always such dangers when mixing low-level code (Win32 calls) and high-level code (MFC’s CWinThread) without understanding how they relate to each other. To do what you’re trying to do within the MFC architecture proceed as follows: 1. Override your CMyThread's OnIdle member function. It should look like this:

      BOOL CMyThread::OnIdle(LONG lCount)
      {
      DoMyWork();
      CWinThread::OnIdle(lCount);
      return TRUE;
      }

      2. Remove your CMyThread::Run override.

      Steve

      G 1 Reply Last reply
      0
      • K kasturi_haribabu

        I think that you also introduce atleast a Sleep(0) after the DispatchMessage statement.

        G Offline
        G Offline
        GameProfessor
        wrote on last edited by
        #7

        It still doesn't work. Actually, can DispatchMessage() work with a message handler defined using macro ON_THREAD_MESSAGE ?

        S 1 Reply Last reply
        0
        • K kasturi_haribabu

          I think that you also introduce atleast a Sleep(0) after the DispatchMessage statement.

          S Offline
          S Offline
          Stephen Hewitt
          wrote on last edited by
          #8

          What for? It will not help.

          Steve

          1 Reply Last reply
          0
          • G GameProfessor

            It still doesn't work. Actually, can DispatchMessage() work with a message handler defined using macro ON_THREAD_MESSAGE ?

            S Offline
            S Offline
            Stephen Hewitt
            wrote on last edited by
            #9

            I don't think so.

            Steve

            1 Reply Last reply
            0
            • S Stephen Hewitt

              That's because by implementing your own message pump instead of using CWinThread’s you’re bypassing MFC’s message routing architecture. There are always such dangers when mixing low-level code (Win32 calls) and high-level code (MFC’s CWinThread) without understanding how they relate to each other. To do what you’re trying to do within the MFC architecture proceed as follows: 1. Override your CMyThread's OnIdle member function. It should look like this:

              BOOL CMyThread::OnIdle(LONG lCount)
              {
              DoMyWork();
              CWinThread::OnIdle(lCount);
              return TRUE;
              }

              2. Remove your CMyThread::Run override.

              Steve

              G Offline
              G Offline
              GameProfessor
              wrote on last edited by
              #10

              this doesn't work because things in OnIdle() can not be a loop and the framework doesn't loop that function by itself. I need an infinite loop. I have try these two methods: Method 1: --> my thread can not handle any message from main thread BOOL CMyThread::OnIdle(LONG lCount) { for(;;) { DoMyWork(); } CWinThread::OnIdle(lCount); return TRUE; } Method 2: --> DoMyWork() only run one time after we send message from Main thread to My thread. BOOL CMyThread::OnIdle(LONG lCount) { DoMyWork(); CWinThread::OnIdle(lCount); return TRUE; } I expect DoMyWork() to be loop to run forever !!! There must be a way, isn't it?

              S 1 Reply Last reply
              0
              • G GameProfessor

                this doesn't work because things in OnIdle() can not be a loop and the framework doesn't loop that function by itself. I need an infinite loop. I have try these two methods: Method 1: --> my thread can not handle any message from main thread BOOL CMyThread::OnIdle(LONG lCount) { for(;;) { DoMyWork(); } CWinThread::OnIdle(lCount); return TRUE; } Method 2: --> DoMyWork() only run one time after we send message from Main thread to My thread. BOOL CMyThread::OnIdle(LONG lCount) { DoMyWork(); CWinThread::OnIdle(lCount); return TRUE; } I expect DoMyWork() to be loop to run forever !!! There must be a way, isn't it?

                S Offline
                S Offline
                Stephen Hewitt
                wrote on last edited by
                #11

                GameProfessor wrote:

                this doesn't work because things in OnIdle() can not be a loop

                It will work: the loop is within MFC's CWinThread::Run function. There should be ***NO*** loop inside OnIdle! Try it and see. Remember to remove your Run override.

                Steve

                G 1 Reply Last reply
                0
                • S Stephen Hewitt

                  GameProfessor wrote:

                  this doesn't work because things in OnIdle() can not be a loop

                  It will work: the loop is within MFC's CWinThread::Run function. There should be ***NO*** loop inside OnIdle! Try it and see. Remember to remove your Run override.

                  Steve

                  G Offline
                  G Offline
                  GameProfessor
                  wrote on last edited by
                  #12

                  i'm sure it wont run because it's the first thing I've tried. !!! Here's the code: LRESULT CMyThread::OnMyMsg(WPARAM wParam, LPARAM lParam) { MessageBox(NULL,"super man","MyMSG message",MB_OK); // this never show up!!! return 0; } int CMyThread::Run() { for (;;) { i++; if (i>=10000) { i = 0; } } return CWinThread::Run(); } BOOL CMyThread::OnIdle(LONG lCount) { // TODO: Add your specialized code here and/or call the base class return CWinThread::OnIdle(lCount); }

                  S 2 Replies Last reply
                  0
                  • G GameProfessor

                    i'm sure it wont run because it's the first thing I've tried. !!! Here's the code: LRESULT CMyThread::OnMyMsg(WPARAM wParam, LPARAM lParam) { MessageBox(NULL,"super man","MyMSG message",MB_OK); // this never show up!!! return 0; } int CMyThread::Run() { for (;;) { i++; if (i>=10000) { i = 0; } } return CWinThread::Run(); } BOOL CMyThread::OnIdle(LONG lCount) { // TODO: Add your specialized code here and/or call the base class return CWinThread::OnIdle(lCount); }

                    S Offline
                    S Offline
                    Stephen Hewitt
                    wrote on last edited by
                    #13

                    I know it will; I've just build a test app from scratch and it does. So just try it ok! Here's code snippits: --------------------- // From CMyThead's implementation: BEGIN_MESSAGE_MAP(CMyThread, CWinThread) //{{AFX_MSG_MAP(CMyThread) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_MSG_MAP ON_THREAD_MESSAGE(WM_USER, OnFromUI) // *******IMPORTANT******* END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMyThread message handlers BOOL CMyThread::OnIdle(LONG lCount) { DoMyWork(); // *******IMPORTANT******* CWinThread::OnIdle(lCount); // *******IMPORTANT******* return TRUE; // *******IMPORTANT******* } void CMyThread::DoMyWork() { } afx_msg LRESULT CMyThread::OnFromUI(WPARAM, LPARAM) { return 0; } // Creating the thead and a dialog: BOOL CWillWorkApp::InitInstance() { // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need. #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif CWinThread *pThread = AfxBeginThread(RUNTIME_CLASS(CMyThread)); CWillWorkDlg dlg(pThread); m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE; } // In the dialog: CWillWorkDlg::CWillWorkDlg(CWinThread *pThread, CWnd* pParent /*=NULL*/) : CDialog(CWillWorkDlg::IDD, pParent) , m_pThread(pThread) // *******IMPORTANT******* { //{{AFX_DATA_INIT(CWillWorkDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CWillWorkDlg::OnButton1() { m_pThread->PostThreadMessage(WM_USER, 0, 0); // *******IMPORTANT******* } =========================== CMyThread::DoMyWork() is called continuously and CMyThread::OnFromUI is called when I press a button from a dia

                    1 Reply Last reply
                    0
                    • G GameProfessor

                      i'm sure it wont run because it's the first thing I've tried. !!! Here's the code: LRESULT CMyThread::OnMyMsg(WPARAM wParam, LPARAM lParam) { MessageBox(NULL,"super man","MyMSG message",MB_OK); // this never show up!!! return 0; } int CMyThread::Run() { for (;;) { i++; if (i>=10000) { i = 0; } } return CWinThread::Run(); } BOOL CMyThread::OnIdle(LONG lCount) { // TODO: Add your specialized code here and/or call the base class return CWinThread::OnIdle(lCount); }

                      S Offline
                      S Offline
                      Stephen Hewitt
                      wrote on last edited by
                      #14

                      The reason your code doesn't work is that you haven't removed your Run override as I instructed. MFC's message pump is in CWinThread::Run but your override (CMyThread::Run) never calls it because it enters an endless loop and the call to MFC's is after it. Remove your Run function entirely.

                      Steve

                      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