Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Can't get progress control working to save my life!

96 views
Skip to first unread message

Alex Horvath

unread,
Jan 14, 2002, 12:08:18 AM1/14/02
to
Here's my code:

CProgressBar ProgressBar; //parent dialog for progress bar
ProgressBar.Create(IDD_PROGRESS,NULL); //create the parent dialog modeless
CRect rect;
CWnd* pView = CAstroCharts4View::GetView();
CWnd* pWnd = ProgressBar.GetDlgItem(IDC_PROGRESS1); //get pointer to parent
of progress bar
pWnd->GetWindowRect(&rect); //and get the rect of the parent dialog
CProgressCtrl ProgressCtrl;
ProgressCtrl.Create(WS_VISIBLE | WS_CHILD |
PBS_SMOOTH,rect,&ProgressBar,IDC_PROGRESS1);


for ......
{
ProgressCtrl.StepIt();
}

I know I'm close because if I change &ProgressBar in the create function to
pView, I see the progress bar update as it should but it is not attached to
the ProgressBar dialog box (it is attached to main window). When the code is
as above the dialog box shows up but the progress bar is not visible.
CAstroCharts4View::GetView() returns a pointer to the current view. I looked
very carefully at the CmnCtrl2 example and the only difference I could find
is that they used a "picture" object instead of a "progress" object in the
dialog editor. Also, I'm not sure if I should create the parent dialog as
modeless but if I use DoModal() instead of Create() the code seems to hang
at DoModal().

Thanks for the help


Scott McPhillips

unread,
Jan 14, 2002, 10:22:58 AM1/14/02
to
Alex Horvath wrote:
>
> Here's my code:
>
> CProgressBar ProgressBar; //parent dialog for progress bar
> ProgressBar.Create(IDD_PROGRESS,NULL); //create the parent dialog modeless
> CRect rect;
> CWnd* pView = CAstroCharts4View::GetView();
> CWnd* pWnd = ProgressBar.GetDlgItem(IDC_PROGRESS1); //get pointer to parent
> of progress bar
> pWnd->GetWindowRect(&rect); //and get the rect of the parent dialog
> CProgressCtrl ProgressCtrl;
> ProgressCtrl.Create(WS_VISIBLE | WS_CHILD |
> PBS_SMOOTH,rect,&ProgressBar,IDC_PROGRESS1);
>
> for ......
> {
> ProgressCtrl.StepIt();
> }

You're confused :)
GetDlgItem(IDC_PROGRESS1) gets a pointer to the progress control. That
progress control is created for you automatically when the dialog is
created. Then you are dynamically creating what appears to be a second
progress control.

If you want a modal dialog instead of modeless then you must manipulate
the progress control inside the dialog class. GetDlgItem(IDC_PROGRESS1)
can only work after the control has been automatically created, which
happens inside DoModal.

--
Scott McPhillips [VC++ MVP]

Joseph M. Newcomer

unread,
Jan 14, 2002, 7:16:09 PM1/14/02
to
The problem is that you are creating the progress bar. Pretty much all the other problems
stem from this unnecessary step. The best approach is to create the progress bar in the
dialog editor, which is what you also have appeared to have done, and make it invisible
until you need it.

The problem with the creation you have done is that as soon as the variable ProgressBar
goes out of scope, the window is destroyed.

Instead, create a class member variable to represent the progress bar IDC_PROGRESS1 (read
my essay on my MVP Tips site, "Avoiding GetDlgItem", for details on how to do this).

As far as I can tell you have several different attempts, completely unrelated, to create
or manipulate the progress bar, all in the same code. None of them are appropriate. Note
that using a parent window of NULL for a modeless dialog is usually inappropriate as well;
you should really have it attached to some window of yours, such as the view that is doing
the work. Then you must actually create it via New and store a pointer to it in the class,
because as soon as it goes out of scope it is all over. In addition, you are doing a
computation in loop which does not allow the message pump to execute, which has a tendency
to inhibit the refresh of the progress bar. Then, you are using GetDlgItem to get a
pointer to the window, which seems gratuitous; if you want a progress bar, send a message
to the dialog to update its contents, don't extract a pointer from it (you can't really
save the pointer anyway, because it is temporary).

To create the dialog, do
ProgressDialog = new CProgessBar;
ProgressDialog->Create(CProgressBar::IDD, this);

In the CProgressDialog class, add a user-defined message handler and define a message,
e.g.,
#define UPM_STEPIT (WM_APP + 12) // 12 is a random number

To step the progress bar, do
ProfessDialog->SendMessage(UPM_STEPIT);

In the progress bar class, add a message handler, declare it in the protected area
afx_msg LRESULT OnStept(WPARAM, LPARAM);

Add a handler to the MESSAGE_MAP
ON_MESSAGE(UPM_STEPIT, OnStepit)

and add the handler function
LRESULT CProgressBar::OnStepit(WPARAM, LPARAM)
{
c_Progress.StepIt();
return 0;
}

This is the clean way to do it. No reaching into the dialog, no manipulating its innards.
If the window doesn't update properly, add c_Progress.UpdateWindow() to the OnStepit
handler.

Add a PostNcDestroy handler and have it do
delete this;

joe

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www3.pgh.net/~newcomer
MVP Tips: http://www3.pgh.net/~newcomer/mvp_tips.htm

0 new messages