CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Jul 2003
    Posts
    35

    Button Runs Twice

    I am trying to make a push button control call itself a second time by using the SendMessage function to add the second button press to the que. However this does not seem to be occuring. The reason I need to do this is because the first time the button is pressed the function initializes a routine where a second thread analyzes some data. If the data is found it sets a bit. But in order for th second thread to process the data the main thread has to finish processing the message it is currently on (ie the first button press). So if I call a second button press to occur after the first one it should detect the bit change. Does anyone know of a method that I could get this to work, or if you have a better implementation you could reccomend I am all ears.

    Thanks
    -geoff

    Code:
     
                    case 508:
                        switch(setup)
                        {
                            case 0:
                                FindSearch=FindInBuffer("]#",2);
                                if(FindSearch==1)
                                {
                                    MessageBox(NULL,"Prompt Check","Error",MB_OK|MB_ICONEXCLAMATION);    
                                }     
                                setup=1;  
                            break;
                            case 1:
                                FindInBuffer("]#",1);
                                Command(" ",hwnd);
                                SendMessage(hwnd,WM_COMMAND,(WPARAM)NULL,(LPARAM)508); 
                            break;
                        }
                    break;

  2. #2
    Join Date
    Feb 2003
    Location
    California
    Posts
    334
    Geoff,

    Your SendMessage() doesn't look right. The syntax of WM_COMMAND is:
    Code:
    WM_COMMAND 
    wNotifyCode = HIWORD(wParam); // notification code 
    wID = LOWORD(wParam);         // item, control, or accelerator identifier 
    hwndCtl = (HWND) lParam;      // handle of control
    In other circumstances, you can use the MAKELONG macro to put wNotifyCode and wID into wParam. In your case, there is no need to do this, because you already have a perfectly fine wParam:

    Code:
    case 508:
                        switch(setup)
                        {
                            case 0:
                                FindSearch=FindInBuffer("]#",2);
                                if(FindSearch==1)
                                {
                                    MessageBox(NULL,"Prompt Check","Error",MB_OK|MB_ICONEXCLAMATION);    
                                }     
                                setup=1;  
                            break;
                            case 1:
                                FindInBuffer("]#",1);
                                Command(" ",hwnd);
                                 SendMessage(hwnd,WM_COMMAND,wParam,lParam); 
                            break;
                        }
                    break;
    I don't quite follow the intent though. Since a SendMessage() within the same thread is semantically identical to calling the window function directly, your code effectively becomes:

    Code:
    case 508:
                        switch(setup)
                        {
                            case 0:
                                FindSearch=FindInBuffer("]#",2);
                                if(FindSearch==1)
                                {
                                    MessageBox(NULL,"Prompt Check","Error",MB_OK|MB_ICONEXCLAMATION);    
                                }     
                                setup=1;  
                            break;
                            case 1:
                                FindInBuffer("]#",1);
                                Command(" ",hwnd);
                                 WndProc(hwnd,WM_COMMAND,wParam,lParam); 
                            break;
                        }
                    break;
    (This is assuming your window procedure is called "WndProc.")

    But then, this is identical to:

    Code:
    case 508:
                   FindSearch=FindInBuffer("]#",2);
                   if(FindSearch==1)
                   {
                       MessageBox(NULL,"Prompt Check","Error",MB_OK|MB_ICONEXCLAMATION);    
                   }     
                   FindInBuffer("]#",1);
                   Command(" ",hwnd);
                   break;
    In summary, it's unclear why the two-step approach is even necessary.
    Henri Hein
    Principal Engineer, Propel
    Do not credit Propel with my views or opinions.

  3. #3
    Join Date
    Sep 2003
    Posts
    14
    SendMessage should not call itself while processing a message, this can lead to a classical deadlock-situation:
    When a procedure calls a itself without a proper end-condition, it creates a lock-up and ends in a stack-overflow.
    If you want to work with threads, think of the posibility of race-conditions and *always* provide a synchronization between the threads, or you'll end up in a mess.
    Aside from this is a manipulation of the own message-queue no good idea, *or* use PostMessage instead. SendMessage blocks the first thread until the message is completely processed. PostMessage puts the message at the end of the queue and returns immediately. I think, this would be a more clean approach, because you don't block threads and prevent an out-of-order processing of messages.
    Or think of solving this problem without using threads at all.

    regards,
    Fra "multi-threading is the art of shooting yourself in both legs at the same time" nk

  4. #4
    Join Date
    Jul 2003
    Posts
    35

    sortof

    So I guess I am doing the implementation in the way because I do not know exactly how else to do it. Let me try to explain:

    I am running the main program and a sub thread. Th subthread is putting all the data into a buffer, and a rich edit control in the main thread. When a specific button control is pressed the main control needs to setup the check sequence of characters so the second thread can compare to. Once the sequence is detected a bit is set to tell the main thread that it found the sequence. But if I check that bit from within the first message process routine it never detects it, (the second thread is waiting for the first one to finish the message it is processing at the moment before it begins it analysis). If I use the code the way I originally posted it I can press the button twice and the detection is made. So I thought the easiest way would be to continue in this regard.

    Would there be a beter method

    Also I will try to implement postmessage now and see what happens.

    -geoff

  5. #5
    Join Date
    Jul 2003
    Posts
    35

    Got it now

    Ok so I thought about what you are both saying, in regards to the odd behavior that would occur with the Message process calling itself, so I decided to move the postmessage to the second thread. This seems to work great now as the second thread was already detecting the change so when it does now it simply tells the main thread that it found the change and go ahead with the procesing.

    one other question, in order to implement this I had to set up a MAKELONG macro, it was mentioned previously so I looked it up. But I do not know if I am using it correctly.

    Code:
    PostMessage(hwndMain,WM_COMMAND,MAKELONG((WORD)508,(WORD)508),(LPARAM)NULL);
    please let me know if I am or not thanks

    -geoff

  6. #6
    Join Date
    Feb 2003
    Location
    California
    Posts
    334

    Re: Got it now

    Originally posted by geoffba
    Ok so I thought about what you are both saying, in regards to the odd behavior that would occur with the Message process calling itself, so I decided to move the postmessage to the second thread.
    That makes a lot more sense.

    [/QUOTE]
    Code:
    PostMessage(hwndMain,WM_COMMAND,MAKELONG((WORD)508,(WORD)508),(LPARAM)NULL);
    please let me know if I am or not thanks

    [/QUOTE]

    That might work, but ideally you want something like this:

    Code:
    PostMessage(hwndMain,WM_COMMAND,(WPARAM)MAKELONG(508,BN_CLICKED),(LPARAM)hwndButton);
    Henri Hein
    Principal Engineer, Propel
    Do not credit Propel with my views or opinions.

  7. #7
    Join Date
    Jul 2003
    Posts
    35

    woohoo!!

    Thanks for all your help (both of you). It is now working correctly.

    -geoff

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