Re: How to display messages to the user during long processes!!
On Sep 24, 10:16 pm, Joseph M. Newcomer <newco...@flounder.com> wrote:
See below...
On Wed, 24 Sep 2008 08:58:58 -0700 (PDT), ragh...@gmail.com wrote:
On Sep 24, 7:42 am, Joseph M. Newcomer <newco...@flounder.com> wrote:
That's why I hook the node-builder event. It allows me to show actual =
progress. In my
PowerPoint indexer I am able to determine the total number of slides a=
nd that makes it
pretty easy, but at each #include I add a new progress bar and let it =
run. This is much
better than having a single progress bar whose contents you can never =
interpret, as it
makes N passes but you have no idea what 'progress' it is really showi=
ng.
I added the XML progress bar even though it takes under a minute to re=
ad and parse the
file because the customer really wanted a visble progress bar for any =
operation that took
longer than a few seconds (5 seconds was the nominal acceptable delay =
time without a
progress bar). In the library I use, the node-hook is called each time=
a node is started,
and when you call the reader, you give it an LPVOID userData type of p=
arameter. So I just
packaged the CFile* into the structure I passed in, which let me get t=
he file position
each time a node is built. A small data file can have perhaps 10,000 n=
odes, a large one
perhaps 250,000. In practice, we seemed to hover around 25,000-40,000 =
nodes, and this
exceeded the 5-second limit.
joe
On Tue, 23 Sep 2008 14:30:11 -0700, "Tom Serface" <tom.nos...@camaswoo=
d.com> wrote:
I think an approx. progress bar is better than none, but one that jum=
ps from
0 to 100 is pretty useless. The thing to strive for is periodic feedb=
ack if
the process is going to take a long time. I'm not sure why this is th=
e case
with an XML file unless it is huge. I can parse a 500K line XML file =
before
the progress bar even displays so I haven't found it useful to show t=
hat
kind of feedback.
Tom
"Joseph M. Newcomer" <newco...@flounder.com> wrote in message
news:rfhid494n5j1nf5rjsktvddtr8e515ljak@4ax.com...
I have an article inwww.codeguru.com(linkedto from my Web site) on h=
ow
to put progress
controls on a status bar.
In my PowerPoint Indexer, I have a dialog that does nested progress=
bars
as various
#includes are processed (I allow the user to start with one present=
ation
and pull in a
second one for a composite index). The whole point was to allow for=
early
termination.
Many parsing libraries have hooks for various events; the XML libra=
ries I
use all do.
That's where I just ask the current file position of the input file=
.. It
isn't quite
dead-on because it represents where the file pointer is, not where =
the
internal buffers
are, but it is a good enough approximation for a progress bar.
joe
Joseph M. Newcomer [MVP]
email: newco...@flounder.com
Web:http://www.flounder.com
MVP Tips:http://www.flounder.com/mvp_tips.htm-Hide quoted text -
- Show quoted text -
Hi all,
Thanks to all for the replies but i feel your solution is rather bit
complicated
My solution is simple but not fully implemented i need you guys help
In my code
First i call to start the message:
=
theApp.m_dlgMain-
PostMessage(WM_SHOWMSG,1,0);
****
As soon as I see something callling a method of the CWinApp class, I know=
I'm seeing a
very, very suspect design decision. Assume that you never HEARD of the=
CWinApp-derived
class EXCEPT in the implementation module for the CWinApp class, and that=
never, ever,
under any conditions imaginable will ever refer to the 'theApp' variable.=
In order to do
that, you need the header file for the CWinApp class included, and the fi=
rst thing you
should do in any sane design is delete that #include from your modules (M=
icrosoft LOVES to
put it in, but putting it in is always wrong)
NEVER use WM_ as a prefix for a user-defined message, ever. It makes f=
uture maintenance
difficult.
What are the meanings of 1 and 0? If WPARAM is a boolean, you would us=
e TRUE or FALSE; if
LPARAM is not used, you would not even mention it.
****
/*
=
lengthy process which takes
lot of time like connecting to device and .Xml parsing
*/
Then i want to e=
nd the message
_dlgMain-
PostMessage(WM_SHOWMSG,0,0);
****
Looks to me like these should have been
->PostMessage(UWM_SHOWMSG, TRUE);
and
->PostMessage(UWM_SHOWMSG, FALSE);
so why use 0 and 1 as parameters? Also, I would have passed the CWnd* =
into the thread,
not given it a hardwired member of the CWinApp-derived class.
****
IN the message Handler:
ON_MESSAGE(WM_SHOWMSG,DispMsg)
LRESULT CDlgMain::DispMsg(WPARAM wParam, LPARAM lParam)
{
****
If lParam is not used, the correct prototype is
LRESULT CDlgMain::DispMsg(WPARAM wParam, LPARAM)
otherwise you will get a warning about unused parameters
****
if(wParam==1)
****
If it is a boolean value, just say
if((BOOL)wParam)
and forget doing an ==. Actually, the BOOL cast is redundant, but =
doing things like ==1
and ==0 to convey boolean state is poor practice
****> {
=
/*start a message stating
"please wait... Loading in progress" without any controls*/
-->=
but i am not getting how to show
just a message with no controls.I tried creating a dialog box and
using domodal to display the message
=
but it has a caption which i
cannot remove and also i do not know how to close the dialog box
programmatically without pressing any cancel button or ok button.
****
Create the dialog box template without a caption, minimize, maximize, or =
system menu. I
tend to create them as modeless rather than modal, but if I were creating=
one modal I
would probably launch the thread from its OnInitDialog handler passing 't=
his' in as the
place to post the messages.
When the thread terminates, you would simply invoke the CDialog::OnOK met=
hod to terminate
a modal dialog box, or call DestroyWindow to terminate a modeless dialog =
box
This assumes your thread does a PostMessage that it has terminated, which=
is good
practice. You would also override the OnOK and OnCancel handlers to do=
nothing, and
remove the buttons, or you would override the OnOK handler to do nothing,=
but the OnCancel
handler would be something like
void CMyDIalog::OnOK()
{
//does NOTHING, empty body (except for this comment)
}
void CMyDialog::OnCancel()
{
...request thread shutdown
}
NOTE THAT THERE IS NO CDialog::OnCancel call issued by the OnCancel handl=
er. Then you
would do something like
LRESULT CMyDIalog::OnThreadTerminated(WPARAM wParam, LPARAM)
{
...thread terminated due to cancellation: wParam is TRUE
...thread terminatived because it ran to completion: wParam is FA=
LSE
BOOL ProcessingAborted = (BOOL)wParam;
if(ProcessingAborted)
CDialog::OnCancel();
else
CDialog::OnOK();
return 0;
}
Note that I roll this code into a more general method later in this discu=
ssion.
so a message or atleast a
dialogbox with no caption and displaying the message is just fine
}
else
{
/*Stop the message when wparam i=
s 0*/
the dialogbox or message should =
close without any button click by
****
See my code above. You would call CDialog::OnOK because it was a succe=
ssful termination.
Or you would pass in information saying whether it was a successful termi=
nation or a
cancellation, e.g.,
typedef enum {THREAD_STARTING, THREAD_FINISHED, THREAD_CANCELLED} ThreadS=
tate;
/************************************************************************=
**=AD*******************
* =
UWM_THREAD_STATE
* Inputs:
* WPARAM: (WPARAM)(ThreadState) the state of the thread
* LPARAM:
* THREAD_STARTING: (LPARAM)(CString*) The message to show
* Note: the r=
eceiver must delete this CString*
* THREAD_FINISHED: unused
* THREAD_CANCELLED: unused
* Result: LRESULT
* Logically void, 0, always
* Effect:
* THREAD_STARTING: shows the text in the dialog box
* THREAD_FINISHED: Closes the dialog with OK status
* THREAD_CANCELLED: Closes the dialog with cancelled status
*************************************************************************=
**=AD****************/
....define UWM_THREAD_STATE here, I would write
static const UINT UWM_THREAD_STATE = ::RegisterWindowMessage(_T("UWM_TH=
READ_STATE")
_T("{guid-here}"));
Note that if your definition of your message DOES NOT INCLUDE THE ABOVE D=
OCUMENTATION, YOU
NEED TO RETHINK HOW YOU PROGRAM! Every message is an interface, and ev=
ery interface must
be specified by writing coherent documentation.
Since I'm working on the premise here that you are using a modal dialog, =
I would do the
following:
void CMyWhatever::StartLongProcess()
{
CMyProgressDialog dlg;
dlg.parameters = ...set parameters to thread here...
switch(dlg.DoModal())
{ /* dlg */
case IDOK:
...deal with success
break;
case IDCANCEL:
... deal with cancellation
break;
default:
ASSERT(FALSE);
return;
} /* dlg */
}
BOOL CMyProgressDialog::OnInitDialog()
{
parameters.wnd = this; // CWnd * wnd; // Notification w=
indow
AfxBeginThread(threadfunc, ¶meters);
return TRUE;
}
LRESULT CmyProgressDialog::OnThreadState(WPARAM wParam, LPARAM lParam)
{
ThreadState state = (ThreadState)wParam;
switch(state)
{ /* state */
case THREAD_STARTING:
{
CString * s = (CString *)lParam;
c_Message.SetWindowText(*s);
delete s;
break;
}
case THREAD_FINISHED:
CDialog::OnOK();
break;
case THREAD_CANCELLED:
CDialog::OnCancel();
break;
default:
ASSERT(FALSE);
break;
} /* state */
return 0;
}
*****>user
}
return TRUE;
}
please reply how to do it
Thanks in advance,
RAGHU
Joseph M. Newcomer [MVP]
email: newco...@flounder.com
Web:http://www.flounder.com
MVP Tips:http://www.flounder.com/mvp_tips.htm
Hi Joe,
Thanks for reply.I am not getting the exact flow of what u are saying
What i understood is this:
//Logic is simple i am starting the message "please wait loading in
progress"
theApp.m_dlgMain->PostMessage(UWM_SHOWMSG, TRUE);
/* code for connecting to the device and parsing the .xml file which
will take 1-2 min*/
//Stop the message
theApp.m_dlgMain->PostMessage(UWM_SHOWMSG, FALSE);
ON_MESSAGE(UWM_SHOWMSG,Dispmesg);
LRESULT CDlgMain::Dispmesg(WPARAM wParam, LPARAM)
{
if((BOOL)wParam)
{
U have written lot of functions and how to call
from here is what i am not getting->can u please give a connection
from here
Message "please wait loading in progress" should
start
I do not know how to start a message just saying
the above with no controls-->need help here
}
else
{
which function to call to terminate ???
Message "please wait loading in progress" should
stop
I do not know how to stop a message just saying
the above with no controls-->need your help here
}
return TRUE;
}