Dialog window won't update display

D

Dave Cullen

I have a dialog based MFC application (VS2005) that controls an automation
process. There is a worker thread in the background handling some machine
interfaces. The main thread provides status displays via static text boxes
and UpdateData(FALSE). The worker thread does not write to the window.

Sometimes the window will not update the display. The process keeps running,
so I know both threads are working. Strangely, if I pop up a standard
MessageBox for operator yes/no input the window will update it's display
after the messagebox closes and continue to update normally from that point
on.

I've interspersed calls to RedrawWindow() at various points within the main
loop with no apparent improvement. Is there anything else I can do to insure
the window updates the display? And why would popping up a messagebox make
everything start working?

Thanks
drc
 
S

Scott McPhillips [MVP]

Dave Cullen said:
I have a dialog based MFC application (VS2005) that controls an automation
process. There is a worker thread in the background handling some machine
interfaces. The main thread provides status displays via static text boxes
and UpdateData(FALSE). The worker thread does not write to the window.

Sometimes the window will not update the display. The process keeps
running, so I know both threads are working. Strangely, if I pop up a
standard MessageBox for operator yes/no input the window will update it's
display after the messagebox closes and continue to update normally from
that point on.

I've interspersed calls to RedrawWindow() at various points within the
main loop with no apparent improvement. Is there anything else I can do to
insure the window updates the display? And why would popping up a
messagebox make everything start working?

Thanks
drc


When you pop up a message box it runs a message loop, which lets other
messages through to your main application. If updates don't happen until
you display the message box that is an indication that your main application
is not running its message loop. You also mention your "main loop," which is
suspicious. If your main thread is in a loop then the design is wrong. It
should consist of message handling functions that always return promptly (to
the MFC message loop). Your displays cannot update while your main thread
code is looping.
 
D

David Lowndes

I have a dialog based MFC application (VS2005) that controls an automation
process. There is a worker thread in the background handling some machine
interfaces. The main thread provides status displays via static text boxes
and UpdateData(FALSE). The worker thread does not write to the window.

Dave,

How does the worker thread communicate the updated data to the main UI
thread (I'm assuming it does somehow)?
Sometimes the window will not update the display.

Any idea what the "sometimes" situation is - is it just time the
application has been running, or perhaps after some other action on
the machine?
The process keeps running,
so I know both threads are working.

Is the worker/gui thread communication working though?
Strangely, if I pop up a standard
MessageBox for operator yes/no input the window will update it's display
after the messagebox closes and continue to update normally from that point
on.

Do you have any timers in your application? Are they perhaps not
occurring when the "sometimes" situation arises? When a messagebox is
displayed, the message processing is done in a separate message
dispatch loop - not the loop in your application. Quite why it has the
effect it does is difficult to guess, but undoubtedly it'll make more
sense when you discover the root of the problem.

Can you reproduce the problem with a debug build, and while debugging?
If you can, a few trace points in the code at strategic places may
shed some light onto the problem.
I've interspersed calls to RedrawWindow() at various points within the main
loop with no apparent improvement.

As you've found, things like that are not going to be the answer -
best to discover what's really going on and solve it properly.

Dave Lowndes
 
D

Dave Cullen

Dave,
How does the worker thread communicate the updated data to the main UI
thread (I'm assuming it does somehow)?

Data is passed via CCriticalSection synchronization, using the lock feature.
I have a class object CSharedData that provides interfaces to set and get
the data structure that's passed between threads:
class CSharedData
{
public:
CCriticalSection m_CritSection; // used for synchronization
CSharedData(void); // constructor
int GetSharedData(shared_data* outdata); // get data from class
int SetSharedData(shared_data indata); // set data in class
private:
shared_data m_Data; // private member data
};
Any idea what the "sometimes" situation is - is it just time the
application has been running, or perhaps after some other action on
the machine?

"Sometimes" is actually "always" - from the time that the worker thread is
started (via AfxBeginThread). The worker thread is in a do-while checking
the shared data for a command to execute. The main thread (dialog method)
sends the command and waits for completion. After that it will update the
contents of the display (static text boxes with CString variables) and
UpdateData(FALSE). If the operator presses the machine's pause button I pop
up a "Quit Y/N" message box and the display will update as expected from
that point on.
Is the worker/gui thread communication working though?

Data is being passed correctly both ways, so... yes?
Do you have any timers in your application? Are they perhaps not
occurring when the "sometimes" situation arises? When a messagebox is
displayed, the message processing is done in a separate message
dispatch loop - not the loop in your application. Quite why it has the
effect it does is difficult to guess, but undoubtedly it'll make more
sense when you discover the root of the problem.

No timers.
Can you reproduce the problem with a debug build, and while debugging?

The debug version does not exhibit the symptoms. Maybe that's a clue..

I can't run the machine from my development PC, so I bypass the machine
control functions in debug. The hardware control dll's are still there but I
don't call into them. Gotta think about this some more.

Thanks for the insight.

Dave C
 
D

David Lowndes

"Sometimes" is actually "always" - from the time that the worker thread is
started (via AfxBeginThread).

Ah, so whatever you're doing doesn't work properly at all.
The worker thread is in a do-while checking
the shared data for a command to execute. The main thread (dialog method)
sends the command and waits for completion. After that it will update the
contents of the display (static text boxes with CString variables) and
UpdateData(FALSE).

What's it do after calling UpdateData? Does it perhaps issue the next
command and then "wait"? What is it doing while it waits? i.e. what is
the wait mechanism? For a GUI to perform properly it should not really
be waiting for anything - other than it's normal message processing
loop, which is largely hidden from you in an MFC application.
The debug version does not exhibit the symptoms. Maybe that's a clue..

Yes, there's something amiss going on there then. You can debug your
release build - but it's often difficult because there's no guarantee
the debugger will show the correct values for variables.

Dave
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top