从MMP中的WorkerThread到主窗口的PostMessage

Muh*_*mar 7 user-interface mfc multithreading postmessage worker-thread

我有一个MFC应用程序,它有一个工作线程,我想要做的是将消息从工作线程发布到主GUI线程,以更新GUI上的一些状态消息.到目前为止我所做的是Registered a new window message

//custom messages
static UINT FTP_APP_STATUS_UPDATE = ::RegisterWindowMessageA("FTP_APP_STATUS_UPDATE");
Run Code Online (Sandbox Code Playgroud)

将此消息添加到对话框类的消息映射中

ON_MESSAGE(FTP_APP_STATUS_UPDATE, &CMFC_TestApplicationDlg::OnStatusUpdate)
Run Code Online (Sandbox Code Playgroud)

原型OnStatusUpdate是

afx_msg LRESULT OnStatusUpdate(WPARAM, LPARAM);
Run Code Online (Sandbox Code Playgroud)

和定义是

LRESULT CMFC_TestApplicationDlg::OnStatusUpdate(WPARAM wParam, LPARAM lParam)
{

     //This function is not called at all.
     return 0;
}
Run Code Online (Sandbox Code Playgroud)

而工作线程调用代码是

void CMFC_TestApplicationDlg::OnBnClickedMfcbutton1()
{
    ThreadParams params;
    params.m_hWnd = m_hWnd;
    params.FTPHost = "test_host";
    params.FTPUsername = "test";
    params.FTPPassword = "test";

    AfxBeginThread(FTPConnectThread,&params);
}
Run Code Online (Sandbox Code Playgroud)

和Worker线程代码是

//child thread function
UINT FTPConnectThread( LPVOID pParam )
{
    if(pParam == NULL)
    {
        return 0;
    }
    ThreadParams *params = (ThreadParams*)pParam;
    OutputDebugString(params->FTPHost);
    Sleep(4000); //simulating a network call
    CString * message = new CString("Conencted");
    PostMessage(params->m_hWnd,FTP_APP_STATUS_UPDATE,0,(LPARAM)message);
    //PostMessage do nothing? what I am doing wrong?
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

问题是当调用PostMessage函数时OnStatusUpdate应该调用它,但它没有被调用,没有抛出异常或断言,我做错了什么?我曾尝试ON_REGISTERED_MESSAGE和ON_MESSAGE,但没有成功,任何帮助吗?

Dar*_*con 5

CMFC_TestApplicationDlg::OnBnClickedMfcbutton1()可以在线程开始之前返回.这会导致您ThreadParams超出范围,因此当您从线程访问它时,您正在访问释放的内存.您需要以其他方式分配它,例如:

void CMFC_TestApplicationDlg::OnBnClickedMfcbutton1()
{
    ThreadParams* params = new ThreadParams();
    params->m_hWnd = m_hWnd;
    params->FTPHost = "test_host";
    params->FTPUsername = "test";
    params->FTPPassword = "test";

    AfxBeginThread(FTPConnectThread,params);
}

//child thread function
UINT FTPConnectThread( LPVOID pParam )
{
    if(pParam == NULL)
    {
        return 0;
    }

    ThreadParams *params = (ThreadParams*)pParam;
    OutputDebugString(params->FTPHost);
    Sleep(4000); //simulating a network call
    CString * message = new CString("Conencted");
    PostMessage(params->m_hWnd,FTP_APP_STATUS_UPDATE,0,(LPARAM)message);

    delete params;
    return 1;
}
Run Code Online (Sandbox Code Playgroud)