Starting thread in OnInitDialog()
-
Hi Is it not allowed to start a thread in CDialog?Why isnt the below code working?(where IDC_GRAPH_FRAME is a picture control of Frame type)Please enlighten. Thanks.
UINT PlotAttenuationThread(LPVOID pParam) { CWnd* gFrame = (CWnd*)GetDlgItem(IDC_GRAPH_FRAME); CDC* pDC = gFrame->GetDC(); ReleaseDC(pDC); return 0; } BOOL CGrapDlg::OnInitDialog() { CDialog::OnInitDialog(); AfxBeginThread(PlotAttenuationThread,this); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }
-
Hi Is it not allowed to start a thread in CDialog?Why isnt the below code working?(where IDC_GRAPH_FRAME is a picture control of Frame type)Please enlighten. Thanks.
UINT PlotAttenuationThread(LPVOID pParam) { CWnd* gFrame = (CWnd*)GetDlgItem(IDC_GRAPH_FRAME); CDC* pDC = gFrame->GetDC(); ReleaseDC(pDC); return 0; } BOOL CGrapDlg::OnInitDialog() { CDialog::OnInitDialog(); AfxBeginThread(PlotAttenuationThread,this); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }
raner wrote: Why isnt the below code working? What do you mean? Does it not compile, does it not call your thread function, what? Regards, Alvaro
All you need in this life is ignorance and confidence, and then success is sure. -- Mark Twain
-
Hi Is it not allowed to start a thread in CDialog?Why isnt the below code working?(where IDC_GRAPH_FRAME is a picture control of Frame type)Please enlighten. Thanks.
UINT PlotAttenuationThread(LPVOID pParam) { CWnd* gFrame = (CWnd*)GetDlgItem(IDC_GRAPH_FRAME); CDC* pDC = gFrame->GetDC(); ReleaseDC(pDC); return 0; } BOOL CGrapDlg::OnInitDialog() { CDialog::OnInitDialog(); AfxBeginThread(PlotAttenuationThread,this); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }
There is no problem starting a thread in OnInitDialog(), you just have to be very careful when using MFC objects (particularly objects derived from CWnd) in multiple threads. Anyway, i suspect that here your code isn't compiling (i assume that's what you mean when you said that it doesn't work) because GetDlgItem() doesn't have enough parameters. Since the thread function is a global function, and not a member of CGrapDlg, it does not have access to the member functions of CGrapDlg (and CWnd from where it is derived). This means that when you call GetDlgItem() here, it is actually calling the SDK version, not the CWnd version. The SDK version of GetDlgItem() takes two parameters: the HWND of the dialog box, and then ID of the control. To get around this, you could cast the pParam parameter to a CGrapDlg, and then call the GetDlgItem() member function. However, there are two issues here: 1) This uses CWnd-derived MFC objects in multiple threads, which is error prone. You could get around this by passing in the HWND instead, and calling the SDK directly. 2) By the sound of the thread function name, you are planning to do some drawing within this thread. In general, this is not recommended, as the dialog will also be painting itself (by handling WM_PAINT and WM_ERASEBACKGROUND), and so it is very likely that anything you draw in your thread will never be seen by the user. Dave
-
Hi Is it not allowed to start a thread in CDialog?Why isnt the below code working?(where IDC_GRAPH_FRAME is a picture control of Frame type)Please enlighten. Thanks.
UINT PlotAttenuationThread(LPVOID pParam) { CWnd* gFrame = (CWnd*)GetDlgItem(IDC_GRAPH_FRAME); CDC* pDC = gFrame->GetDC(); ReleaseDC(pDC); return 0; } BOOL CGrapDlg::OnInitDialog() { CDialog::OnInitDialog(); AfxBeginThread(PlotAttenuationThread,this); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }
Use this code:
BOOL CGrapDlg::OnInitDialog()
{
CDialog::OnInitDialog();AfxBeginThread(PlotAttenuationThread, this); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE
}
UINT PlotAttenuationThread(LPVOID pParam)
{
CGraphDlg* pDlg=(CGraphDlg*) pParam;
CWnd* gFrame = (CWnd*)pDlg->GetDlgItem(IDC_GRAPH_FRAME);
CDC* pDC = gFrame->GetDC();
ReleaseDC(pDC);return 0;
}
A. Riazi
-
Hi Is it not allowed to start a thread in CDialog?Why isnt the below code working?(where IDC_GRAPH_FRAME is a picture control of Frame type)Please enlighten. Thanks.
UINT PlotAttenuationThread(LPVOID pParam) { CWnd* gFrame = (CWnd*)GetDlgItem(IDC_GRAPH_FRAME); CDC* pDC = gFrame->GetDC(); ReleaseDC(pDC); return 0; } BOOL CGrapDlg::OnInitDialog() { CDialog::OnInitDialog(); AfxBeginThread(PlotAttenuationThread,this); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }
One problem you should be seeing is that the thread function is not a member function of CGrapDlg so you can't call GetDlgItem. Also what Dave has posted regarding the use of MFC objects accross threads is a problem that cannot be ignored. There are Technical Notes on MSDN regarding this problem. "No matter where you go, there your are..." - Buckaoo Banzi <pete/>
-
raner wrote: Why isnt the below code working? What do you mean? Does it not compile, does it not call your thread function, what? Regards, Alvaro
All you need in this life is ignorance and confidence, and then success is sure. -- Mark Twain
-
There is no problem starting a thread in OnInitDialog(), you just have to be very careful when using MFC objects (particularly objects derived from CWnd) in multiple threads. Anyway, i suspect that here your code isn't compiling (i assume that's what you mean when you said that it doesn't work) because GetDlgItem() doesn't have enough parameters. Since the thread function is a global function, and not a member of CGrapDlg, it does not have access to the member functions of CGrapDlg (and CWnd from where it is derived). This means that when you call GetDlgItem() here, it is actually calling the SDK version, not the CWnd version. The SDK version of GetDlgItem() takes two parameters: the HWND of the dialog box, and then ID of the control. To get around this, you could cast the pParam parameter to a CGrapDlg, and then call the GetDlgItem() member function. However, there are two issues here: 1) This uses CWnd-derived MFC objects in multiple threads, which is error prone. You could get around this by passing in the HWND instead, and calling the SDK directly. 2) By the sound of the thread function name, you are planning to do some drawing within this thread. In general, this is not recommended, as the dialog will also be painting itself (by handling WM_PAINT and WM_ERASEBACKGROUND), and so it is very likely that anything you draw in your thread will never be seen by the user. Dave
regarding issue 2...i need some calculations to know what to draw and i thought if these had to be performed each time WM_PAINT is sent, it'll take a long time. That's why i placed the functions under OnInitDialog(). But after thinking through what you pointed out to me, maybe i should do the calculations in OnInitDialog() and the final display in OnPaint()? thanks alot...i didnt know a thread is a global function before.;P