在ATL中显示后台线程进度的最佳方法?

时间:2011-11-28 19:13:53

标签: multithreading winapi atl progress

使用ATL时,在不阻止UI的情况下,显示后台线程进度的最佳方法是什么(例如,在搜索文件时)?

我仍然希望能够处理消息,允许取消按钮,并允许用户在搜索发生时继续使用该程序。

1 个答案:

答案 0 :(得分:1)

此处没有特定的ATL。其中一种方法是将进度详细信息更新为成员变量并将消息发布到GUI窗口,然后通过从成员变量中提取数据并更新GUI来处理消息,例如更新静态和/或进度条。

工作线程伪代码:

m_DataCriticalSection.Lock();
m_nProgress = (INT) (nCurrent * 100 / nTotal);
m_DataCriticalSection.Unlock();
PostMessage(WM_MYUPDATEPROGRESS);

窗口:

OnMyUpdateProgress()
{
  m_DataCriticalSection.Lock();
  INT nProgress = m_nProgress;
  m_DataCriticalSection.Unlock();
  m_ProgressBar.SetPos(nProgress);
}

UPD。在后台线程上调用real code snippetAddText

    VOID AddText(const CString& sText)
    {
            _A(sText.Find(_T('\n')) < 0);
            BOOL bIsTextEmpty;
            {
                    CRoCriticalSectionLock TextLock(m_TextCriticalSection);
                    bIsTextEmpty = m_sText.IsEmpty();
                    m_sText.Append(sText);
                    m_sText.Append(_T("\r\n"));
            }
            if(bIsTextEmpty)
                    PostPrivateMessage(WM_UPDATETEXT);
    }

the code handler

BEGIN_MSG_MAP_EX(CMainDialog)
        // ...
        MESSAGE_HANDLER_EX(WM_UPDATETEXT, OnUpdateText)

    LRESULT OnUpdateText(UINT, WPARAM, LPARAM)
    {
            CString sText;
            {
                    CRoCriticalSectionLock TextLock(m_TextCriticalSection);
                    sText = m_sText;
                    m_sText.Empty();
            }
            if(!sText.IsEmpty())
            {
                    m_TextEdit.SetValue(m_TextEdit.GetValue() + sText);
                    const INT nTextLength = m_TextEdit.GetWindowTextLength();
                    m_TextEdit.SetSel(nTextLength, nTextLength);
            }
            return 0;
    }

这使用自定义类(不是'纯'ATL),但我希望你明白这一点。