Discussion:
How to run a dialog box without halting a thread?
(too old to reply)
Electronic75
2008-08-09 18:16:01 UTC
Permalink
Hello, I have a Doc/View MFC application that acquires data from an
instrument and processes it and displays it. Now I want to add a calibration
dialog box. In this dialog box user changes position of various slide bars
and spin controls to calibrate the instrument. the problems is I need while
dialog box is open it be able to get response values from instrument but
while the thread has opened the dialog box how it can simultaneously process
incoming data and present it to dialog box to be shown to the user?

thanks
David Lowndes
2008-08-09 23:07:32 UTC
Permalink
Post by Electronic75
Hello, I have a Doc/View MFC application that acquires data from an
instrument and processes it and displays it. Now I want to add a calibration
dialog box. In this dialog box user changes position of various slide bars
and spin controls to calibrate the instrument. the problems is I need while
dialog box is open it be able to get response values from instrument but
while the thread has opened the dialog box how it can simultaneously process
incoming data and present it to dialog box to be shown to the user?
Often the best approach is to have any data gathering operation run in
a separate worker thread and have the worker thread communicate its
data back to the UI thread by posting messages to a window of that
thread.

Dave
Electronic75
2008-08-10 07:05:00 UTC
Permalink
Post by David Lowndes
Often the best approach is to have any data gathering operation run in
a separate worker thread and have the worker thread communicate its
data back to the UI thread by posting messages to a window of that
thread.
Dave
Hello Dave, thanks a lot. I put data gathering operations in a separate
thread so now I have 2 separate threads, one that gathers data and pours them
in a data queue and another main thread that reads from the data queue and
displays the data.
I have synchronized them using CCriticalSection.
Now I have added the calibration dialog box to the main thread but to read
responses from my device I need to run a function(ReadDataQueue()) from main
thread that reads the data queue and for that I initialized a pointer in my
calibration dialog box to CDocument class of main thread also in my
calibration dialog box I added a timer which upon calling it will run
ReadDataQueue() from CDocument class(using the supplied pointer) that is
responsible for reading the data queue.
Problem is whenever calibration dialog box tries to invoke ReadDataQueue()
which is responsible for reading the data queue, program gives memory
violation(can't access memory...). using call stack I tried to find what
causes this memory violation and I found out at the beginning of
ReadDataQueue() it has this line
CSingleLock slData(&m_csDataQueue).
m_csDataQueue is CCriticalSection defined in header.
After running this line, this function is called from ObjectCore.cpp
BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const
and in this function it calls GetRuntimeClass() which causes memory violation.
how can I solve this? am I going at right direction?
thanks
David Lowndes
2008-08-10 13:01:42 UTC
Permalink
Post by Electronic75
Hello Dave, thanks a lot. I put data gathering operations in a separate
thread so now I have 2 separate threads, one that gathers data and pours them
in a data queue and another main thread that reads from the data queue and
displays the data.
I have synchronized them using CCriticalSection.
OK, one simplification - you could have it to use the Windows message
queue as your queue. Have your worker thread allocate memory for the
data and post a message to the window that will process the data. That
way you're not writing your own (often problematic) synchronisation
code.
Post by Electronic75
Now I have added the calibration dialog box to the main thread but to read
responses from my device I need to run a function(ReadDataQueue()) from main
thread that reads the data queue and for that I initialized a pointer in my
calibration dialog box to CDocument class of main thread also in my
calibration dialog box I added a timer which upon calling it will run
ReadDataQueue() from CDocument class(using the supplied pointer) that is
responsible for reading the data queue.
Problem is whenever calibration dialog box tries to invoke ReadDataQueue()
which is responsible for reading the data queue, program gives memory
violation(can't access memory...). using call stack I tried to find what
causes this memory violation and I found out at the beginning of
ReadDataQueue() it has this line
CSingleLock slData(&m_csDataQueue).
m_csDataQueue is CCriticalSection defined in header.
After running this line, this function is called from ObjectCore.cpp
BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const
and in this function it calls GetRuntimeClass() which causes memory violation.
I can't imagine what your code is doing, you'd have to show more than
you have.

Dave
Electronic75
2008-08-10 16:12:00 UTC
Permalink
Hi Dave Thanks, previous problem solved that was because I had called a modal
dialog box while I had to call a modeless dialog box.
Now my problem is How can I send a message from this dialog box to CDocument
class. In CDocument class that I create this calibration dialog box I've
assigned its parent the CView associated with CDocument(I have only one view)
This is code
void CMyDoc::OnCommandsCalibrate()
{
bool res;
POSITION pos = GetFirstViewPosition();

res = m_dlgCalibrate.Create(IDD_CALIBRATE, GetNextView(pos));
if(!res)
AfxMessageBox(_T("Error Creating Dialog Box"));
m_dlgCalibrate.ShowWindow(SW_SHOW);
}
So when in this calibration dialog box I executed
PostMessage(WM_CAL_COMMAND);
I expected it is routed to CMyView
I have put this in CMyView Message map
ON_MESSAGE(WM_CAL_COMMAND, CMyView::OnNewCalCommand)
I also have defined handler function as:
afx_msg LRESULT OnNewCalCommand(WPARAM, LPARAM);
but this message won't reach to CMyView let alone CMyDoc
but I could grab it in CMainFrame class(I use SDI) using similar code(I only
executed AfxGetMainWnd()->PostMessage(WM_CAL_COMMAND) in dialog box in this
case). Is there anyway so I can post this message to CMyDoc directly or at
least to CMyView?
Thanks
David Lowndes
2008-08-11 13:35:33 UTC
Permalink
Post by Electronic75
Now my problem is How can I send a message from this dialog box to CDocument
class.
That's not a natural thing to want to do.
Post by Electronic75
In CDocument class that I create this calibration dialog box I've
assigned its parent the CView associated with CDocument(I have only one view)
Dialog parents are usually the frame window.
Post by Electronic75
This is code
void CMyDoc::OnCommandsCalibrate()
{
bool res;
POSITION pos = GetFirstViewPosition();
res = m_dlgCalibrate.Create(IDD_CALIBRATE, GetNextView(pos));
if(!res)
AfxMessageBox(_T("Error Creating Dialog Box"));
m_dlgCalibrate.ShowWindow(SW_SHOW);
}
OK, you've created a modeless dialog.
Post by Electronic75
So when in this calibration dialog box I executed
PostMessage(WM_CAL_COMMAND);
I expected it is routed to CMyView
Why? You've not specified the window so it'll be posted to the "this"
window (i.e. the dialog itself).
Post by Electronic75
but I could grab it in CMainFrame class(I use SDI) using similar code(I only
executed AfxGetMainWnd()->PostMessage(WM_CAL_COMMAND) in dialog box in this
case). Is there anyway so I can post this message to CMyDoc directly or at
least to CMyView?
Use GetParent()->PostMessage.

Dave
Electronic75
2008-08-12 04:15:00 UTC
Permalink
Hi Dave,
well my assumption is when one post a message to a dialog box window it will
be automatically routed to its parent window. I read this in MSDN if you
post a message to a dialog box it will be posted to:
1-This dialog box
2-Window that owns the dialog box
3-Application (CWinApp object)
so I expected it be posted to parent view but wait a minute even
GetParent()->PostMessage(...) didn't send message to the view that owns the
dialog box. maybe that's because what you said earlier that parent of a
dialog box should be a frame window and a view can't be a parent?
Regards,
David Lowndes
2008-08-12 06:19:15 UTC
Permalink
Post by Electronic75
well my assumption is when one post a message to a dialog box window it will
be automatically routed to its parent window. I read this in MSDN if you
1-This dialog box
2-Window that owns the dialog box
3-Application (CWinApp object)
That's MFC's command message routing (for WM_COMMAND messages), not
for user defined messages.
Post by Electronic75
so I expected it be posted to parent view but wait a minute even
GetParent()->PostMessage(...) didn't send message to the view that owns the
dialog box. maybe that's because what you said earlier that parent of a
dialog box should be a frame window and a view can't be a parent?
I didn't say it couldn't be the parent, only that it's more normal to
use the frame.

Debug it and check what window you have passed as the parent, and what
window GetParent returns. You may need to use GetOwner instead.

Dave

Loading...