How can I delay a function without freezing the thread using C++ - c++

I'm trying to delay a Right Button click using C++,
Right now I have
if (GetKeyState(VK_LBUTTON) > 0) {
delay(120);
}
It works fine but while it's executing the program freezes.
Is there a way I can make it delay the click but without freezing the Program?.

If you want to delay when an action occurs, then you should set a timer for it. Your program shouldn't just delay because it still needs to handle mouse events and graphics during that time. By setting a timer, the action will occur at the appropriate time without the rest of the program freezing.
Here's the microsoft guide on using timers: https://learn.microsoft.com/en-us/windows/desktop/winmsg/using-timers

Related

C++ function Sleep() executes before piece of code

I work in Visual Studio with C++, Windows Form App. I try to paint the button red, wait 3 seconds and then paint it blue.
button1->BackColor = System::Drawing::Color::DarkRed;
Sleep(3000);
button1->BackColor = System::Drawing::Color::CornflowerBlue;
However, Sleep() functions executes before first line (painting red). Program starts from waiting 3 seconds and after time it paints the button blue. It seems like painting red piece of code doesn't have time to execute. Individually, painting red works fine.
I've tried other delay solutions also. Example:
int wait = clock() + 2 * CLOCKS_PER_SEC;
while (clock() < wait) {}
It seems to be an issue in Visual Studio C++, because the Sleep() function have worked perfectly in Code::Blocks console script. Do you have any ideas of solution?
Since Button is also a Window you can Invalidate it before calling Sleep().
what is invalidate,update methods do in VC++
Setting component properties, eg 'button1->BackColor = System::Drawing::Color::DarkRed;' are not trivial assignments. The setter methods generate messages, or sequences of messages, that are posted to the Windows/thread that implement the GUI. Those messages must be handled before the requested property set actions can be considered completed.
If you set a window visual property in an event-handler, and then remove all execution from the thread that manages the window before leaving the event-handler, the messages will not get processed.
Do not wait in a GUI event handler. It's a state-machine for handling messages. Don't stop it.
Thank you for your contribution guys!
Advice about threads was helpful. I've solved this problem with the Refresh() function. It seems like parts of code are handled with different threads which work asynchronous. Refresh() function probably implements waiting for the threads to by synchronised.

ProcessMessages on OnShow Event c++ builder

I'm using c++ builder (bcb6) and on:
FormShow
event there is:
Application->ProcessMessages
I would like to know what exactly the responsibility of:
Application->ProcessMessages
What exactly it did? and when we shall use by that? when it can cause exp.?
Thanks!
The BDS 2006 IDE help states for Application->ProcessMessages this:
Interrupts the execution of an application so that it can process the message queue.
Call ProcessMessages to permit the application to process messages that are currently in the message queue. ProcessMessages cycles the Windows message loop until it is empty, and then returns control to the application.
Neglecting message processing affects only the application calling ProcessMessages, not other applications. In lengthy operations, calling ProcessMessages periodically allows the application to respond to paint and other messages.
ProcessMessages does not allow the application to go idle, whereas HandleMessage does.
so what for it is?
It allows to respond to Windows messages in case your app is blocking normal WindProc operation (inside VCL). For example if you got some lengthy computation on some event that takes minutes the application would freeze (can not click,move,resize,redraw,... until operation is done). If you once in a time call ProcessMessages from that long loop (timers would also not work during that time) that will allow to make your app responsive during this time... so it will not freeze.
I usually use threads or OnIdle event instead for such computations so the main App is not blocked at all.
I am reluctant to believe that OnShow is called during such blocking. I would place the ProcessMessages inside the computation that blocks the App (if the computations is inside the OnShow then it is OK otherwise it would be useless. Anyway OnShow is called only if your Form is turning to Visible do not mistake it for OnActivate or OnPaint.
small example
Create empty form app and place 2 buttons in it (btStart,btStop) then create on click event for them as following:
//---------------------------------------------------------------------------
bool go=false;
//---------------------------------------------------------------------------
void __fastcall TForm1::btStartClick(TObject *Sender)
{
int i=0;
for (go=true;go;)
{
Caption=i; i++;
Application->ProcessMessages();
Sleep(100);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btStopClick(TObject *Sender)
{
go=false;
}
//---------------------------------------------------------------------------
When you start app and click btStart it will start incrementing integer in Caption field of the Form1 and stop when you click btStop. during counting the App is still responsive (can click,move,resize,...). You need to stop before closing App is possible (destructors wait for returning from all events). if you rem out the Application->ProcessMessages(); then the App will count but will never stop because you can not click on btStop due to the freeze. To close click on the IDE and press CTRL+F2.
Hope it clears things a bit.

Making a music player in C++/GTK

I would like to create a music player, but I'm working with robots.
My robot should play a series of action (speech, move, etc) and I need to be able to stop it at anytime (for security).
I'm working with C++ and GTK.
I have a PLAY button linked to the function play_playlist:
void play_playlist ()
{
std::deque<history_record>::iterator it = list_to_play_.begin();
while (!g_stop_ && it != list_to_play_.end())
{
play_action(it); // take time to execute (simulate using sleep 3sec)
it++;
}
}
And a STOP button linked to the function set_stop_to_false:
void set_stop_to_true()
{
g_stop_ = true;
}
When I click PLAY the GUI freezes and I'm not able to click on STOP.
How can I have my playlist running and be able to click on the GUI? (i.e. GUI should be responsive)
My best hope is a thread, but I'm not sure how to use it appropriately.
When I click PLAY the GUI freezes and I'm not able to click on STOP.
You need to build a multi-threaded application. Your interface freezes because your application is busy doing something else, so not only that events raised from GUI are not being processed but they are not even raised.
Your application should start a worker thread that will do its job in the background, the main thread can then communicate with this worker thread for example via shared memory.
Once you enter a callback like play_playlist, the GTK main loop can't process events until you exit that function, which freezes the user interface. As play_action takes seconds to run, you only have 2 choices:
split play_playlist execution in several smaller steps, and use a
state machine to execute each step one after the other using a
callback triggered by g_idle_add. Here's an example of this
technique for lazy loading.
the other solution is to run your blocking play_action in a thread. Give a look at GThread. You start your thread when you press PLAY and stop it when you press STOP. However, you can't manipulate the user interface from a thread, GTK is not thread safe. Every GTK action should be processed from the main thread.

How to stop a function which is still computing with button stop?

I've an application visual c++ written using vs2010,
I have two buttons: "start" and "stop",the first one calls a function that takes a lot of time to process, so in a certain moment I'd like to stop the computation pressing stop button. But in my application the button start seems still clicked (I think it's waiting for the return of the function) and all the other buttons appear to be disabled. Even if I had a wonderful stop function, I could not active because I'm not able to click on button stop. Solutions,ideas,using threads,easy example? Thanks.
You need to run your calculations in another thread. Otherwise your gui freezes until your calculations are done (because only one thing can be done at the moment).
If you are using some modern compiler look at std::thread.
other solutions are boost threads or even microsoft threads.
If your computation is a loop, it may be quite easy to check at each iteration if your User wants to stop the computation.
In the computation thread:
while(compute){
// one loop of computation
}
While your GUI thread can set computationto false through your stop button.
I hope it helps
Note: In c++ as in java Swing etc.., the GUI has it's own thread (not really visible to the developer) and you should never do heavy tasks in it. For instance, every callbacks for buttons should be as small as possible to keep your GUI responsive. This thread's job is just to drive your application.
Button 1 -> onClick =
{
start thread -> { do stuff here }
}
BUtton 2 -> onClick =
{
close thread
}
Be careful when forcibly closing a thread because you can leak memory !
http://msdn.microsoft.com/it-it/library/system.componentmodel.backgroundworker%28v=vs.110%29.aspx
BackgroundWorker is perfect for this use!
First you need to imports the namespace
using System.Threading;
then use the following code :
Thread T=new Thread(Your Code Goes method name);
your method name()
{
// your code goes here
}
T.Start();
then
T.Abort();

Sleep() in Win32 makes program unresponsive

Basically exactly what the title says. I would like to update the text that a button contains every 1 second when the user presses that particular button. I have noted that when the program doesn't have focus it works alright and the text refreshes correctly but when I am hovering over the program or when I am trying to click on it's menu Windows inform me that the program is unresponsive and asks me if I want it terminated. When the loop finishes the program returns to its normal state. Also any action I might have done (like moving it around or closing it) while it was Sleep()-ing is executed after the loop. Here is a bit of code:
case ID_BUTTON_START:
// Code executed when pressing Start Button.
char startButtonText[30]; // Storing next loop text
for (int i=5; i>0; i--)
{
sprintf(startButtonText, "Starting in ... %d", i);
SendMessage(hwndButtonStart, WM_SETTEXT, 0, (LPARAM)(startButtonText));
Sleep(1000);
}
Is this normal? If not what's causing this?
The WndProc does not process messages asynchronously within an application which means all messages are expected to be handled quickly and a return value delivered immediately. You must not Sleep in the UI thread since it will block other UI events from being processed. Any heavy work or synchronous requests/jobs which are likely to take a long time should be performed in worker threads. There are at least three viable options:
Create a new (worker thread) for the task.
If the task is likely to be done often, use a thread pool instead.
Set and subscribe to timer events.
I think the call to Sleep() might be keeping you from returning from the WndProc, so your application is not processing the incomming events for 5 secs. I suggest you try to subscribe to 5 timer events in 1s, 2s,..., 5s. Like when the timer message is recieved the button text must change. I don't know a way how to do that off the top of my head.