-
April 27th, 2010, 04:10 AM
#1
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
-
April 27th, 2010, 04:48 AM
#2
Re: How to manage user messege sent by PostThreadMessage
AfxEndThread() call looks a bit suspicious. What it's for?
-
April 27th, 2010, 04:49 AM
#3
Re: How to manage user messege sent by PostThreadMessage
Also I do not see where you start message loop, where you pump messages.
-
April 27th, 2010, 04:56 AM
#4
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...
-
April 27th, 2010, 05:01 AM
#5
Re: How to manage user messege sent by PostThreadMessage
About AfxEndThread:
"Call this function to terminate the currently executing thread."
-
April 27th, 2010, 05:03 AM
#6
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);
}
-
April 27th, 2010, 05:42 AM
#7
Re: How to manage user messege sent by PostThreadMessage
but doesn't it block my main loop ?
-
April 27th, 2010, 06:12 AM
#8
Re: How to manage user messege sent by PostThreadMessage
 Originally Posted by dvyukov
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.
 Originally Posted by dvyukov
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
-
April 27th, 2010, 06:13 AM
#9
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.
-
April 28th, 2010, 02:38 PM
#10
Re: How to manage user messege sent by PostThreadMessage
 Originally Posted by aragornx
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.
-
April 28th, 2010, 02:46 PM
#11
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|