使用ATL时,在不阻止UI的情况下,显示后台线程进度的最佳方法是什么(例如,在搜索文件时)?
我仍然希望能够处理消息,允许取消按钮,并允许用户在搜索发生时继续使用该程序。
答案 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 snippet,AddText
:
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);
}
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),但我希望你明白这一点。