-1

I have a working GUI and now need to add some code that will need to run continuously and update the GUI with data. Where should this code go? I know that it should not go into the message loop because it might block incoming messages to the window, but I'm confused on where in my window process this code could run.

Philip Pittle
  • 11,821
  • 8
  • 59
  • 123

2 Answers2

2

You have a choice: you can use a thread and post messages back to the main thread to update the GUI (or update the GUI directly, but don't try this if you used MFC), or you can use a timer that will post you messages periodically, you then simply implement a handler for the timer and do whatever you need to there.

The thread is best for a complicated, slow process that might block. If the process of getting data is quick (and/or can be set to timeout on error) then a timer is simpler.

gbjbaanb
  • 51,617
  • 12
  • 104
  • 148
  • I don't know why having used MFC would matter. The Win32 UI is fundamentally single-threaded. Posting a message would be the appropriate thing to do either way. – Cody Gray - on strike Aug 15 '14 at 15:53
  • I just couldn't remember if it was going to work with posting messages to a win32 wndproc from a thread, I do know that MFC will barf horribly if you try to call GUI update methods in a thread though. – gbjbaanb Aug 15 '14 at 16:39
  • Thanks, yeah I tried using threads at first but my GUI was very upset so I ended up using a timer...everything works now :) – Heather Savage Aug 15 '14 at 16:59
0

Have you looked into threading at all?

Typically, you would create one thread that performs the background task (in this case, reading the voltage data) and storing it into a shared buffer. The GUI thread simply reads that buffer every so often (on redraw, every 30 seconds, when the user clicks refresh, etc) and displays the data.

Your background thread runs on its own schedule, getting CPU time from the OS, and is not bound to the UI or message pump. It can use some type of timer to monitor the data source and read things in as necessary.

Now, since the threads run separately and may run at the same time, you need to make them aware of one another. This can be done with locks (look into mutexes). For example:

  1. The monitor reads the current voltage and stores it in the buffer.
  2. The background/monitor thread locks the buffer holding the latest sample.
  3. The monitor copies the internal buffer to the shared one.
  4. The monitor unlocks the buffer.

Simultaneously, but separately, the UI thread:

  1. Gets a redraw call.
  2. Waits for the buffer to be unlocked, then reads the value.
  3. Draws the UI with the buffer value.

Setting up a new thread and using it, in most Windows GUI-producing languages, is pretty simple. C/++ and C# both have very simple APIs for creating a new thread and having it work on some task, you usually just need to provide a function for the thread to process. See the MSDN docs on CreateThread for a C example.

The concept of threading and locking is for the most part language-agnostic, and similar in most C-inspired languages. You'll need to have your main (in this case, probably UI) thread control the lifetime of the worker: start the worker after the UI is created, and kill it before the UI is shut down.

This approach has a little bit of overhead up front, especially if your data fetch is very simple. If your data source changes (a network request, some blocking data source, reading over actual wires from a physical sensor, etc) then you only need to change the monitor thread and the UI doesn't need to know.

ssube
  • 47,010
  • 7
  • 103
  • 140
  • Thanks, I tried using threads (I have never actually used threads before) but my GUI was upset (hard to explain, nothing would show on the page...) So I took them out and used a timer mentioned in gbjbannb answer I feel like threads would be the correct way to implement this continuous updating...Guess I need to read more about threads to fully understand why nothing worked – Heather Savage Aug 15 '14 at 17:03