问题需求:在主界面显示数据信息之间添加一个显示进度窗口,进度条滚动的同时进行一些复杂数学运算,一旦计算完成马上结束显示进度的窗口(即使进度条没有到达100%),然后出现主界面并显示计算结果。要求用多线程实现。
    这是项目中的一个特殊的需求,研究很长时间都没有结果,最后用其他方法现实的,但仍然耿耿于怀,还望对多线程比较有造诣的各位朋友不吝赐教!我的思路是:
(1)在BOOL CDlgTestApp::InitInstance()中开启一个UI线程完成计算工作,并在主线程中创建进度条滚动窗口,如下BOOL CDlgTestApp::InitInstance()
{
   .....
         // CMyThread继承自CWinThread
m_pThread = (CMyThread*)AfxBeginThread(RUNTIME_CLASS(CMyThread));
Sleep(500);
m_pThread->PostThreadMessage(WM_CALCULATE, NULL, NULL); // 给UI线程发送消息,指示可以开始计算了           
         // 创建显示进度条的窗口,CCheckStart是对应的对话框类
CCheckStart *pCheckStart = new CCheckStart;
pCheckStart->Create(IDD_DLG_START, NULL);
pCheckStart->SvrSetRange(0, 2000);
pCheckStart->ShowWindow(SW_SHOW);
pCheckStart->UpdateWindow();

DWORD dwSpan = 0;
DWORD dwOld  = GetTickCount();
while (dwSpan < 2000 && bWaitting)   // bWaitting是指示UI线程计算完后不再继续循环,
{
dwSpan = GetTickCount() - dwOld;
pCheckStart->SetProgressPos(dwSpan);
pCheckStart->UpdateWindow();
}
delete pCheckStart;
pCheckStart = NULL; int nResponse = dlg.DoModal();   ......
}(2)CMyThread中的消息处理函数(WM_CALCULATE消息)afx_msg void CMyThread::OnCalculate(WPARAM wParam, LPARAM lParam)
{
int nTemp = 1;
for (int i = 0; i < 10; i++)
{
nTemp *= 2;
Sleep(100);
}
if (TRUE == CDlgTestApp::bWaitting)
{
CDlgTestApp::bWaitting = FALSE; // 修改滚动条滚动标识
}         
         // 将计算结果发送给主对话框
::PostMessage((HWND)(GetMainWnd()->GetSafeHwnd()), WM_DISPLAY, nTemp, NULL);
}
(3)主对话框对WM_DISPLAY消息的处理LRESULT CDlgTestDlg::OnDisplay(WPARAM wParam, LPARAM lParam)
{
int nTemp = (int)wParam;
SetDlgItemInt(IDC_EDIT_CHAG, nTemp, FALSE);
return 0;
}
通过跟踪代码发现,主对话框收不到UI线程中发送的WM_DISPLAY消息,这是为什么?
有更简单的方法解决这个问题吗?

解决方案 »

  1.   

      ::PostMessage((HWND)(GetMainWnd()->GetSafeHwnd()), WM_DISPLAY, nTemp, NULL);   
    这个时候GetMainWnd返回有效的值了吗,主对话框不是还没有创建吗
      

  2.   

    GetMainWnd()是线程相关的,
    你应该用theApp.m_pMainWnd;
      

  3.   


    BOOL CDlgTestApp::InitInstance()
    {
    CDlgTestDlg dlg;
    m_pMainWnd = &dlg;

    m_pThread = (CMyThread*)AfxBeginThread(RUNTIME_CLASS(CMyThread));
    Sleep(500);
    m_pThread->PostThreadMessage(WM_CALCULATE, NULL, NULL);
    }创建UI线程前已经创建了对话框的实例,只是没有显示出来。
      

  4.   

    GetMainWnd()->GetSafeHwnd()只是在UI线程中获取主对话框的窗口句柄,没问题吧
      

  5.   

    percent=1;
    static int OFF=0;
    if(OFF==0)
    {
    OFF=1; unsigned long t;
    ENthread::ENCreateThread(t,GALoading::LoadingThread, m_game);
    }
    if(percent==1000)
    {
    ENthread::ENExitThread();
    }
      

  6.   

    #include"ENthread.h"int ENthread::ENCreateThread(unsigned long& t, void(__cdecl *func)(void *), void* arglist)  
    {  
    cout<<"创建线程:func:"<<func<<endl;
    return t = (unsigned long)_beginthread(func, 0, arglist);  
    }  void ENthread::ENExitThread()
    {
    cout<<"结束线程"<<endl;
    _endthread();}