-
December 27th, 2017, 05:10 AM
#1
OnIdle?
Sorry if I repeated the same question. But as I tried to find there was no Q&A that fitted in with my work.
What I want to know is this:
I am working on SDI-MFC application. I click on the toolbar button, let me say the "Play" button to play animation.
In animation loop, it is a loop to repeat drawing. While animation is going on. Then I want to click the other button, the "Stop" button, on the toolbar to stop playing animation.
But I cannot. It seems that I even cannot do anything else, except waiting the animation loop to finish.
Could anyone help me in this issue. Thank you in advance.
I am very pleased to give more information in case my question is not clear.
-
December 27th, 2017, 08:13 AM
#2
Re: OnIdle?
Is it your own application?
What do you mean by "In animation loop, it is a loop to repeat drawing"?
Victor Nijegorodov
-
December 27th, 2017, 09:53 AM
#3
Re: OnIdle?
Originally Posted by VictorN
Is it your own application?
What do you mean by "In animation loop, it is a loop to repeat drawing"?
Yes, it is. It is my own application.
The code segment is shown in the following:
Code:
void CMIDEView::OnPlayButton()
{
// TODO: Add your command handler code here
this->m_bPlayAnimation = TRUE;
double scale = 1000;
double factor;
BOOL STOP;
MSG msg;
STOP = false;
factor = 0;
double inc = 0.1;
while (!STOP)
{
if (m_bPlayAnimation)
{
GetDocument()->AdjustDeformScale(scale, factor);
Invalidate(NULL);
}
else
return;
if (factor >= 1000)
inc = -0.1;
if (factor <= 0)
inc = 0.1;
factor += inc;
if (::PeekMessage(&msg, GetSafeHwnd(), WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
{
if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE)
{
STOP = TRUE;
m_bPlayAnimation = FALSE;
}
}
}
}
The animation isn't working here. But it doesn't matter because it works well by invoking another event.
The code as shown above, it can detect "pressing Esc key" to exit the loop. And what I want is to make it able to detect pressing the 'STOP' button at the toolbar, like I invoke the OnPlayButton().
Any more information is very pleased to give, but please be patient to wait because of time difference, Thank you again.
Last edited by 2kaud; December 27th, 2017 at 12:55 PM.
-
December 27th, 2017, 11:26 AM
#4
Re: OnIdle?
To be more specific,
if I have the loop like this:
Code:
non_stop = true;
do
{
do_some_action();
}
while (non_stop);
While this loop is running, I cannot do anything, for example clicking on the menu file. So what I want should be like this:
Code:
non_stop = true;
do
{
do_some_action();
if (I_click_stop_button())
non_stop = false;
}
while (non_stop);
Last edited by 2kaud; December 27th, 2017 at 12:55 PM.
-
December 27th, 2017, 12:04 PM
#5
Re: OnIdle?
See the example in MSDN
In your case you should also check the WM_COMMAND message with the wParam containing in its low word the ID of the "Stop" button.
Victor Nijegorodov
-
December 27th, 2017, 12:42 PM
#6
Re: OnIdle?
I don't think this (the code below) would be enough.
As I stated earlier, while the loop is running, I cannot do anything else.
It is very late in the night time here, so I will study more in the link you gave me.
Code:
void CMIDEView::OnPlayButton()
{
// TODO: Add your command handler code here
this->m_bPlayAnimation = TRUE;
double scale = 1000;
double factor;
BOOL STOP;
MSG msg;
STOP = false;
factor = 0;
double inc = 0.1;
while (!STOP)
{
if (m_bPlayAnimation)
{
GetDocument()->AdjustDeformScale(scale, factor);
Invalidate(NULL);
}
else
return;
if (factor >= 1.0)
inc = -0.1;
if (factor <= 0)
inc = 0.1;
factor += inc;
if (::PeekMessage(&msg, GetSafeHwnd(), WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
{
if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE)
{
STOP = TRUE;
m_bPlayAnimation = FALSE;
}
if (msg.message == WM_COMMAND && msg.wParam == ID_STOP_BUTTON)
{
STOP = TRUE;
m_bPlayAnimation = FALSE;
}
}
}
}
Last edited by 2kaud; December 27th, 2017 at 12:56 PM.
-
December 27th, 2017, 12:59 PM
#7
Re: OnIdle?
[When posting code, please use code tags so that the code is readable. Go Advanced, select the formatted code and click '#'.]
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
December 27th, 2017, 12:59 PM
#8
Re: OnIdle?
1. Please, use CODE tags while posting code snippets. See Announcement: Before you post....
2. Please, compare the call of PeekMessage from MSDN example and yours. Don't you see the difference?
Also read the PeekMessage function description.
Victor Nijegorodov
-
December 27th, 2017, 01:33 PM
#9
Re: OnIdle?
I click on the toolbar button, let me say the "Play" button to play animation.
In animation loop, it is a loop to repeat drawing. While animation is going on. Then I want to click the other button, the "Stop" button, on the toolbar to stop playing animation.
It looks like you are only using one thread? Why not have one thread dealing with the gui (buttons etc) and one thread dealing with the animation. See http://flounder.com/workerthreads.htm for details re using worker threads.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
December 27th, 2017, 10:36 PM
#10
Re: OnIdle?
Originally Posted by 2kaud
[When posting code, please use code tags so that the code is readable. Go Advanced, select the formatted code and click '#'.]
Verry sorry and thank you very much.
-
December 27th, 2017, 10:53 PM
#11
Re: OnIdle?
Originally Posted by VictorN
I tried to follow the link you gave me, but it does not work. I still cannot do anything else while the loop is performing. Anyway I do not use thread, do I need to use it?
-
December 27th, 2017, 10:54 PM
#12
Re: OnIdle?
Originally Posted by 2kaud
It looks like you are only using one thread? Why not have one thread dealing with the gui (buttons etc) and one thread dealing with the animation. See http://flounder.com/workerthreads.htm for details re using worker threads.
Yes, I use just one thread. So I will try.
-
December 28th, 2017, 12:37 AM
#13
Re: OnIdle?
Originally Posted by Kiattisak
I tried to follow the link you gave me, but it does not work. I still cannot do anything else while the loop is performing. Anyway I do not use thread, do I need to use it?
The link Victor gave you should work. https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
The main problem with your code is you are calling PeekMessage in an if statement rather than in a while loop. Generally, there are hundreds of messages getting passed to your app, so if you use an if statement, you are only going to process one message. You need to use a while loop so you process all the messages.
-
December 28th, 2017, 12:43 AM
#14
Re: OnIdle?
Originally Posted by Arjay
The link Victor gave you should work. https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
The main problem with your code is you are calling PeekMessage in an if statement rather than in a while loop. Generally, there are hundreds of messages getting passed to your app, so if you use an if statement, you are only going to process one message. You need to use a while loop so you process all the messages.
Thank you very much for your reply. I will check it again very carefully. By the way, I already switched to use while loop, rather than an if statement.
-
December 28th, 2017, 04:29 AM
#15
Re: OnIdle?
Finally, I do this approach as shown below. It works in the way I want. However, more comments, suggestions, and advice are still welcome to make it even better.
Code:
MSG msg;
non_stop = true;
do
{
do_some_action();
if(::peekMessage(&msg, AfxGetMainWnd()->m_hWnd, 0, 0, PM_REMOVE)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (I_click_stop_button_on_toolbar())
non_stop = false;
}
while (non_stop);
PS. I tried to read a thread approach, it made me quite confused.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|