Re: Batch file and MFC (Properly Terminating Application)
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Fri, 02 Feb 2007 23:44:00 -0500
On 2 Feb 2007 11:22:28 -0800, "one-trick-pony" <worldofpain.aamir@xxxxxxxxx> wrote:
Thanks Joseph. I really liked your line by line breakdown of dummy****
code. Fact is, I never worked with MFC before and I wanted a response
like that to tell me what I am doing wrong. I was expecting some
professional to come along and declare my code nightmare. I already
have your website marked as favorites in my internet explorer. I went
there today to read up on CString. There is TONS AND TONS AND TONS of
information on MFC. I can read but I can't remember everything. Best
solution is to actually write nightmarish code and have someone look
at it and then make corrections-that is, practice, practice and
practice.
Well, check out my essay on CString as well.
When Robert Heinlein was asked what it took to make a great writer, he said "write. lots."
Code walkthroughs, though sometimes hard on the ego, are one of the best techniques for
refining code. I do this several times a year on my perfect code and usually find about
six bugs on each first walkthrough. Sometimes they are serious bugs. Embarrassing. But
I don't make those mistakes a second time.
****
****
In my code, I allow user to be able to exit code at two different
times(inside AutoRun function). I have a function called DoEvents
that processes user input(messages) such as clicking of Exit Button.
There should be no need to have a DoEvents or any need to process an exit button message
in the thread doing the AutoRun function. It should only ask if the button was clicked by
examining the boolean variable set by the button
*****
I give user a few seconds for each input via a while loop where I call****
Sleep function with 100msec each time through loop and loop runs for
about 1000 times which is roughly 10 seconds window for user to click
on exit. Sleep fucntion is within that loop as well as DoEvents
function.
Sleep() should be considered ALWAYS a design error in the main GUI thread, except in some
remarkably rare and exotic situations. Sleep() in a secondary thread is ALWAYS a design
error unless it is a specific requirement of the thread, e.g., sleep for n ms then check
an external device. Tossing Sleep() calls around to make something work means that the
design is deeply and fundamentally flawed. In fact, it is EXACTLY one of the techniques I
use to discover broken multithread design: if there is a Sleep() it is broken. And I've
never been wrong yet.
So you are still miles from robust and reliable code.
If you need to prompt for user input, life gets a bit more complex. Essentially, at that
point you have to postmessage a request to the main GUI thread to obtain data, and then
wait for the data to arrive. I would do this by doing the postmessage, then blocking on
an I/O Completion Port. Note that at no time is there any need to do a DoEvents anywhere
for any reason.
When the message is received by the main thread, it puts up an input request. When the
operation completes, the input string is retrieved, placed into the I/O Completion Port,
and that's the end of the operation from the main GUI thread.
void CMyClass::DoThingN()
{
PostMessage(UWM_QUERY_INPUT, IDS_QUESTION);
DWORD bytes;
UINT_PTR key;
LPOVERLAPPED ovl;
while(!GetQueuedCompletionStatus(port, &bytes, &key, timeout))
{ /* error */
see if it was timeout or something else
deal with timeout if user fails to respond
if timeout also check for abort
if other error throw abort
check key: if IDOK, proceed, if IDCANCEL abort
if user taking too long, you might choose to abort
} /* error */
CString * s = (CString *)ovl;
... use value returned
delete s;
}
LRESULT OnQueryInput(WPARAM wParam, LPARAM)
{
CMyInputDialog dlg;
dlg.prompt.LoadString((UINT)wParam);
if(dlg.DoModal() == IDOK)
{ /* pass input back */
CString * s = new CString(dlg.result);
PostQueuedCompletionStatus(port, 0, IDOK, (LPOVERLAPPED)s);
} /* pass input back */
else
{ /* abort */
PostQueuedCompletionStatus(port, 0, IDCANCEL, NULL);
} /* abort */
return 0;
}
Note: I've never tried to pass NULL as the LPOVERLAPPED parameter; this may actually be
rejected by the system; if it is, pass some useless dummy address, since it would never be
looked at if IDCANCEL is the completion key.
Note that there is no need to use anything like DoEvents, PeekMessage, or anything else
that serves no useful purpose.
****
****
I feel like there is LOTS of room for improvment. I have****
barely begun to scratch the surface. This approach works but do I
think it is professional engineering? Probably not. Thats why I am
here-to understand and learn professional software engineering.
One of the main challenge is amount of information I have to
understand to become good programmer. Please, often visit this post
because, I will be asking more questions. Now I am off to your
website reading up on world of threads! I thank you for your effort
of breaking down my code line by line-a true teacher! :p Currently, I
do utilize functions inside AutoRun that branch off other processes
via CreateProcess. I also used WaitForSingleObject function to keep
my program in syncrohnization. This is my first time using these
functions. I am still in learning process and working toward becoming
a better coder.
Key here is to see all the pieces and figure out how to assemble them into systems that do
useful things. One of the most valuable mechanisms for doing this is reading code others
have written. After a while, you also begin to figure out which programmers have good
style and which have bad style. You can learn a lot even from bad style.
joe
****
Joseph M. Newcomer [MVP]
Thanks for help.
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- Follow-Ups:
- Re: Batch file and MFC (Properly Terminating Application)
- From: one-trick-pony
- Re: Batch file and MFC (Properly Terminating Application)
- References:
- Batch file and MFC (Properly Terminating Application)
- From: one-trick-pony
- Re: Batch file and MFC (Properly Terminating Application)
- From: Joseph M . Newcomer
- Re: Batch file and MFC (Properly Terminating Application)
- From: one-trick-pony
- Batch file and MFC (Properly Terminating Application)
- Prev by Date: use ostream to output TCHAR
- Next by Date: Re: CString::Right , My mistake or bug? please hlep me
- Previous by thread: Re: Batch file and MFC (Properly Terminating Application)
- Next by thread: Re: Batch file and MFC (Properly Terminating Application)
- Index(es):
Loading