in Programming

Using AfxBeginThread for multi-thread in VS C++

Summary

Create a separate thread as the worker thread, which can process time consuming task like printing, computation, etc., here I am using the new thread to process the interactive with the smart card, this mechanism can enable the application to response to user’s other action (requests to user interface), such as move the window, drag the scroll bar, etc.

Two tricks about multi-thread

Controlling function must be global or static

Microsoft wants the controlling function either to be a global function or to be a static class member function, so you cannot access to your class member variables or methods from within the controlling function. This can be resolved by pass the application pointer into AfxBeginThread function as the 2nd parameter.

Multithreading must be enabled by the application

Remember to enable multithreading compiler option in the Visual Studio, otherwise this function will fail.

Example

AfxBeginThread function

AfxBeginThread is to create new thread, I’m using two parameters, first to point to the controlling function for the worker thread, 2nd as the application pointer parameter to be passed to the controlling function.

Code Example

1, APDURunDlg.h, to declare the worker thread function

public:
    //structure for passing to the controlling function
    typedef struct _MultiCardThreadParam
    {
        CWnd * wndHandler;
    } MultiCardThreadParam;

    MultiCardThreadParam m_mctParam;
    static UINT RunCardThread(LPVOID param);    
    ......

2, APDURunDlg.cpp

void CAPDURunDlg::OnBnClickedRun()
{
    // TODO: Add your control notification handler code here
    //call the thread on a button click, pass the current application pointer into the worker thread function.
    m_mctParam.wndHandler = this;

    AfxBeginThread(RunCardThread,(LPVOID)&m_mctParam);
    ......
UINT CAPDURunDlg::RunCardThread(LPVOID pVal)
{
    MultiCardThreadParam * param = (MultiCardThreadParam *) pVal;
    CAPDURunDlg *dlg = (CAPDURunDlg *)param->wndHandler;

    //below code shows to access to the class member variables or methods from within the controlling function will require to use the "dlg" pointer passed in...
    //make sure the file to execute to be selected!
    if(dlg->m_edtDataSource.GetWindowTextLength() == 0 )
    {
        AfxMessageBox(_T("Please select the file to execute!"));
        dlg->GetDlgItem(IDC_BROWSE)->SetFocus();
        return 0;
    }
    ......

Write a Comment

Comment