• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 694
  • Last Modified:

Where to place my CWnd::OnTimer(...) call ?

Hi experts,

I am working on a SDI application, that on startup builds a table of about 1000 values.
Since those calculations can take a few seconds, I want a modal dialog box to pop up,
showing a progressbar as the calculations advange, and disappear when all is done.
I use a timer to proces each value in the table. My problem is, that I do not know
where to place my CWnd::SetTimer(...) call. (Fires at roughly 55 millisecond intervals).
When I call it from the CDialog::OnInitDialog() my dialog box does not appear always,
especially on slower machines. Here the dialog´s WM_PAINT message seems never to get
Could someone tell me how to solve this one. Any help would be greatly appreciated.
1 Solution
I would say place it in the constructor to the class you expect to process the WM_TIMER messages.  Then, in ClassWizard, add a handler for the WM_TIMER message.
   Oh, using a value under 100 milliseconds for how often you want to receive WM_TIMER messages "appears" to default to a value of 100 (atleast on Windows 95).  Somehow the timeslice value is relevant but I don't know how.
Vinayak KumbarSr Program ManagerCommented:

R U trying to process one record at a time, whenever a Timer message called?. If yes, what I suggest is, Display a modal dialog box, put the progress bar in it. And InOnitDialog(), Initialise the progress bar, set the range to it, and set the timer using this->SetTimer(1, 10, NULL);. Then map the WM_TIMER message and do the following

while(records are there)
process the record.
update the progress bar.
continue for the next record.

That will the required job.

Hope this helps.
Hi bs161900,

Try a ShowWindow( SW_SHOW ) in OnInitDialog before the SetTimer() function (and after the CDialog::OnInitDialog()) to force the dialog being displayed ...

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

This is how I did it, without WM_TIMER.

In your CProgressDialog create a function that looks something like this:

void CProgressDialog::SetProgress (int nCurrentPost, int nTotalPosts)
float f;

f = (nCurrentPost / (float)nTotalPosts) * 100;
f = f + (float)0.5;
int nProgress = (int)f;

m_ctrlProgress.SetPos (nProgress);

CString str;
str.Format(_T("Importing post %d of %d"), nCurrentPost, nTotalPosts);

then in your class where you start to build your table, first create a modeless dialog:
CProgressDialog dlg;

then call the function SetProgress:

for (int i = 0; i < .......
    dlg.SetProgress (i, nNumberPosts);

When you are done destroy the dialog:
dlg.DestroyWindow ();

That worked for me, perhaps not what you were after....

Good luck....

I wrote a program that does the very same thing (although, it doesn't calculate 1000 values).

What I did was add the Splash-screen component (Project, Add to project, Components and controls)

The code snippet here is inserted into the splash class.  It scrolls a progress bar (CProgressCtrl m_Prog) and displays text from a string table.  The strings in the table are numbered sequentially from IDS_ONE (=81).  In this example, there are ten strings.  

This code was used to initialize variables that took 100 iterations to calculate (the ten strings keep the user entertained).

Hope this helps.  Good luck!

void CSplash::OnTimer(UINT nIDEvent)
      static int iCount = IDS_ONE - 1;
      static int iPos = 1;
      CString strTemp;

      // Increment string index

      // ** If we've run through the 10 strings,
        //    keep the last one up.
      if( iCount > ( IDS_ONE + 9 ) )
            iPos = 10;
            strTemp.LoadString( iCount );
            m_Bog = strTemp;

      // ** Update the progress bar position
      m_Prog.OffsetPos( iPos );

      //** Do all calculations here;
      UpdateData( FALSE );

      // ** When we get to 100, we're done.
      if( m_Prog.GetPos() == 100 )
bs161900Author Commented:
I learned a lot from this little piece of code. It pushed me in the right direction.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now