Re: SetTimer not working
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Sat, 09 May 2009 21:17:25 -0400
See below...
On Sat, 9 May 2009 16:34:45 -0400, "Jeova Almeida" <jeovaalmeida@xxxxxxxxx> wrote:
Hello,****
I have a welcome dialog which registers my users to a web server just after
the application is installed. This registragion may take from 5 to 30
seconds:
void CWelcomeDlg::OnBnClickedOK()
{
DoLengthyProcessing();
this->EndDialog(1);
What does "1" mean? EndDialog usually takes some useful value, like IDOK.
****
*****
}
As I said, the processing takes long to finish, so I wanted to show a
feedback to my users that the program hasn't stopped working. I inserted a
Static control and implemented a simple animation:
If you have a lengthy computation it is generally a Bad Idea to do this processing in the
main GUI thread. Note that OnTimer only happens when the message pump retrieves a
message, so if you are off doing something lengthy, you are not processing messages and
there will be no notification. If you do it in a secondary thread, you can continue to
get all messages and terminate the thread according to one or more of several protocols.
You can assume that a design that does lengthy processing in the main GUI thread should
have its design carefully reconsidered. In your case, it is not a viable solution.
****
****
void CWelcomeDlg::OnTimer(UINT_PTR nIDEvent)
{
CStatic* pLabel = (CStatic*)GetDlgItem(IDC_LBL_PROCESSING);
Why in the world would you use GetDlgItem? We aren't programming 16-bit WIndows and we
aren't programming in the raw API. Create a control variable and bind to that with the
Add Variable option. Using GetDlgItem almost always is a design error.
****
****
CString strVal;
pLabel->GetWindowText(strVal);
if (strVal == L"/")
pLabel->SetWindowTextW(L"\\");
else if (strVal == L"\\")
pLabel->SetWindowTextW(L"/");
Actually, there are horizontal modes. So the correct solution is to have a counter
running modulo 4:
state = (state + 1) % 4;
switch(state)
{
case 0:
strVal = _T("|");
break;
case 1:
strval = _T("/");
break;
case 2:
strval = _T("-");
break;
case 3:
strval = _T("\\");
break;
}
Label.SetWindowText(strVal);
Although I tend to do this using a sequence of 16 icons in a circular format that make a
nicer effect, and I usually display it in a static control. But to do this, you cannot
have the message pump stop. It is just a bad idea to do a lengthy computation in the main
GUI thread.
*****
****
CDialog::OnTimer(nIDEvent);
}
and changed the previous click event shown before to start the timer:
void CWelcomeDlg::OnBnClickedOK()
{
m_nTimer = SetTimer(1, 1000, NULL);
DoLengthyProcessing();
Create a thread:
AfxBeginThread(LengthyProcessing, this);
See my essays on worker threads on my MVP Tips site
****
****
KillTimer(m_nTimer);
this->EndDialog(1);
}
The problem is the timer isn't working while the lengthy procesing is
running. If I put the SetTimer() and KillTimer() inside the click event of
two command buttons, it works fine.
Yes, and that is exactly what is supposed to happen.
****
****
The processing connects with a Windows Service via named pipe, and the
Windows Service makes the needed registration via web.
Then you could use asynchronous I/O on the named pipe and handle the completion in the
thread associated with an I/O Completion Port
****
****
Why the timer isn't working? How can I do the same if not with timer?
It isn't working because as you designed your code, it isn't supposed to work.
****
****
I tried moving the lengthy processing into a thread and kept the timer in
the main thread, but it not worked as well.
Then there is something else wrong. You would have to show the code you used. If, for
example, a WaitForSingleObject appeared that was waiting on the thread handle, you created
a complex way to do a subroutine call in the main thread, and the exact same problem
remains.
Start a thread or an asynchronous I/O operation and return to the main message pump. You
will need to disable certain controls until the thread or I/O operation completes, but
that's trivial stuff. Key is to never, ever try to force an asynchronous thread to
exhibit synchronous behavior.
joe
****
Joseph M. Newcomer [MVP]
Please help.
Jeova
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- Follow-Ups:
- Re: SetTimer not working
- From: Jeova Almeida
- Re: SetTimer not working
- References:
- SetTimer not working
- From: Jeova Almeida
- SetTimer not working
- Prev by Date: Re: How to setup self-contained ToolTip coverage in CEdit control
- Next by Date: Re: error RC2104: undefined keyword or keyname TBS_NOTIFYBEFOREMOV
- Previous by thread: Re: SetTimer not working
- Next by thread: Re: SetTimer not working
- Index(es):
Relevant Pages
|