where am I mistaking
Hello,
In my code :
OnLButtonDown()
{
Draw_Object_One();
Invalidate(False);
Sleep(2000);
Draw_Object_Two();
Invalidate(False);
}
This code should first draw object one and then wait for two seconds and then draw object two.
What is happening is that it does not draw object one but draws object two
and then halts the program for two seconds?
Can anybody see what I am doing wrong?
Thanks!
[481 byte] By [
Ajami] at [2007-11-20 11:48:28]

# 1 Re: where am I mistaking
Hello,
In my code :
OnLButtonDown()
{
Draw_Object_One();
Invalidate(False);
Sleep(2000);
Draw_Object_Two();
Invalidate(False);
}
This code should first draw object one and then wait for two seconds and then draw object two.
What is happening is that it does not draw object one but draws object two
and then halts the program for two seconds?
Can anybody see what I am doing wrong?
Thanks!
what does Draw_Object_X do? it sounds like you are not actually drawing it to the screen, so the object 2 that you see is maybe the one from the previous LButtonDown()?
but that does not make 100% sense to me, what is triggering the WM_PAINT message? can you post more of the code?
# 2 Re: where am I mistaking
Both Draw..() functions are working properly because when I try each of them alone they work correctly.
Invalidate(False) will trigger the WM_PAINT message.
Thanks for your reply.
Ajami at 2007-11-11 4:03:57 >

# 3 Re: where am I mistaking
Your application likely isn't handling any incoming messages during that 2-second sleep -period. Sort of same effect when you do a long loop without 'message pumping' -> application seems not to respond to any messages.
eero_p at 2007-11-11 4:04:56 >

# 4 Re: where am I mistaking
Both Draw..() functions are working properly because when I try each of them alone they work correctly.
Invalidate(False) will trigger the WM_PAINT message.
Thanks for your reply.
Invalidate() only produces a WM_PAINT message when the thread is idle.
Sleep "Suspends the execution of the current thread", so the message is not produced.
try putting an UpdateWindow() in to see if that helps?
# 5 Re: where am I mistaking
Where should I put the UpdateWindow function.
I am using sleep here to delay the drawing of the second object for two seconds.
But what is happening is that the first object is never drawn and then the second object is drawn. After that my program suspends for two seconds??
Thanks!
Ajami at 2007-11-11 4:06:55 >

# 6 Re: where am I mistaking
As a general rule: put all drawing stuff into the WM_PAINT message handler.
# 7 Re: where am I mistaking
Where should I put the UpdateWindow function.
I am using sleep here to delay the drawing of the second object for two seconds.
But what is happening is that the first object is never drawn and then the second object is drawn. After that my program suspends for two seconds??
Thanks!
put one straight after both of the invalidate functions. that will force the window to redraw itself instead of waiting for windows to decide when it can..
you can keep the sleep() in to produce the delay
# 8 Re: where am I mistaking
Thanks LOki,
I placed UpdateWindow() before sleep and it worked as I want.
But until know I can't understand the reason.
Thanks again
Ajami at 2007-11-11 4:10:03 >

# 9 Re: where am I mistaking
Thanks LOki,
I placed UpdateWindow() before sleep and it worked as I want.
But until know I can't understand the reason.
Thanks again
no problem :)
when you call Invalidate() that tells Windows that you have changed the window and it needs to redraw it. But windows waits until it is not doing anything before it actually redraws the window (sends WM_PAINT message).
Sleep() counts as 'doing something' (even though it is not doing anything useful) so Windows does not send the paint message.
by calling UpdateWindow() you are forcing windows to send the WM_PAINT message at that point.
# 10 Re: where am I mistaking
Yes LOKI I understand what you said but the Sleep() function is after the first Invalidate().
This first invalidate was the function that was not executed knowing that it is before the Sleep().
Thanks!
Ajami at 2007-11-11 4:11:57 >

# 11 Re: where am I mistaking
Yes LOKI I understand what you said but the Sleep() function is after the first Invalidate().
This first invalidate was the function that was not executed knowing that it is before the Sleep().
Thanks!
no problem - i was sort of thinking out loud :) the Invalidate should still be executed, but windows does not generate a separate paint message.
it is not what i originally expected, i thought it should at least draw both after two seconds not just the second one.
could you post one of your drawing functions and your WM_PAINT handler as it is interesting for me :) maybe i will just write something later to test it.
# 12 Re: where am I mistaking
PushButtons()
{
//static int cnt[10]={0,};
GLuint Arrow;
CRect cr; // client rectangle -
// used to calculate client sizes
CMainFrame *pFrame;
pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
(pFrame->m_viewportSplitter.GetPane( 0, 1 ))->GetClientRect( &cr );
GLfloat xbox = (GLfloat)cr.Width(),ybox=25.0;
GLfloat ar = (GLfloat)cr.Width() / (GLfloat)cr.Height(); //aspect ratio
glDisable( GL_TEXTURE_2D );
//Bottom
::glPushMatrix();
::glLineWidth(1.0f);
::glTranslatef(0.0f,45.0f,0.0f);
::glBegin(GL_LINE_LOOP);
::glColor3f(1.0f,1.0f,1.0f);
::glVertex2f(0.0f, 0.0f);
::glVertex2f(xbox, 0.0f);
::glVertex2f(xbox, ybox);
::glVertex2f(0.0f, ybox);
::glEnd();
::glPopMatrix();
::glPushMatrix();
::glTranslatef(0.0f,45.0f,0.0f);
if(m_click[0] == 1)
::glColor3ub(150,170,250);
if(m_click[0] == 0)
::glColor3ub(7,14,252);
::glRectf(0.0f,0.0f,xbox,ybox);
::glPopMatrix();
//Top
::glPushMatrix();
::glLineWidth(1.0f);
::glTranslatef(0.0f,(GLfloat)cr.Height()-ybox-200.0,0.0f);
::glBegin(GL_LINE_LOOP);
::glColor3f(1.0f,1.0f,1.0f);
::glVertex2f(0.0f, 0.0f);
::glVertex2f(xbox, 0.0f);
::glVertex2f(xbox, ybox);
::glVertex2f(0.0f, ybox);
::glEnd();
::glPopMatrix();
::glPushMatrix();
::glTranslatef(0.0f,(GLfloat)cr.Height()-ybox-200.0,0.0f);
if(m_click[1] == 1)
::glColor3ub(150,170,250);
if(m_click[1] == 0)
::glColor3ub(7,14,252);
::glRectf(0.0f,0.0f,xbox,ybox);
::glPopMatrix();
xbox = 25.0;
ybox= (GLfloat)cr.Height()-50.0-200.0-45.0;
//Left
::glPushMatrix();
::glLineWidth(1.0f);
::glTranslatef(0.0f,70.0f,0.0f);
::glBegin(GL_LINE_LOOP);
::glColor3f(1.0f,1.0f,1.0f);
::glVertex2f(0.0f, 0.0f);
::glVertex2f(xbox, 0.0f);
::glVertex2f(xbox, ybox);
::glVertex2f(0.0f, ybox);
::glEnd();
::glPopMatrix();
::glPushMatrix();
::glTranslatef(0.0f,70.0f,0.0f);
if(m_click[2] == 1)
::glColor3ub(150,170,250);
if(m_click[2] == 0)
::glColor3ub(7,14,252);
::glRectf(0.0f,0.0f,xbox,ybox);
::glPopMatrix();
//Right
::glPushMatrix();
::glLineWidth(1.0f);
::glTranslatef((GLfloat)cr.Width()-25.0f,70.0f,0.0f);
::glBegin(GL_LINE_LOOP);
::glColor3f(1.0f,1.0f,1.0f);
::glVertex2f(0.0f, 0.0f);
::glVertex2f(xbox, 0.0f);
::glVertex2f(xbox, ybox);
::glVertex2f(0.0f, ybox);
::glEnd();
::glPopMatrix();
::glPushMatrix();
::glTranslatef((GLfloat)cr.Width()-25.0f,70.0f,0.0f);
if(m_click[3] == 1)
::glColor3ub(150,170,250);
if(m_click[3] == 0)
::glColor3ub(7,14,252);
::glRectf(0.0f,0.0f,xbox,ybox);
::glPopMatrix();
Arrow = glGenLists(1);
glNewList(Arrow, GL_COMPILE);
::glColor3f(1.0f,1.0f,1.0f);
glBegin(GL_TRIANGLES);
glVertex2f(-7.5,0);
glVertex2f(0.0,7.5);
glVertex2f(7.5,0);
glEnd();
glEndList();
glDisable( GL_DEPTH_TEST );
//bottom arrows
::glPushMatrix();
::glLineWidth(1.0f);
::glTranslatef((GLfloat)cr.Width()/2.0f-75.0f,45.0f+ 25.0/2.0f, 0.0f);
::glRotatef(180, 0.0f, 0.0f, 1.0f);
::glCallList(Arrow);
::glPopMatrix();
::glPushMatrix();
::glTranslatef(0.0f,45.0f,0.0f);
Text(cr.Width()/2.0f-20.0f,8.0f,white,75.0f,"South");
::glPopMatrix();
::glPushMatrix();
::glLineWidth(1.0f);
::glTranslatef((GLfloat)cr.Width()/2.0f+75.0f, 45.0f+25.0/2.0f, 0.0f);
::glRotatef(180, 0.0f, 0.0f, 1.0f);
::glCallList(Arrow);
::glPopMatrix();
//top arrows
::glPushMatrix();
::glLineWidth(1.0f);
::glTranslatef(0.0f,(GLfloat)cr.Height()-200-25.0,0.0f);
::glTranslatef((GLfloat)cr.Width()/2.0f-75.0f, 25.0/2.0f, 0.0f);
::glRotatef(0, 0.0f, 0.0f, 1.0f);
::glCallList(Arrow);
::glPopMatrix();
::glPushMatrix();
::glTranslatef(0.0f,(GLfloat)cr.Height()-xbox-200.0,0.0f);
Text(cr.Width()/2.0f-20.0f,8.0f,white,75.0f,"North");
::glPopMatrix();
::glPushMatrix();
::glLineWidth(1.0f);
::glTranslatef(0.0f,(GLfloat)cr.Height()-200-25.0,0.0f);
::glTranslatef((GLfloat)cr.Width()/2.0f+75.0f, 25.0/2.0f, 0.0f);
::glRotatef(0, 0.0f, 0.0f, 1.0f);
::glCallList(Arrow);
::glPopMatrix();
//left arrows
::glPushMatrix();
::glLineWidth(1.0f);
::glTranslatef(0.0f,70.0f,0.0f);
::glTranslatef(25.0/2.0f,(GLfloat)ybox/2.0f-75.0,0.0f);
::glRotatef(90, 0.0f, 0.0f, 1.0f);
::glCallList(Arrow);
::glPopMatrix();
::glPushMatrix();
::glTranslatef(0.0f,70.0f,0.0f);
::glRotatef(90, 0.0f, 0.0f, 1.0f);
Text(ybox/2.0f-22.0f, -20.0f,white,75.0f,"West");
::glPopMatrix();
::glPushMatrix();
::glLineWidth(1.0f);
::glTranslatef(0.0f,70.0f,0.0f);
::glTranslatef(25.0/2.0f,(GLfloat)ybox/2.0f+75.0,0.0f);
::glRotatef(90, 0.0f, 0.0f, 1.0f);
::glCallList(Arrow);
::glPopMatrix();
//right arrows
::glPushMatrix();
::glLineWidth(1.0f);
::glTranslatef((GLfloat)cr.Width()-25.0f,70.0f,0.0f);
::glTranslatef(25.0/2.0f, (GLfloat)ybox/2.0f-75.0,0.0f);
::glRotatef(-90, 0.0f, 0.0f, 1.0f);
::glCallList(Arrow);
::glPopMatrix();
::glPushMatrix();
::glTranslatef((GLfloat)cr.Width()-25.0f,70.0f,0.0f);
::glRotatef(-90, 0.0f, 0.0f, 1.0f);
Text(-ybox/2.0f-5.0f, 5.0f,white,75.0f,"East");
::glPopMatrix();
::glPushMatrix();
::glLineWidth(1.0f);
::glTranslatef((GLfloat)cr.Width()-25.0f,70.0f,0.0f);
::glTranslatef(25.0/2.0f, (GLfloat)ybox/2.0f+75.0,0.0f);
::glRotatef(-90, 0.0f, 0.0f, 1.0f);
::glCallList(Arrow);
::glPopMatrix();
}
This is my drawing function. I just call it from OnDraw()
thanks!
Ajami at 2007-11-11 4:14:03 >

# 13 Re: where am I mistaking
PushButtons()
{
...
}
This is my drawing function. I just call it from OnDraw()
Well, how and what can this function draw if you don't pass the CDC pointer/reference to it from the OnDraw handler? :confused:
# 14 Re: where am I mistaking
This is my drawing function. I just call it from OnDraw()
thanks!
what about Draw_Object_One() and Draw_Object_Two() ?
# 15 Re: where am I mistaking
Sorry guys but I forgot to tell you that I call PushButtons()
form the Draw() functions
Thanks!
Ajami at 2007-11-11 4:17:04 >

# 16 Re: where am I mistaking
Sorry guys but I forgot to tell you that I call PushButtons()
form the Draw() functions
Thanks!Nice! :D
But how and why?
And how is it related to the drawing? :confused:
# 17 Re: where am I mistaking
Seems that I am not able to express my self well. Sorry!
The PushButton() function is really found in the OnDraw() function but when I call the Invalidate() function after the draw functions the PushButton is automatically executed.
I hope this makes it clear.
The role of the Draw functions is to prepare some variables for the PushButton functions.
Thanks
Ajami at 2007-11-11 4:19:08 >

# 18 Re: where am I mistaking
The PushButton() function is really found in the OnDraw() function but when I call the Invalidate() function after the draw functions the PushButton is automatically executed.
I hope this makes it clear.
Yeah, absolutely clear. It's like running around tail... nasty!
The role of the Draw functions is to prepare some variables for the PushButton functions.
Dear Ajami,
First take a look at my first post...
As a general rule: put all drawing stuff into the WM_PAINT message handler.
...then complete with "...and only drawing stuff".
# 19 Re: where am I mistaking
Thanks For all of your help. This forum is the best.
But still I don't understand how the UpdateWindow() function solved my problem.
The Sleep() function should have delayed the execution of the second Draw
function and not the first one but the opposite was happening.
It was only solved when I used UpdateWindow()??
Thanks
Ajami at 2007-11-11 4:21:10 >

# 20 Re: where am I mistaking
You can think of Invalidate as PostMessage (async), and UpdateWindow as SendMessage (snyc).
As you must have known to, PostMessage sends the message to target window and does not wait for the message to process (just like you send email/sms). On the other hand, SendMessage waits for the message to complete and does not return until message is processed (calling a friend and telling something him/her - you don't end call unless you deliver your message).
I hope you it makes everything clear.
# 21 Re: where am I mistaking
Ajay,
Therefore I understand that it is not necessary for the Invalidate() function to be processed completely before the program continues its next instruction statement.
Now I understand!!!
Is there any function other than Sleep() I can use to make a delay.
The Sleep() function is pending my program for 2 seconds. I don't want this to happen.
Thanks!
Ajami at 2007-11-11 4:23:12 >

# 22 Re: where am I mistaking
Ajay,
Therefore I understand that it is not necessary for the Invalidate() function to be processed completely before the program continues its next instruction statement.
Now I understand!!!
Is there any function other than Sleep() I can use to make a delay.
The Sleep() function is pending my program for 2 seconds. I don't want this to happen.
Thanks!
you mean you want a delay in the drawing, but not in the execution of your code? what is is that your program is doing/drawing? - it would help me to know what you are tying to do
in the mean time, have a look at timers.
# 23 Re: where am I mistaking
Ajay,
Is there any function other than Sleep() I can use to make a delay.
The Sleep() function is pending my program for 2 seconds. I don't want this to happen.
Thanks!
Delay what ?? Execution of your program ?? check out for timers.. it may help you..
Thanx
As loki said use timers instead
# 24 Re: where am I mistaking
Hi,
The Sleep() function I am using is working OK but the code is stuck in this function for two seconds.
Is there any function I can use that permits another code to interrupt the Sleep() function.
For example I may have serial data coming in during these two seconds delay and I want to get notified.
Thanks!
Ajami at 2007-11-11 4:26:14 >

# 25 Re: where am I mistaking
Well, you may hookup with PeekMessage. Refer to this function in MSDN, find out relevant sample code and implement.
Along with GdiFlush may also do the trick.
# 26 Re: where am I mistaking
...
For example I may have serial data coming in during these two seconds delay and I want to get notified.
Thanks!Then you have to use multithreading (one worker thread to get data from the serial port + one worker or, better, UI thread to send data to the port).
The Sleep cannot help you at all! Keep in mind that using Sleep is usually a very serious design mistake, at least in the main GUI thread!
About serial port I/O you could read in this Joe Newcomer's essay: http://www.flounder.com/serial.htm
# 27 Re: where am I mistaking
VictorN,
Where can I read more about multithreading. I need a beginners book or something(MSDN is a little complex for me).
Why is using Sleep() a serious mistake?Thanks!
Ajay,
Do you prefer using the PeekMessage over multithreading?Thanks!
Ajami at 2007-11-11 4:29:19 >

# 28 Re: where am I mistaking
VictorN,
Where can I read more about multithreading. I need a beginners book or something(MSDN is a little complex for me).There is indeed MSDN at the first place.
Then have a look at "The "Threads and Processes series" on the Joe Newcomer page:
MVP Tips, Techniques, and Goodies (http://www.flounder.com/mvp_tips.htm)
Using Worker Threads (http://www.flounder.com/workerthreads.htm)
Why is using Sleep() a serious mistake?Thanks!
GUI thread must process messages. If it sleeps - no messages can be processed. The process hangs. Sometimes it could cause a deadlock. See MSDN about Sleep using.
Once more point is here: prohttp://groups.google.com/group/microsoft.public.vc.mfc/browse_frm/thread/f5e6ee74289129fc/b9b18fc5664333e5?lnk=st&q=sleep+newcomer+mfc#b9b18fc5664333e5
# 29 Re: where am I mistaking
Ajay,
Do you prefer using the PeekMessage over multithreading?Thanks!Nopes. I dont!
It it just a trick for single threaded applications, which can do something else and also handles windows messages. It is non-recommended way. Multithreading is the only recommended way for your problem.
But to understand and use MT along with GUI, you need to learn basics of MT. Start with CreateThread function. Use PostThreadMessage to post the thread a message, which you can handle in thread using GetMessage.
First code for MT, it should be non-GUI. Create threads, wait for them (WaitForSingleObject), send some data, use synronization primitives (mutex, critical section etc.). There is a long way to go, to master MT. But it is one of the interesting topics of Software engineering!