Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Worker Thread vs. User Thread 2

Status
Not open for further replies.

bluecrush

Programmer
Mar 26, 2004
61
US
Have mercy on the newbie...

I've developed a worker thread that functions flawlessly within my dlg-based app. However, I've decided I want to have a progress bar that gives an indication of the thread's progress. I've tried to put the progress bar on the main dlg but can't figure out how to StepIt() from within my thread. Is there a way I can communicate from within my static UINT Dlg::Thread(pParam) function to update the progress bar?
 
Your thread function should take an LPVOID, right? In the function to create the thread, you should be able to pass an LPVOID that the function will recieve. Just pass "this", and type cast it back to your dialog class first thing in the thread. This will give you access to your dialog and anything it contains, including the progress bar.
 
Beautiful! Thank you.

Do I need to type case my member variables as well to be able to access the data in them? Currently I am trying to access a CString in a text field and when I run it under debug and put a watch on it, it says it "Error: cannot display value.
 
You shouldn't need to, but the debugger does seem to have problems calling methods in the debugger for some reason. If it's a CString member of the class, you shouldn't have any problems getting it from the debugger if you cast it as shown here. If you need to call a method from the debugger, that will be slightly harder - you might have to call it in the code to put it in a variable and just check the value with the debugger. Here's how to cast it:

UINT CMyClass::HandleThread(LPVOID lp)
{
CMyClass* pClass = (CMyClass*) lp;

// Do whatever you need to do here
pClass->m_strSomeString = "Hello";
// Using pClass->m_strSomeString in the debugger should work fine

// other stuff

return 0;
}
 
Thank you! It's working like a charm...and the debugger doesn't mind it either! [thumbsup]
 
Okay, "charm" may be a bit of an overstatement...

I can access and manipulate the members but, like you said, the methods are being problematic...specifically the UpdateData() method. Any ideas?
 
Okay, I've tracked the assert to passing "this" to the thread...it doesn't like it! From what I can gather, I need to pass an HWnd object. Am I on the right track???
 
No, passing "this" should be fine. Several different methods can be problematic, as you have discovered. There may be a better way of solving this than what I have done in the past, but I can tell you a way that I know works. First, #define some big number like this so it won't conflict with any WMs:

#define MY_UPDATE_DATA_MESSSAGE 100000001

Then override PreTranslateMessage to do this:

BOOL CMyClass::preTranslateMessage(MSG* pMsg)
{
switch(pMsg->message == MY_UPDATE_DATA_MESSSAGE)
{
case MY_UPDATE_DATA_MESSAGE:
pSomething->UpdateData();
return TRUE;
//additional cases if necessary
}
return CView::preTranslateMessage(pMsg);
}

When you need to update data on the control, do this:
pClass->PostMessage(MY_UPDATE_DATA_MESSAGE);
The main window should do it ASAP.

Like I said, this probably isn't the best way of doing things, but it has worked for me in the past and I don't know how else to do it.
 
Yes, it's been awhile, but I have good news! Like you, I'm not sure if it's the best way to do it, but heck -- It works! The only thing I had to do differently was to pass a pointer pClass as a param in PostMessage, re-cast it in PreTranslateMessage and ba-da-boom ba-da-bing...

Thank you for your help!
 
i have been trying to launch my dialog box(with a progress bar on it) in user thread(derived the class from CWinThread)... It works fine for the functionality part except that when i try to set the posof the progressbar and stepit , it gives an exception as the parent window is not set. (CWnd =???)..
Can anyone throw some idea to solve the same..!!
 
Keep in mind that the MFC classes are not thread safe (unless you add mutexes etc yourself).

Windows handles can however safely be passed across threads. To post a message across threads use the PostThreadMessage function.
So...in your working thread post messages to the GUI, in the GUI process the messages and do whatever.

I would recommend you to not pass "this" across the threads. It could get bad if you call its methods from the working thread since there is no thread safety mechanisms involved.


/Per

"It was a work of art, flawless, sublime. A triumph equaled only by its monumental failure."
 
Thanks.. but i have the class derived from the Cwinthread which makes it thread safe..
I have made a dialog box(not derived it fron CDialog) with a progress bar on it.
i donn have any main dlg window(the thread is in a windows service)The problem is that to call a dialog box in the thread i hav to derive it form CWinThread (IMPLEMENT DYNAMIC) and not from CDialog .. And i have tried giving the dialog box both NULL and Desktop Handle in the CreateDialog(hinst,MAKEINTRESOURCE(IDD_PROGRESSDIALOG),hWndDEsk/NULL,GoToProc) but both does not work!! GetDlgitem gives me the progessbar handle but when i try to set the progress Setpos() the application crashes.Hope this clears the situation i am in .. Still trying to find a way out!
 
>the class derived from the Cwinthread which makes it thread safe

Deriving from CWinThread doesn't necessarily make it thread safe.

>Still trying to find a way out!

You try by only posting messages as I suggested.


/Per

"It was a work of art, flawless, sublime. A triumph equaled only by its monumental failure."
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top