|
MFC, VS6.0, C++
From within a thread I have used SendMessage() to flag an error and display an acknowledge dialog using AfxMessageBox, it's a simple 'An error has occurred press ok' kind of message and then it returns with return 0 eg:-
LRESULT CMainFrame::OnError(WPARAM wParam, LPARAM lParam)
{
switch (wParam)
{
case 1:
AfxMessageBox("Error 1 - Press OK");
break;
case 2:
AfxMessageBox("Error 2 - Press OK");
break;
}
return 0;
}
The problem is that the calling thread is 'hanging' after I click ok in the dialog box even though the only line after that is return 0. If I use PostMessage instead of SendMessage then the problem doesn't occur.
As I understand it SendMessage will wait until the message has been processed before continuing where PostMessage simply pops the message into the message queue and returns. I'm not quite sure what is going on here, obviously in the first case the message is not being flagged as completed so SendMessage never finishes but why? Any Ideas?
|
|
|
|
|
I suppose you hit this [^]:
Message Deadlocks
A thread that calls the SendMessage function to send a message to another thread cannot continue executing until the window procedure that receives the message returns. If the receiving thread yields control while processing the message, the sending thread cannot continue executing, because it is waiting for SendMessage to return. If the receiving thread is attached to the same queue as the sender, it can cause an application deadlock to occur. (Note that journal hooks attach threads to the same queue.)
Note that the receiving thread need not yield control explicitly; calling any of the following functions can cause a thread to yield control implicitly.
* DialogBox
* DialogBoxIndirect
* DialogBoxIndirectParam
* DialogBoxParam
* GetMessage
* MessageBox
* PeekMessage
* SendMessage
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
So its probably AfxMessageBox() thats causing the problem then? I can check that easily enough by removing them temporarily I suppose...
|
|
|
|
|
Caslen wrote: So its probably AfxMessageBox() thats causing the problem then?
I suppose.
Caslen wrote: I can check that easily enough by removing them temporarily I suppose...
Let's try...
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Funnily enough it works ok with the MessageBoxes linked out!
I've added ReplyMessage as follows:-
LRESULT CMainFrame::OnError(WPARAM wParam, LPARAM lParam)
{
if (InSendMessage())
ReplyMessage(TRUE);
switch (wParam)
{
case 1:
AfxMessageBox("Error 1 - Press OK");
break;
case 2:
AfxMessageBox("Error 2 - Press OK");
break;
}
return 0;
}
and it works just fine, whats the difference between this and just using PostMessage though? Is it because it waits until the message is starting to be processed before replying and allowing the calling thread continue, where PostMessage just posts the message before allowing the calling thread to continue even though its possible that the message may not be processed?
|
|
|
|
|
When a SendMessage is being processed, the message loop of the receiving window (or thread) is still going and can process messages posted to it via PostMessages. Be aware that the notion that a PostMessage may not be processed is often misstated. The issue is whether the input queue on the receiving window is filled or not. This is a rare occurrence and indicates far bigger problems with your code if it is.
Do note that there is a SendMessageTimeout() function. I have never used it.
|
|
|
|
|
The message is definitely being processed as the message box is displayed correctly it's just not allowing/instructing/signalling the sending process that it has finished. For whatever reason the AfxMessageBox call is causing this to happen. I looked at SendMessageTimeout() too but I was more concerned as to why the sending thread wasn't continuing - SendMessageTimeout() would have been a workaround but I don't think I would have been better off than with PostMessage()
|
|
|
|
|
I prefer PostMessage() for something like this. The rule of thumb for SendMessage() is to do nothing that won't return in a few milliseconds AND to do no window operations in the call. As you've learned, don't open a message box or dialog box either.
|
|
|
|
|
Hi
How to get folder list on a root folder?
Thanks
Failure is Success If we learn from it!!
|
|
|
|
|
_findfirst() /_findnext()
FindFirstFile() /FindNextFile()
CFileFind
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
See here[^].
MVP 2010 - are they mad?
|
|
|
|
|
You could use the FindFirstFile() and FindNextFile() functions, then check for the FILE_ATTRIBUTE_DIRECTORY flag in your WIN32_FIND_DATA variable's dwFileAttributes member.
The MSDN page is here[^]
|
|
|
|
|
Hello,
Can any body tell what is data directory in PE file format ? and what is the main purpose of these data directories to maintain in PE format.?
Regards
Muhammad Usman Khalil
|
|
|
|
|
glitteringsound wrote: Can any body tell what is data directory in PE file format ?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
|
|
|
|
|
See here[^].
MVP 2010 - are they mad?
|
|
|
|
|
#include <iostream>
using namespace std;
class Element{
public:
int value;
Element *next;
Element() : value(0), next(NULL) {}
Element(int v) : value(v), next(NULL) {}
Element(int v,Element *n) : value(v), next(n) {}
};
class Stack{
private:
int length;
Element head;
public:
Stack() : head(), length(0) {}
void clear();
void traversal() const;
void push(int value);
int pop();
};
void Stack::clear(){
head = Element();
}
void Stack::traversal() const{
if (length == 0)
cout << "The stack is empty" << endl;
else{
Element e = head;
while(true){
cout << e.value << ' ';
if (e.next != NULL)
e = *e.next;
else
break;
}
}
}
void Stack::push(int value){
if (length == 0)
head = Element(value);
else
head = Element(value,&head);
length++;
}
int Stack::pop(){
return 0;
}
int main(int argc, string args[]){
Stack s;
cout << endl;
for (int i = 0; i < 10; i++)
s.push(i);
s.traversal();
cout << endl;
return 0;
}
well, i m trying to implement stack structure with C++. i got a problem with this code. the traversal function runs forever, and it prints out all '9'. can any1 help with this problem ?
|
|
|
|
|
hung2h wrote: head = Element(value,&head);
The problem when you do this is that the object head after the assignment has the same address as before the assignment (head has a specific address and if you assign a new element to this variable, the address will still be the same). So, it means that the head is pointing to itself for the next element, thus you end up with an infinite loop.
You should really allocate all the elements dynamically (using the new operator). Of course, you should also delete them when you pop them from the stack.
|
|
|
|
|
many thanks to Cédric Moonen, i see it now .
|
|
|
|
|
hung2h wrote: well, i m trying to implement stack structure with C++.
YOu may also use the std::stack , see [^].
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Isn't that cheating for homework?
You measure democracy by the freedom it gives its dissidents, not the freedom it gives its assimilated conformists.
|
|
|
|
|
Nah, it is 'smart usage of available technology'
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
|
The way I read this, you want to #include "sc.h" in frst.h and #include "th.h" in sc.h, but not #include "frst.h" in th.h? WQell, surely you just need to put the appropriate #include lines in frst.h and sc.h as below?
Put this line at the start of frst.h
#include "sc.h"
Put this line at the start of sc.h
#include "th.h"
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
MVP for 2010 - who'd'a thunk it!
|
|
|
|
|
More information might be useful, but I'd suggest reading about Forward Declarations[^] as a good place to start.
Steve
|
|
|
|
|
Right, I'll do it with forward declaration. Thanks for answers.
|
|
|
|