Hi I am currently writing a windows form application using visual studio 2010, the application I am writing needs to update labels on the form independent of any events happening - I know it is possible to update the form using event handlers but this requires and event to happen to do something.
I am planning to to use some form of main loop to update the form constantly - I just do not know where to place such a loop? I think I've heard of something called the message loop, would it go there? Or would I have to create a separate thread to do so - and if I did create a separate thread , would I have problems accessing controls created in another thread?
Basically I am modelling an elevator system and need to update certain details about the elevator to the form constantly without any buttons being pressed , e.g current floor, going up down ect
I can post code if need be
You almost certainly want to do the background work in a worker thread. Have that worker thread send updated data to the main thread in a way that triggers an event. The main thread then updates the UI based on the updated data in reaction to the event you triggered.
Related
In my MFC application , I am using TCP/IP socket for communcating and getting data from a server.During this process I am displaying a modelless dialog with static text and progress control.During communication I am updating the static text and progress control in a separate user thread(AfxBeginThread).
If I try to communicate to wrong ip the sockets select function with timeout value 5 secs blocking the displaying of dialog with static text and progress control(I.e the dialog hangs, the controls are getting displayed).
Once the socket comes out from select function the dialog is getting displayed properly.
How to fix this problem?
In MFC, I'd strongly recommend using CAsyncSockets, and just reacting when data comes in from the server. You probably have no need to spin up a thread at all.
If you were going to spin up a separate thread for part of the job, you'd want to allocate tasks to threads somewhat differently. You always want to leave UI updates in the main thread (the one that was created by default). If you were going to use (for example) a blocking socket, and call select on it, you'd want to move that work to a separate thread, and leave the UI updates in the thread that was created by default. Then the thread handling the socket could (for example) send messages to the UI thread to tell it about what's going on, so it could update the UI appropriately. But, as already noted, you probably just want to use a CAsyncSocket, in which case you won't need a second thread at all.
I am working on a dialog-based MFC Application using Visual Studio 2015. Basically my problem is that I have a button that will start a worker thread after the user has chosen the necessary inputs (.csv files that will be parsed and put into different vectors). To avoid complications, I decided that the user will not be able to press this button or the input buttons until after the calculation done by the worker thread has finished. I tried the WaitforSingleObject options but defeats the purpose of keeping the main thread or the MFC Application running while waiting for the worker thread to finish. Is there any other workaround around this problem? I appreciate any help.
Your worker thread could post a completion message back to your UI thread. Your UI thread wouldn't need a special message loop in that case, instead your window procedure would then reenable the buttons when it receives that message.
You could use the MsgWaitForMultipleObjects function:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684242(v=vs.85).aspx
ATL uses it in AtlWaitWithMessageLoop(https://msdn.microsoft.com/en-us/library/26hwk2bx.aspx).
I have a CListCtrl in my MFC application. The list needs to be updated when I get some notification from the server. Updating list works quite good when there are less notification as operations on the list are less. But in case of heavy load, list control and in turn the application gets freeze.
I am aware of updating UI items in the separate thread in case of bulk updates, but in this case I have the notifications that can come in any order and in any volume, I need to handle in such way that my main thread is not getting blocked.
If anyone faced the issue before please suggest the approach for this case.
You could put all the updates into a queue. Then do a limited number of updates from the queue to the control in the OnIdle function. OnIdle is called when your GUI message queue is empty. It could do up to, say, 20 updates and then return. The main thread would than process any GUI input and when finished with that it would call OnIdle again. In this way you delay and spread out the updates while keeping the GUI alive.
I had a similar situation and resolved it using a Timer. Only when the Timer ticked the ListCtrl could got updated.
Side note: You should do
SetRedraw(FALSE);
before a bulk update
and
SetRedraw(TRUE);
after.
You should not have the control drawing itself at a one-by-one item level, when doing a bulk operation.
Use Thread.I had the same problem and I solved it by just having the loop of adding elements into the clistctrl in thread function. That is,is the POSTMESSAGE() function in the thread should be called as much time as we want to add elements .
MFC Application getting stuck when adding list control elements
Also refer the above link to get some idea
I was able to move SliderControl according to the position using CSliderCtrl::GetPos , being played by the program. (This is a part of my Music Player MFC project).
But I need to do this automatically without any notification/events ....
I thought of creating a thread that will move slider after clicking on play button.
You generally want to have exactly one thread updating the UI (and doing as little else as possible).
It would almost certainly work better to have a secondary thread playing the music. It can send a message to the UI thread, and the UI thread updates the slider control position when it receives that message.
It is always good to update the UI from the main thread instead of adding a new thread for updating UI. Better you can perform your background tasks by using a worker thread and update the UI by sending a message to the main thread when ever required.
In your case, you can have a worker thread to play the music and send a message to the main thread to update the slider position.
::SendMessage( AfxGetMainWnd()->m_hWnd, Message_Id, ( WPARAM )&String, 0 );
You can use the APIs CSliderCtrl::SetPos() to update the position.
I have a QT application that allows a user to define a list of models. Each model defined has a fairly complex widget class that is created. Currently this is all being done in the main (GUI) thread. The program works fine for normal use, but I tried to stress test it by creating 200 to 1000 models and the creation of the GUI took a VERY long time (20 seconds to many minutes).
I tried a couple attempts at threading out the work using QtConcurrent::run, but the program always complained because "Widgets must be created in the GUI thread."
I found this answer on SO: How do I create a Window in different QT threads?. But this doesn't seem to be doing much in the new thread except telling the main thread to create a new widget. This does not distribute the workload, as far as I can tell.
With all of that, I have a couple direct questions:
1) Is there a better design (faster performance) than looping through my list of models and serially creating each widget?
2) If this process is possible to be multithreaded, can someone point me in the direction of a simple example?
There really is no way to put widget stuff to other threads. OpenGL rendering or some data processing for a widget to show when ready, stuff like that can easily use other thread, but not the actual widgets.
Better design would be to create the widget when you need it. Or just have one widget and update the data it displays (unless widgets for different items are actually different).
If you are worried about performance when scrolling, then one solution to that is to switch widget only after current one has been visible for some minimum time (say, 500ms if user keeps scrolling, or 200ms after last scroll event, some logic like that) note that this is not delay for reacting to user selection, this is delay after selection and visible widget change, so if user just changes to next item, GUI is updated immediately. But in scrolling the widget is not updated for every item briefly selected, and things don't slow down. Use QTimer or two to send signal when widget should be updated.