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.
Related
I've created a dialog based MFC application on MS Visual Studio 2013. To the dialog, I've added ActiveX elements and some other list elements to show text output. One of the buttons with the ID IDC_BUTTONLAUNCH calls a function like
void CpiezcamDlg::OnBnClickedButtonlaunch()
{
SweepAndImage();
}
The function SweepAndImage(), which is a member of the class CpiezcamDlg and a bit more expensive (it takes about 10 sec). The function also calls updates to the list elements. There is also a Sleep function inside of SweepAndImage(). The result is that during the call of this function, the complete dialog is "blocked" and doesn't react (which makes sense). I've just started with MFC this week so my knowledge is rather limited. I tried to do
void CpiezcamDlg::OnBnClickedButtonlaunch()
{
#pragma omp parallel
{
#pragma omp single nowait
SweepAndImage();
}
}
to sort of "fork" the function into another thread. Since there's an implicit barrier at the end of the omp pragma, this doesn't work. I guess I need some sort event handler that is running in the background of my application and see if that button was clicked. Any kind of help or link is appreciated. If more information is needed, I'll add it.
OpenMP uses fork and thread to do work. It will not really do what you wish here.
MFC's GUI is running on the main thread. SweepAndImage will be run in a separate thread however OnBnClickedButtonlaunch will block waiting for SweepAndImage to return from doing work and then it will continue on. Because the main thread has been blocked updates to the GUI will also halt. Windows/MFC has a hidden window message pump that is abstracted away. That pump relies on event handlers (ie. your button press method) not blocking for too long so that the pump can continue on with the next event in the queue.
Since you are using MFC, MFC does have support for multithreading. I would recommend starting with this MSDN article
What you can do is create a new thread (see the article above) in your button handler that spawns off some work. That will allow the main thread to continue immediately and continue processing windows events in its pump.
To be complete:
Define
UINT SweepAndImage(LPVOID pParam)
Call it like
AfxBeginThread(SweepAndImage, NULL);
Instead of return 0, use
AfxEndThread(0, TRUE); /* or (1, ...) for return 1 */
to exit SweepAndImage
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();
I am currently making a lot of use of code like this in order to determine a control's location within a window's client area:
CRect rect;
GetDlgItem(IDC_CONTROL_ID)->GetWindowRect(&rect);
ScreenToClient(&rect);
All is working fine, but I'm concerned about the safety of this code. Specifically, if the user moves the window in between GetWindowRect and ScreenToClient due to the thread containing the above code being suspended by Windows, will it produce the wrong results? If so, is there a better way of doing this?
The user won't be able to move the window at all while your code inside of a message handler function is executing. So no, this will not be a problem.
The UI is basically temporarily frozen or suspended while your code is running. Technically, this is because Windows is unable to process other messages until you return. The message loop starts running again once you return from your message handler function, thus returning control.
This is, of course, why you shouldn't execute code that takes a long time to run (e.g., complex calculations) inside of your message handlers because the UI will be frozen until it finishes.
Instead, you should spin off a separate thread to run this kind of stuff. Since you're not multi-threading here (and don't need to because this code takes a negligible amount of time to execute), there will be no re-entrancy problems.
I'm New to QT. I understand that you can force a display refresh, but I've pulled all my hair out trying to figure out how. Here is what I'm specifically trying to do.
I press a button (onClick signal event), which runs code that changes an image (QLabel) on the display, waits for input, and then proceeds by changing a new image (different QLabel). I've tried everything and the display doesn't refresh until the onclick signal event code is complete. Right now, I'm not waiting for user input, I'm using usleep(~500 ms) for testing purposes.
From what I read, QT is event driven meaning that I'm basically creating a bunch of events, that get put in a que, and executed when the (onClick signal event) returns to the (main loop)/(event handler). I don't want to wait until the function is complete, it's going to make programming extremely painful if I have to accomplish this routine entirely based on events.
How can I force the QLabel pixmap to refresh. I've tried everything. Below is all the code I have tried in my onClick signal event handler. (upButton is the name of the QLabel which is a pixmap)
update();
repaint();
ui->upButton->setUpdatesEnabled(TRUE);
update();
repaint();
QPaintEvent paintevent(ui->upButton->childrenRegion());
QPaintEvent * test = &paintevent;
paintEvent(test);
this->changeEvent(test);
ui->upButton->update();
ui->upButton->repaint();
ui->upButton->repaint(ui->upButton->childrenRegion());
repaint();
QApplication::sendPostedEvents();
this->parentWidget()->update();
usleep(100000);
As you can see, I'm just shooting in the dark at this point. I've tried to look at sample code and do all my homework, but I'm lost. Appreciate any help, advice, and or sample code.
I was using sleep to emulate a brief amount of time the computer was waiting for something to happen.
As I stated in my question, I didn't want to use events because it's a whole lot of unnecessary work to accomplish something extremely simply.
Also, the 'event' that needs to take place for the program to continue, is a USB event. Since I'm using an HID class device, there is no way to set an event to happen without a wait loop. USB HID classes don't permit setting interrupts, the OS claims the device.
I managed to get the above to work. I walked through the debugger and noticed the display would refresh before the sleep function. Running the program independently, I got random results with the display refreshing 1% of the time. I got rid of the sleep function, and added some other code in it's place to emulate a delay, and it was fine.
Just for everyone's knowledge, this is possible, it's not forbidden, and it's easy to do with the following:
qApp->processEvents();
qApp is a global external variable in the QApplication header.
Because this USB event is making my flow tricky, I stumbled upon the QWaitCondition Class. I was going to start a process waiting for the USB event. I would wait until the process releases the wait condition for my routine to continue.
But if anyone thinks this is a bad idea, please, speak out. I really do appreciate your feedback PiedPiper and Hostile Fork.
Thank you.
I noticed sometimes when you have multiple layered widgets, or widgets inside of widgets it helps to call their repaint() events.
For example
this->repaint();
this->parentWidget()->repaint();
this->parentWidget()->parentWidget()->repaint();
This is far easier then pushing out any processing to another Thread, or creating additional event handlers.
You shouldn't be waiting for input in your event handler. You need to rethink the logic of your program to use events the way they were intended. All the update() and repaint() calls in your code are unnecessary if you return to the event loop.
If i understood correctly, you have a slot and in this slot, you update the image shown in a QLabel. But you want this change to be displayed before the slot finishes.
If that is the case, issue an update() event, and call qApp->processEvents(). This method processes events that are waiting in the event queue and then returns, therefore this may be what you are after.
PS: an update() may not be necessary at all, i am not sure.
I have written a multithreaded program which does some thinking and prints out some diagnostics along the way. I have noticed that if I jiggle the mouse while the program is running then the program runs quicker. Now I could go in to detail here about how exactly I'm printing... but I will hold off just for now because I've noticed that in many other programs, things happen faster if the mouse is jiggled, I wonder if there is some classic error that many people have made in which the message loop is somehow slowed down by a non-moving mouse.
EDIT: My method of "printing" is as follows... I have a rich edit control window to display text. When I want to print something, I append the new text on to the existing text within the window and then redraw the window with SendMessage(,WM_PAINT,0,0).
Actually its a bit more complicated, I have multiple rich edit control windows, one for each thread (4 threads on my 4-core PC). A rough outline of my "my_printf()" is as follows:
void _cdecl my_printf(char *the_text_to_add)
{
EnterCriticalSection(&my_printf_critsec);
GetWindowText(...); // get the existing text
SetWindowText(...); // append the_text_to_add
SendMessage(...WM_PAINT...);
LeaveCriticalSection(&my_printf_critsec);
}
I should point out that I have been using this method of printing for years in a non-multithreaded program without even noticing any interaction with mouse-jiggling.
EDIT: Ok, here's my entire messageloop that runs on the root thread while the child threads do their work. The child threads call my_printf() to report on their progress.
for(;;)
{
DWORD dwWake;
MSG msg;
dwWake = MsgWaitForMultipleObjects(
current_size_of_handle_list,
hThrd,
FALSE,
INFINITE,
QS_ALLEVENTS);
if (dwWake >= WAIT_OBJECT_0 && dwWake < (WAIT_OBJECT_0 + current_size_of_handle_list))
{
int index;
index = dwWake - WAIT_OBJECT_0;
int j;
for (j = index+1;j < current_size_of_handle_list;j++)
{
hThrd[j-1] = hThrd[j];
}
current_size_of_handle_list--;
if (current_size_of_handle_list == 0)
{
break;
}
}
else if (dwWake == (WAIT_OBJECT_0 + current_size_of_handle_list))
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else if (dwWake == WAIT_TIMEOUT)
{
printmessage("TIMEOUT!");
}
else
{
printmessage("Goof!");
}
}
EDIT: Solved!
This may be an ugly solution - but I just changed the timeout from infinite to 20ms, then in the if (dwWake == WAIT_TIMEOUT) section I swapped printmessage("TIMEOUT!"); for:
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
I'm not closing this question yet because I'd still like to know why the original code did not work all by itself.
i can see 3 problems here:
the documentation for WM_PAINT says: The WM_PAINT message is generated by the system and should not be sent by an application. unfortunately i don't know any workaround, but i think SetWindowText() will take care of repainting the window, so this call may be useless.
SendMessage() is a blocking call and does not return until the message has been processed by the application. since painting may take a while to be processed, your program is likely to get hanged in your critical section, especially when considering my 3rd point. PostMessage() would be much better here, since you have no reason to need your window to be repainted "right now".
you are using QS_ALLEVENTS in MsgWaitForMultipleObjects(), but this mask DOES NOT include the QS_SENDMESSAGE flag. thus your SendMessage() call is likely ignored and does not wake your thread. you should be using QS_ALLINPUT.
can you check the behavior of your application with an INFINITE timeout and the above 3 modifications included ?
If I remember correctly, WM_PAINT is a very low priority message, and will only get relayed when the message queue is otherwise empty. Also, Windows will coalesce multiple WM_PAINT messages into one. I could see the mouse movement resulting in fewer redraw events, each handling a larger update, thus improving performance.
Well I can't totally help you because we don't have enough info but I had a similar problem where my application would not refresh unless I moved the mouse or after some (not unsignificant) delay.
When investigating the problem I found that basically, the GUI thread will sleep if there is no more messages to process. Jiggling the mouse will create new windows messages to be sent to the windows, waking the thread from sleep.
My problem was that I was doing my processing in the OnIdle (MFC, not sure about you) function, and that, after doing the processing one time, the thread would go to sleep.
I don't think that is your problem since you seems to post a windows message (WM_PAINT) from your thread, what I wasn't doing in my case (which should wake up the gui thread) but maybe this can help you get in the right direction to solve your problem?
Edit: I though about it a little, maybe there is a special case for WM_PAINT (like you forget to call Invalidate or something, I'm not an expert in windows programming) so maybe try to post another message like WM_USER to your application and see if it fix your problem (this should be sure to wake up the gui thread I think). Also posting the full call to the SendMessage function could help.
Edit2: Well, after seeing your comment to Kelly French above you seems to have exactly the same symptoms I had so I would guess that, for whatever reason, your call to PostMessage do not seems to wake up the gui thread or something similar. What are you passing for first argument to PostMessage? What I did in my case was to call PostMessage with argument WM_USER, 0, 0 to my app. You can also try the PostThreadMessage variant while keeping the current threadID of the main thread in a variable (see GetCurrentThreadId).
Also you could try to call Invalidate on your object. Windows keeps memory of if an object need to be repainted and will not do it if it is not needed. I do not know if a direct call to WM_PAINT override this or not.
Well that's all I can think of. At least you found a fix even if it is not the most elegant.
Are you completely sure that the program really runs faster? Or is it output that is refreshed more frequently?
Are you using SendMessage or PostMessage? I'm curious if perhaps switching to the other will make things work "better" in this particular environment.
Taken from developerfusion:
There’s another similar API which
works exactly like SendMessage and
that is PostMessage API. Both require
same parameters but there’s a slight
difference. When a message is sent to
a window with SendMessage, the window
procedure is called and the calling
program (or thread) waits for the
message to be processed and replied
back, and until then the calling
program does not resume its
processing. One thing is wrong with
this approach however, that is if the
program that is busy carrying out long
instructions or a program that has
been hung and hence no time to respond
to the message will in turn hang your
program too because your program will
be waiting for a reply that may never
arrive. The solution to this is to use
PostMessage instead of SendMessage.
PostMessage on the otherhand returns
to the calling program immediately
without waiting for the thread to
process the message, hence saving your
program from hanging. Which of them
you have to use depends on your
requirement.
Is your GUI window maximized? Does it happen whether the mouse movement happens over your app window or over some other window like another app or the desktop? When the mouse moves over your app, the mouse_move messages get sent to your message queue. This may wake up the thread or be forcing a WM_PAINT message.
I doubt that the printing is actually going faster. I suspect that the increased number of messages caused by the mouse movement is forcing more window invalidation events so the text updates are happening on a more granular basis. When the mouse isn't being moved does the printing happen in larger blocks, say blocks of 20 characters vs 5 characters at a time?
Could you clarify what you mean by faster printing? Is it absolute, like 100 characters per minute vs 20 characters per minute? Or is it more like 100 characters per minute either way but they show up in blocks when the mouse is still?
One possibility is that you are seeing the effect of the OS doing thread priority boosting / retarding for certain GUI messages.
I am assuming you have one ”GUI & Other Stuff” thread, and multiple worker threads. When there is no GUI activity, the “Other Stuff” thread goes to a lower priority. When you wiggle the mouse or timeout, the “Other Stuff” thread goes to a higher priority.
Changing the worker threads to a lower priority and then wiggling the mouse, would confirm or refute this.
I think it has to do with processing in foreground and background. If the operating system thinks your window is not top priority it shifts your job to background. If you are forcing the window to be on top, it will put all its resources to work on your window and drops the other items it is working on. Its real and its been here since DOS. http://en.wikipedia.org/wiki/Foreground-background You might try calling the following at critical times in your code.
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long