Click to See Complete Forum and Search --> : Button Runs Twice


geoffba
October 1st, 2003, 01:04 PM
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


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;

hankdane
October 1st, 2003, 01:29 PM
Geoff,

Your SendMessage() doesn't look right. The syntax of WM_COMMAND is:

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:


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:


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:


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.

pukys
October 1st, 2003, 01:34 PM
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

geoffba
October 1st, 2003, 01:39 PM
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

geoffba
October 1st, 2003, 01:57 PM
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.


PostMessage(hwndMain,WM_COMMAND,MAKELONG((WORD)508,(WORD)508),(LPARAM)NULL);


please let me know if I am or not thanks

-geoff

hankdane
October 1st, 2003, 02:55 PM
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]

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:


PostMessage(hwndMain,WM_COMMAND,(WPARAM)MAKELONG(508,BN_CLICKED),(LPARAM)hwndButton);

geoffba
October 1st, 2003, 03:39 PM
Thanks for all your help (both of you). It is now working correctly.

-geoff