CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 25

Thread: PostMessage

Hybrid View

  1. #1
    Join Date
    Dec 2007
    Location
    France
    Posts
    329

    PostMessage

    I found a very strange behaviour.
    Im sending a message from a worker thread to the main window.
    If I uncomment the 'cout' line its working properly main window gets all the strings Im sending.
    But if I comment out 'cout' it only gets the first one again and again.
    It would seem that lstrcpy() only copies the first string if I comment out 'cout'.
    I dont see the relation between the two.

    Code:
    DWORD WINAPI ShowProcess()
    {
       ...
    
        TCHAR* pItem = new TCHAR[MAX_PATH];
        string str;
        stringstream ss(s);
        while (getline(ss, str, '?'))
        {
           lstrcpy(pItem, (TCHAR*)str.c_str());
           PostMessage(hwnd, WM_USERDEFINED, (WPARAM)pItem, 0);
           //cout << "item  "  << pItem << endl;
        }
    
        delete pItem;
        return 0;
    }
    WndProc:
    Code:
        case WM_USERDEFINED:
     
            SendMessage(hListBox,  LB_ADDSTRING, (WPARAM)0, (LPARAM)(TCHAR*)wParam);
          
            return 0;
    Last edited by MasterDucky; June 27th, 2014 at 12:57 PM.

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: PostMessage

    PostMessage is asynchronous so you have no guarantees on when the data is read on the other thread. To see a change in this behavior, declare the string buffer inside the while loop (or use SendMessage as a test).

  3. #3
    Join Date
    Dec 2007
    Location
    France
    Posts
    329

    Re: PostMessage

    It works with SendMessage but I was advised to use PostMessage from a thread instead.

    It works also with declaring and deleting the string buffer in every loop but I thought it was an overkill.

    Looks like it was designed this way then.

    Thank you.
    Last edited by MasterDucky; June 30th, 2014 at 03:15 AM.

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

    Re: PostMessage

    Quote Originally Posted by MasterDucky View Post
    It works also with declaring and deleting the string buffer in every loop but I thought it was an overkill. Looks like there is no other way to program it.
    It is not an "overkill". It is a standard way to implement the messaging from a worker thread. And I already pointed out in your other thread (maybe too short?) how to implement it.
    Victor Nijegorodov

  5. #5
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: PostMessage

    Quote Originally Posted by MasterDucky View Post
    It works with SendMessage but I was advised to use PostMessage from a thread instead.

    It works also with declaring and deleting the string buffer in every loop but I thought it was an overkill.

    Looks like it was designed this way then.

    Thank you.
    If you use PostMessage, then the receivng thread needs to delete the buffer not the sending thread (for the reasons I've decribed previously).

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

    Re: PostMessage

    Quote Originally Posted by Arjay View Post
    If you use PostMessage, then the receivng thread needs to delete the buffer not the sending thread (for the reasons I've decribed previously).
    Absolutely true!
    However, with an exception: if PostMessage has failed then the sending thread must delete the buffer:
    Code:
        string str;
        stringstream ss(s);
        while (getline(ss, str, '?'))
        {
           TCHAR* pItem = new TCHAR[MAX_PATH];
           lstrcpy(pItem, (TCHAR*)str.c_str());
           if(!PostMessage(hwnd, WM_USERDEFINED, (WPARAM)pItem, 0))
                 delete[] pItem;
           //cout << "item  "  << pItem << endl;
        }
    ....
    // receiver
        case WM_USERDEFINED:
             TCHAR* pItem = (TCHAR*)wParam ;       
             SendMessage(hListBox,  LB_ADDSTRING, (WPARAM)0, (LPARAM)pItem);
             delete[] pItem;
            return 0;
    Victor Nijegorodov

  7. #7
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: PostMessage

    Do not SEND messages from a thread to your main UI thread. This could potentially end up being a deadlock, but even if it isn't, it will effectively suspend the worker thread until the main thread has processed and returned from the message. This is why you should use PostMessage()

    but in the case of post as here. you can't send a pointer and expect this to work "just like that". In this case, the message may not get processed until after you called the delete. The main thread will then end up accessing memory which is no longer valid, which could result in a crash, or the main thread processing incorrect data.

    If you need to send a structure of data:
    - either use a global interface structure shared by both threads. In this case, you'll need to synchronise access to this structure.
    - allocate a structure, post the pointer, and delete the memory in the receiving thread.
    - there's hybrid solutions of the above such as managing a ringbuffer (or some other type of structure depending on needs) that might have advantages over the above 2.

  8. #8
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: PostMessage

    I mention using SendMessage only as a test.

  9. #9
    Join Date
    Dec 2007
    Location
    France
    Posts
    329

    Re: PostMessage

    Thanks for pointing this out.

    I changed my code accordingly but since I cannot declare the pointer inside 'case WM_USERDEFINED:' I have to declare it outside of the 'switch (Msg)' and it's crashing that way.

    Code:
    LRESULT CALLBACK WndProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
    {
    TCHAR* pItem;
      
        switch (Msg)
        {
        case WM_CREATE:
     ...
    
       case WM_USERDEFINED:
             pItem = (TCHAR*)wParam ;
             SendMessage(hListBox,  LB_ADDSTRING, (WPARAM)0, (LPARAM)pItem);
             delete[] pItem;
    
            return 0;
    
    ...
    Last edited by MasterDucky; June 30th, 2014 at 02:41 PM.

  10. #10
    Join Date
    May 2007
    Posts
    811

    Re: PostMessage

    Yes, you can add variable inside case statement, add braces there to create local scope.

  11. #11
    Join Date
    Dec 2007
    Location
    France
    Posts
    329

    Re: PostMessage

    Thanks, I did, it compiles but crashing.

    This is what you meant?
    Code:
        case WM_USERDEFINED:
        {
            TCHAR * pItem = (TCHAR*)wParam;
            SendMessage(hListBox, LB_ADDSTRING, (WPARAM)0, (LPARAM)pItem);
            delete[] pItem;
        }
    It's working this way but Im not deleting the pointer:

    Code:
        case WM_USERDEFINED:
        {
           
            SendMessage(hListBox, LB_ADDSTRING, (WPARAM)0, (LPARAM)(TCHAR*)wParam);
         
        }
    Last edited by MasterDucky; July 1st, 2014 at 01:45 AM.

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

    Re: PostMessage

    Show your actual thread procedure code.
    Victor Nijegorodov

  13. #13
    Join Date
    Dec 2007
    Location
    France
    Posts
    329

    Re: PostMessage

    Quote Originally Posted by VictorN View Post
    Show your actual thread procedure code.
    Code:
     
        string str;
        stringstream ss(s);
    
        while (getline(ss, str, '?'))
        {
            TCHAR* pItem = new TCHAR[MAX_PATH];
            lstrcpy(pItem, (TCHAR*)str.c_str());
            if(!PostMessage(hwnd, WM_USERDEFINED, (WPARAM)pItem, 0))
             delete pItem;
        }
    Last edited by MasterDucky; July 1st, 2014 at 06:48 AM.

  14. #14
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: PostMessage

    Quote Originally Posted by MasterDucky View Post
    Code:
     
        string str;
        stringstream ss(s);
    
        while (getline(ss, str, '?'))
        {
            TCHAR* pItem = new TCHAR[MAX_PATH];
            lstrcpy(pItem, (TCHAR*)str.c_str());
            if(!PostMessage(hwnd, WM_USERDEFINED, (WPARAM)pItem, 0))
             delete pItem;
        }
    should be a delete [] pItem; but that don't really make a difference for this code.

  15. #15
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: PostMessage

    Thanks, I did, it compiles but crashing.
    Have you used the debugger to trace through the code? On what line does the debugger determine it is 'crashing'? What are the contents of the variables when the crash occurs?When stepping through the code when does the value of variables differ from the expected values?
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Page 1 of 2 12 LastLast

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