PostMessage & ON_MESSAGE(...)

Hi.
when I use form ON_MESSAGE(WM_USER+1,ShowInListBox) in my Code
after 2 or 3 Second (Less or More) my Program does Hang! but If I delete ON_MESSAGE(WM_USER+1,ShowInListBox) my Thread work Properly.


this my Code:
////////////////////////////////////////////////////////////////////////////////////

...........

public:
BOOL* GetContinue() {return m_bContinue;}
void SetContinue(BOOL* bContinue) {m_bContinue=bContinue;}

...

.....
void CRandomString::RandStr()
{
ran=rand();
m_sRandStr.Format("%f",ran);
AfxGetMainWnd()->PostMessage(WM_USER+1);
}
////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////

.
.
.
...
BEGIN_MESSAGE_MAP(CSampleThreadDlg, CDialog)
//{{AFX_MSG_MAP(CSampleThreadDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_RUNSTOP, OnRunstop)
ON_WM_DESTROY()
//----------------------------
ON_MESSAGE(WM_USER+1,ShowInListBox)
//-----------------------------------

.
.
.
...
....
void CSampleThreadDlg::InitRandomString()
{
m_cRandomString.SetContinue(NULL);
m_cRandomString.SetContinue(&m_bRunStopTh);
}

UINT CSampleThreadDlg::ThreadFunction(LPVOID pParam)
{
CRandomString* pRanStr=(CRandomString*)pParam;
BOOL *pContinue=pRanStr->GetContinue();
while(*pContinue)
pRanStr->RandStr();
return 0;

}

void CSampleThreadDlg::Suspend(BOOL bSus)
{
if(!bSus)
{
if(m_pcThread)
{
HANDLE hThread=m_pcThread->m_hThread;
::WaitForSingleObject(hThread,INFINITE);
}
}
else
m_pcThread=AfxBeginThread(ThreadFunction,(LPVOID)&m_cRandomString);

}
void CSampleThreadDlg::ShowInListBox(WPARAM wp,LPARAM lp)
{
m_clShow.AddString(m_cRandomString.m_sRandStr);
if(m_clShow.GetCount()>100)
m_clShow.DeleteString(0);
}

void CSampleThreadDlg::OnRunstop()
{
UpdateData(TRUE);
Suspend(m_bRunStopTh);

}

void CSampleThreadDlg::OnDestroy()
{
if(m_bRunStopTh)
{
m_bRunStopTh=FALSE;
Suspend(m_bRunStopTh);
}
CDialog::OnDestroy();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////

thank.




Answer this question

PostMessage & ON_MESSAGE(...)

  • liffey

    No, Martin didn't mean that you should post a DM_SETDEFID, he meant that you should start your custom messages from WM_APP (and not WM_USER). So in your original code, instead of WM_USER+1, use WM_APP+1.



  • Rask

    CriticalSection and Mutexes will change nothing becauise the code is executed in the same thread.
    Do what Nish and I wrote. And if it doesn't work provide us more code and a better explanation of your problem.

    If I want to display some data in a ListBox I just use AddString and it works.

    If you send a message you have to take care that the message is understood correctly. If you send messages with IDs of other messages the messages will be miss understood and can cause serious problems



  • artificer

    Hi Martin!

    thank you very much.



  • zacarias2006

    Hi again!

    is right my Method


    m_clShow is public ListBox in CSamplethread.
    RandStr() Create Random String and return to randStr().

    I know that shuoldn't use public member in ThreadFunction (Static)
    but I don't know that what did I wrong.
    couse when I run my program ...."Debug Assertion Faild"

    I removed AfxGetMainWnd & ON_MESSAGE form my code.

    UINT CSampleThreadDlg::ThreadFunction(LPVOID pParam)
    {
    CRandomString* pRanStr=(CRandomString*)pParam;
    CSampleThreadDlg* pNew=new CSampleThreadDlg;

    BOOL *pContinue=pRanStr->GetContinue();
    while(*pContinue)
    {
    CString str=pRanStr->RandStr();
    pNew->m_clShow.AddString(str);

    }
    return 0;

    }

    again thank.

    Alireza



  • Lakshmi

    Hi Matin. thank you. I have problem yet.

    but when I changed

    void CRandomString::RandStr()
    {
    ran=rand();
    m_sRandStr.Format("%10.0f",ran);
    AfxGetMainWnd()->PostMessage(DM_SETDEFID);
    }

    to

    void CRandomString::RandStr()
    {
    ran=rand();
    m_sRandStr.Format("%10.0f",ran);
    AfxGetMainWnd()->PostMessage(DM_SETDEFID);
    Sleep(1);
    }

    my broblem has solved. but I don't want to use this way.



  • KenY

    Hi Nishant and thank you for Help.

    I have problem yet. my program work properly but when I click on Dialog's caption for "Move" or "Minimize" , my Program does Hang. I don't know why

    when I used Sleep(1) for SpeedDown I hadn't any problem.

    thank you

    Alireza



  • cschaeff

    Really thank.

    this was test for me about MultiThreading. you'r Right. (I'm so Stupid!).

    I understand!

    thank for your Note! My Program Work Properly Now!

    again thank.

    Alireza



  • kgause

    You can not use MFC CWnd objects in a different thread from were they were created. The problem is that the CWnd objects use a object map that thread dependant.

    If you need to use a window from a second thread you have to use the plain window handle.

    But again: What do you ant to do Why do you need a second thread

    Note: If you Send a message to a window that is created by another thread the message must pass the windows message queue and the thread that owns the window must execute a message loop. Only if GetMessage is executed the thread that sends the message can continue execution when the windows thread returns the return value.



  • Christine Zhao - MSFT

    Using WM_USER is dangerours if your class does not derive from CWnd.

    A dialog class uses to messages defined as

    #define DM_GETDEFID (WM_USER+0)
    #define DM_SETDEFID (WM_USER+1)

    So you are replacing in some way the second message.

    Use WM_APP not WM_USER!



  • Dataman911

    Hi again!

    should  I use from CriticalSection or Mutex for this (this way exists in MSDN).

    (for Display some String in Listbox with CPU speed)

    I don't know! I'm very beginner for this subject.

    thank.

    Alireza



  • PostMessage & ON_MESSAGE(...)