troubleshooting Question

MFC UpdateData and Threading problems

Avatar of deafie_sb
deafie_sb asked on
System ProgrammingMicrosoft DevelopmentEditors IDEs
23 Comments1 Solution3089 ViewsLast Modified:
Im having a weird problem with a MFC Dialog program Im writing and I cannot find a good solution. Im hoping someone might have an answer.

The problem is with the UpdateData function when new data is to be placed on in the dialog panel called PanelDlg. Im running two threads that are IDENTICAL in every aspect, except on which channel it should be reading

I have two worker threads that I am constantly running because it needs to listen at a PCI card for incoming data. Both the thread and the main Dialog classes are using DLLIMPORT functions: the worker threads to LISTEN and send a message when incoming data is being recieved from a channel, and within the Dialog panel itself, read the data and update the screen.

Some notes:

CH1_text and CH2_text are CString variables and they are connected to the dialog box by using:

      DDX_Text(pDX, CH1_INCOMING, CH1_text);
      DDX_Text(pDX, CH2_INCOMING, CH2_text);

And CH1_INCOMING and CH2_INCOMING are RichEdit boxes on the dialog panel.

Also you may notice that while I am passing WPARAM and LPARAM back to the main Dialog class, no data is being sent. This is because I only want to raise the event and have the functions themselves recieve the data and then update as it is written in onFlag1 and onFlag2 functions of the dialog class.

The threads are working properly and they are indeed firing the correct messages, therefore the functions in PanelDlg are being called correctly as well.

The problem: Only the function onFlag1 will update, but not on the function onFlag2. Ive tried using UpdateData(TRUE) and without it, but I get the same results.

Does any one have any ideas on what Im doing wrong?

Steve


------ global.h file
 
typedef struct _THREADINFOSTRUCT
{
	HWND hWnd;
	CString cString;
} THREADINFOSTRUCT;
 
 
------ PanelDlg.cpp file:
 
THREADINFOSTRUCT *myStruct = new THREADINFOSTRUCT;
 
 
PanelDlg::DoDataExchange(CDataExchange* pDX)
{
// Some code here...
 
BEGIN_MESSAGE_MAP(CSubAssemblyPanelDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
 
	// .... more stuff
 
	ON_MESSAGE(WM_ONFLAG1, onFlag1)
	ON_MESSAGE(WM_ONFLAG2, onFlag2)
 
 
END_MESSAGE_MAP()
}
 
BOOL PanelDlg::OnInitDialog()
{
	// ... some code
 
	MyStruct->hWnd = m_hWnd;
	tis->cString = "Main Dialog Thread";
	s1Thread = AfxBeginThread(s1.ThreadProc1, myStruct, THREAD_PRIORITY_NORMAL,0,0,0);
	s2Thread = AfxBeginThread(s1.ThreadProc2, myStruct, THREAD_PRIORITY_NORMAL,0,0,0);
 
	// ... some code
 
}
 
LPARAM PanelDlg::onFlag1(WPARAM wParam, LPARAM lParam)
 
{
      int count, i;
      char inchar;
      //UpdateData(TRUE);
      NumBytesWaiting(ch1,&count);
      for (i = 0; i < count; i++)
 
      {
            ReceiveByte(ch1, &inchar);
            CH1_text.AppendChar(inchar);
      }
 
      UpdateData(FALSE);      //THIS LINE DOES UPDATE CORRECTLY
      return 0;
}
 
 
LPARAM PanelDlg::onFlag2(WPARAM wParam, LPARAM lParam)
 
{
      int count, i;
      char inchar;
      //UpdateData(TRUE);
 
      NumBytesWaiting(ch2,&count);
      for (i = 0; i < count; i++)
 
      {
            ReceiveByte(ch2, &inchar);
            CH2_text.AppendChar(inData.inchar);
      }
 
      UpdateData(FALSE);    <---DOES NOT UPDATE THE DIALOG BOX! 
 
     return 0;
 
}
 
---- thread.h file
 
#define WM_ONFLAG1 (WM_USER+0x101)
#define WM_ONFLAG2 (WM_USER+0x102)
 
---- thread.cpp file
 
UINT serial1::ThreadProc1(LPVOID lParam)
{
	THREADINFOSTRUCT *tis = (THREADINFOSTRUCT*)lParam;
	int status;
	int cnt;
 
	while (true)
	{
		// TODO: add code here
		
		status = Wait_For_Interrupt(ch1, 100); // channel 1 for 100 msec
 
		if (status >= 0)
		{
			NumBytesWaiting_SER(serial_ch0,&cnt);
			if (cnt > 0)
				PostMessage(tis->hWnd,WM_ONFLAG1,0,0);
 
		}
	}
 
	return 0;
}
 
UINT serial1::ThreadProc2(LPVOID lParam)
{
	THREADINFOSTRUCT *tis = (THREADINFOSTRUCT*)lParam;
	int status;
	int cnt;
 
	while (true)
	{
		// TODO: add code here
		
		status = Wait_For_Interrupt(ch2, 100);  // channel 2 for 100 msec
 
		if (status >= 0)
		{
			NumBytesWaiting_SER(serial_ch0,&cnt);
			if (cnt > 0)
				PostMessage(tis->hWnd,WM_ONFLAG2,0,0);
 
			 
		}
	}
 
	return 0;
}
Join the community to see this answer!
Join our exclusive community to see this answer & millions of others.
Unlock 1 Answer and 23 Comments.
Join the Community
Learn from the best

Network and collaborate with thousands of CTOs, CISOs, and IT Pros rooting for you and your success.

Andrew Hancock - VMware vExpert
See if this solution works for you by signing up for a 7 day free trial.
Unlock 1 Answer and 23 Comments.
Try for 7 days

”The time we save is the biggest benefit of E-E to our team. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange.

-Mike Kapnisakis, Warner Bros