【问题标题】:Send return value to dialog from thread MFC从线程 MFC 向对话框发送返回值
【发布时间】:2013-10-08 15:59:57
【问题描述】:

我正在使用 do modal 创建对话框:

MainHamsterDlg MainHamsterDlg;
 if (MainHamsterDlg.DoModal() == IDCANCEL)
 break;

然后在该对话框中创建工作线程:

BOOL MainHamsterDlg::OnInitDialog()
    {
        AfxBeginThread(WorkerThreadProc, m_hWnd, THREAD_PRIORITY_NORMAL, 0, 0, NULL);
        CDialogEx::OnInitDialog();

        return TRUE;
    }

线程必须通过发送返回值 IDCANCEL 来退出对话框。

    UINT WorkerThreadProc(LPVOID Param) //Sample function for using in AfxBeginThread
    {
        Sleep(1000); // process simulation
        MainHamsterDlg * self = (MainHamsterDlg *)Param;
        self->EndDialog(IDCANCEL);
        return FALSE;
    }

编译时我没有收到任何错误。处理时,然后进入重点:

self->EndDialog(IDCANCEL);

错误信息:

Unhandled exception at 0x01503AD4 in L2Hamster.exe: 0xC0000005:
Access violation reading location 0x00000020.

指向我的 dlgcore.cpp 文件:

void CDialog::EndDialog(int nResult)
{
    ASSERT(::IsWindow(m_hWnd)); <<<<<===== to that line

    m_bClosedByEndDialog = TRUE;

    if (m_nFlags & (WF_MODALLOOP|WF_CONTINUEMODAL))
        EndModalLoop(nResult);

    ::EndDialog(m_hWnd, nResult);
}

我不知道我做错了什么。有什么解决办法吗?

【问题讨论】:

  • 我只会将窗口句柄传递给线程,然后在完成后让线程 PostMessage 将 WM_COMMAND IDCANCEL 传递给该句柄,以便仅在主消息队列上处理窗口处理。跨度>
  • 你可以发布一些示例代码吗?
  • 现在我仔细查看了您的代码...看来您没有在 AfxBeginThread pParam 参数中发送任何内容...将 hWnd 放在那里。另外,在您的示例中,线程立即结束......您的线程可能在窗口完全创建之前结束。 PostMessage(hWnd, WM_COMMAND, IDCANCEL, 0);
  • 我编辑了一点代码,你能再看一遍吗? PostMessage(hWnd,WM_COMMAND,IDCANCEL,0);如何发送到线程 hWnd
  • UINT WorkerThreadProc(LPVOID 参数) { Sleep(1000); PostMessage((HWND)参数,WM_COMMAND,IDCANCEL,0);返回错误; }

标签: c++ multithreading mfc


【解决方案1】:

我假设您打算将指向对话框的指针传递给线程进程。但是您改为传递 null:

 AfxBeginThread(WorkerThreadProc, NULL, THREAD_PRIORITY_NORMAL, 0, 0, NULL);

应该是:

 AfxBeginThread(WorkerThreadProc, this, THREAD_PRIORITY_NORMAL, 0, 0, NULL);

您还需要协调线程的结尾和对话框的结尾,以确保在线程结束之前对话框不会被关闭。 (我认为这是某种进度对话框)。

【讨论】:

  • 我通过将 m_hWnd 放入线程调用来编辑代码,但仍然出现相同的错误。
  • @klasik,如果要转换为 CDialog,则需要将 this 传递给线程。
【解决方案2】:

这对我来说似乎是个问题:

AfxBeginThread(WorkerThreadProc, NULL, THREAD_PRIORITY_NORMAL, 0, 0, NULL);

紧随其后

UINT WorkerThreadProc(LPVOID Param) //Sample function for using in AfxBeginThread
{
    MainHamsterDlg * self = (MainHamsterDlg *)Param;
        self->EndDialog(IDCANCEL);
    ...
}

这里,ParamNULL,所以 selfNULL。然后你取消引用一个空指针。

【讨论】:

  • 然后编辑转换为 HWND 而不是 MainHamsterDlg *... 然后使用 PostMessage 而不是 self->EndDialog
猜你喜欢
  • 1970-01-01
  • 2020-06-27
  • 2012-06-16
  • 1970-01-01
  • 2016-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多