CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    May 2006
    Posts
    21

    How to manage user messege sent by PostThreadMessage

    Hi - I have problem with receiving a message sent by PostThreadMessage. I'm posting message from main application class (CWinApp). I'm posting it to my class derived from CWinThread. Part of my thread class code:
    CReaderThread.h
    Code:
    CReaderThread : public CWinThread {
    [...]
    afx_msg void OnMessageTest( WPARAM, LPARAM );
    protected:
    	DECLARE_MESSAGE_MAP()
    [...]
    }
    in CReaderThread.cpp
    Code:
    BEGIN_MESSAGE_MAP(CReaderThread, CWinThread)
    	ON_THREAD_MESSAGE( WM_MESSAGE_TEST, OnMessageTest )
    END_MESSAGE_MAP()
    
    BOOL CReaderThread::InitInstance() {
    	TRACE( _T("CReaderThread::InitInstance() START\r\n") );
    	if ( reader != NULL ) {
    		if ( start() == true ) {
    			mainLoop();
    		}
    	}
    	stop();
    	TRACE( _T("CReaderThread::InitInstance() STOP\r\n") );
    	AfxEndThread(0);
    	return TRUE;
    }
    
    void CReaderThread::mainLoop() {
    	long startTime = 0x00;
    	long endTime = 0x00;
    	long time2wait = 0x00;
    	MSG msg;
    	while ( CRealtime::getInstance()->isWorking() ) {
    		startTime = GetTickCount();
    		if ( PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE) ) {
    			TRACE( _T("RECEIVED message : %i\r\n"), msg.message);
    		}
                    [...]
                    ::WaitForSingleObject( stopEvent->m_hObject, time2wait );
            }
    }
    void CReaderThread::OnMessageTest( WPARAM wP, LPARAM lP ) {
    	TRACE( _T("Get Message wP=%i, lP=%i\r\n"), wP, lP );
    	return;
    }
    BOOL CReaderThread::PreTranslateMessage(MSG* pMsg) {
    	if ( pMsg->message == WM_MESSAGE_TEST ) {
    		OnMessageTest( pMsg->wParam, pMsg->lParam );
    	}
    	return CWinThread::PreTranslateMessage(pMsg);
    }
    I set breakpoints after PeekMessage(), in OnMessageTest() and in PreTranslateMessage() - nothing. Messages are lost. How to make my thread to receive sended messages?
    Greetings.
    AragornX
    Last edited by aragornx; April 27th, 2010 at 04:23 AM. Reason: errors

  2. #2
    Join Date
    Apr 2010
    Posts
    27

    Re: How to manage user messege sent by PostThreadMessage

    AfxEndThread() call looks a bit suspicious. What it's for?

  3. #3
    Join Date
    Apr 2010
    Posts
    27

    Re: How to manage user messege sent by PostThreadMessage

    Also I do not see where you start message loop, where you pump messages.

  4. #4
    Join Date
    May 2006
    Posts
    21

    Re: How to manage user messege sent by PostThreadMessage

    about AfxEndThread - http://msdn.microsoft.com/en-us/libr...8VS.80%29.aspx
    "Must be called from within the thread to be terminated." - so I used it.
    and about message loop - do I need to write it by myself ? I thought that it's implemented in CWinThread. Could you write me a sample of that message loop, and where should I place it ? I need to execute some code in same time intervals - I doing it in my mainLoop()... Thank you for answers...

  5. #5
    Join Date
    Apr 2010
    Posts
    27

    Re: How to manage user messege sent by PostThreadMessage

    About AfxEndThread:
    "Call this function to terminate the currently executing thread."

  6. #6
    Join Date
    Apr 2010
    Posts
    27

    Re: How to manage user messege sent by PostThreadMessage

    I do not remember already how to do that in MFC, but in WinAPI one must do something along the lines of:
    BOOL rv;
    MSG msg = {};
    while (0 != (rv = GetMessage(&msg, 0, 0, 0)))
    {
    if (-1 == rv)
    break;
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }

  7. #7
    Join Date
    May 2006
    Posts
    21

    Re: How to manage user messege sent by PostThreadMessage

    but doesn't it block my main loop ?

  8. #8
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: How to manage user messege sent by PostThreadMessage

    Quote Originally Posted by dvyukov View Post
    AfxEndThread() call looks a bit suspicious. What it's for?
    I agree. It is wrong to call AfxEndThread() here. Just return TRUE from InitInstance() is enough and correct.

    Quote Originally Posted by dvyukov View Post
    Also I do not see where you start message loop, where you pump messages.
    It is started within CWinThread class (CWinThread::Run method).
    So there is no need to explicitely call GetMessage nor TranslateMessage/DispatchMessage
    Last edited by VictorN; April 27th, 2010 at 06:18 AM. Reason: Fixed my own mistake
    Victor Nijegorodov

  9. #9
    Join Date
    Apr 2010
    Posts
    27

    Re: How to manage user messege sent by PostThreadMessage

    Here is code that works:

    class CReaderThread : public CWinThread
    {
    afx_msg void OnMessageTest( WPARAM, LPARAM )
    {
    AfxMessageBox(L"MESSAGE ARRIVED");
    }

    virtual BOOL InitInstance( )
    {
    return 1;
    }

    protected:
    DECLARE_MESSAGE_MAP()
    };


    class Ctest7445App : public CWinApp
    {
    CReaderThread m_thread;
    };


    #define WM_MESSAGE_TEST (WM_USER+1)

    BEGIN_MESSAGE_MAP(CReaderThread, CWinThread)
    ON_THREAD_MESSAGE( WM_MESSAGE_TEST, OnMessageTest )
    END_MESSAGE_MAP()


    BOOL Ctest7445App::InitInstance()
    {
    ...
    m_thread.m_bAutoDelete = 0;
    m_thread.CreateThread();
    ...
    return TRUE;
    }

    void Ctest7445App::OnAppAbout()
    {
    m_thread.PostThreadMessageW(WM_MESSAGE_TEST, 11, 22);
    }

    That's the additional to the default MFC project.

  10. #10
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: How to manage user messege sent by PostThreadMessage

    Quote Originally Posted by aragornx View Post
    Code:
    BOOL CReaderThread::InitInstance() {
    	TRACE( _T("CReaderThread::InitInstance() START\r\n") );
    	if ( reader != NULL ) {
    		if ( start() == true ) {
    			mainLoop();
    		}
    	}
    	stop();
    	TRACE( _T("CReaderThread::InitInstance() STOP\r\n") );
    	AfxEndThread(0);
    	return TRUE;
    }
    The code in bold text is wrong. It is always wrong to do something extensive in InitInstance(). The purpose of InitiInstance) is initialization only, after which you should simply return TRUE so as to allow the built-in message loop to commence. Your code, on the other hand, traps the InitiInstance() function, by calling your mainLoop() function forever, and never allows InitInstance() to return. Thus, you block the built-in message loop from ever even starting.

  11. #11
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: How to manage user messege sent by PostThreadMessage

    Incidentally, it is always a bad architecture to use PostThreadMessage for posting messages to a thread that has any form of a visible window. If the thread hosts any form of a visible window, then the messages posted to it will inevitably be lost under very common circumstances.

    Mike

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured