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

    New to threads and messages

    I am trying to write a program which constantly polls the serial port waiting for an input (why I'm bothering I have no idea - I'm sure millions of other people have already done it successfully!) but anyway, I have created a new thread (using AfxBeginThread) to constantly check, and send a message to the main thread when it finds anything in the buffer:

    UINT ThreadProc(LPVOID pParam)//global func called by the thread
    {
    CSerialDlg* pParent=(CSerialDlg*)pParam;
    pParent->ReadSerial();
    return 0;
    }

    void CSerialDlg::ReadSerial() //member function called by the global function
    {
    CString Output = "";
    unsigned char OutputBuffer[1024];
    int BytesRead;
    CString Text;

    while(1)
    {
    while((BytesRead = ReadComms(OutputBuffer, 1024)) > 0)
    {
    OutputBuffer[BytesRead] = '\0';
    Output = OutputBuffer;
    m_pOutputString = &Output;
    this->PostMessage(WM_SERIAL, 0, 0); //it crashes somewhere around here
    }
    ::Sleep(0);
    }
    }



    The problem I have is that in release mode the program crashes after the second time the message is posted. This happens under NT and 95. In 95 I get an invalid page fault and in NT it just says "the memory cannot be read".

    The message is declared as follows:

    #define WM_SERIAL WM_USER+100

    BEGIN_MESSAGE_MAP(CSerialDlg, CDialog)
    //{{AFX_MSG_MAP(CSerialDlg)
    ...
    ON_THREAD_MESSAGE(WM_SERIAL, OnSerialMessage)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()



    and in the .h file:

    // Generated message map functions
    //{{AFX_MSG(CSerialDlg)
    ...
    afx_msg void OnSerialMessage();

    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()



    the message handler function is as follows:

    void CSerialDlg::OnSerialMessage()
    {
    m_Output += *m_pOutputString;
    m_Output.Replace("\r\n", "\n");
    m_Output.Replace("\n", "\r\n");
    UpdateData(FALSE);
    }



    I hope I have given enough information for someone to be able to help with this problem. This is my first attempt at working with threads or messages, so I really don't have much idea what I'm doing!

    Thanks,
    Jess


  2. #2
    Guest

    Re: New to threads and messages

    Hi,
    I think the problem is that you are changing the String (m_pOutputString) in the thread (ReadSerial) while you access the String in the Dialog (OnSerialMessage).
    One possibility is to allocate a String in the thread, send it with the PostMessage to the Dialog and delete the String in the Dialog when you made the access.

    Hope this helps you!



  3. #3
    Join Date
    May 1999
    Posts
    9

    Re: New to threads and messages

    Hi,

    Thanks for your answer.. I was worried that accessing the string in both threads might cause problems, but unfortunately I don't think it causes *this* problem. Even if I comment out all the lines referring to the output string (or even all the lines in OnSerialMessage) it still crashes in the same way!

    Any other suggestions?

    Jess


  4. #4
    Join Date
    May 1999
    Posts
    9

    Re: New to threads and messages

    P.S
    Sorry for my ignorance but how do you send a CString with a PostMessage?


  5. #5
    Join Date
    Aug 1999
    Posts
    9

    Re: New to threads and messages

    Interesting point about the polling. If you use ReadFile it will block and nicely tell you when a byte has come in.

    re: release mode. Set up your project to generate .pdb files and use the debugger to see what's going on.

    re: posting a message with an address. Since the msg loop and the Post() are in the same Process, you can just pass the address in lParam or wParam.

    Still don't know why your code is crashing, though

    John A




  6. #6
    Guest

    Re: New to threads and messages

    Hi,
    sorry, I ignored your MessageMap. ON_THREAD_MESSAGE you can only use if your class is derived from CWinThread. In your case you should use ON_MESSAGE(WM....,OnSerialMessage)
    Prototyp: ...::OnSerialMessage(WPARAM wParam, LPARAM lParam)
    You can use the lParam for example for your String.

    Hope it´s working now.



  7. #7
    Join Date
    May 1999
    Posts
    9

    Re: New to threads and messages

    Yay!! It works now, thanks Anonymous. I had actually changed the ON_THREAD_MESSAGE to ON_MESSAGE just after my first post, but still couldn't understand why it was crashing - I can't believe it was something as simple as leaving out the parameters in the OnSerialMessage function. I somehow thought they were optional

    Thanks again,
    Jess


  8. #8
    Join Date
    May 1999
    Posts
    9

    Re: New to threads and messages

    Why thankyou Arrizza, debugging in release mode.. I didn't realise it could be done!

    The code is fixed with regard to the crashing, but I will take your advice about how to pass the string.

    I'd love to give Anon some points for fixing the crash which has been bugging me for days, but sadly he/she is anonymous so I can't!


  9. #9
    Guest

    Re: New to threads and messages

    I have the same problem as this although mine is a little different.
    It ONLY posts the message back to my main Dialog-based application the first
    time PostMessage() or SendMessage() has been issued. On the next calls does
    not do anything. It skips the PostMessage() and/or SendMessage() function.
    Could someone help me?

    Thanks



  10. #10
    Guest

    Re: New to threads and messages

    My problems is somewhat similar to Jess'. However, mine does not crash but instead it ignores succeeding calls to PostMessage() and/or SendMessage().

    I have a dialog based application where i call my thread like this:


    DWORD readstatusID;
    ReadAndStatusThreadInfo readThreadInfo;

    readThreadInfo.m_hwndMainDialogHandle = AfxGetMainWnd()->m_hWnd;

    g_readThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReadDataAndStat, (LPVOID)&readThreadInfo, 0, &readstatusID);

    then my Thread Procedure is Something like this:
    :
    :
    if(bytesRead != MAX_READ_BUFFER)
    {
    ::SendMessage(pInfo->m_hwndMainDialogHandle, WM_USER_READSTATUS_MSG, STATUS_WINDOW, READ_TIMEOUT);
    AfxMessageBox("Sample String!");
    }

    :
    :
    LRESULT CSerialComDlg::OnNewMessageString(WPARAM msgDest, LPARAM msgType)
    {
    if(int(msgDest) == DATA_WINDOW)
    AppendToReadWindow(int(msgType));
    else
    AppendToStatusWindow(int(msgType));

    return 0;
    }

    AppendToStatusWindow() simply adds a string to my list box.

    The problem is that it only displays the string during the first time it is called. and not everytime. But the call to AfxMessageBox("Sample String"),
    after the PostMessage() is always done.

    Can someone enlighten me?

    Thanks.

    Butch


















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