如何解决在用户移动窗口时,窗口中的进度条刷新的问题,先谢谢了。
大家看到windows资源管理器中复制文件时的进度对话框了吧,用户移动时,它还会指示当前的操作进度。我现在做了个加/解密的进度对话框,用了2个线程,可是,当用户移动它时,进度就停止刷新了,可是后台还在工作啊!如何做到windows资源管理器的效果!!
感谢!!感谢!!
问题点数:30、回复次数:3Top
1 楼yaozijian110()回复于 2004-09-03 17:07:39 得分 20
你是怎么实现进度条的走动的?
如果是用全局变量表示进度,在线程中改变这个变量的值,在对话框中每隔一定时间刷新的话,是不行的。因为移动窗口的时候,进入一个特殊的模态过程,它会阻止窗口过程的执行的。
你可以把更新进度条的操作放到线程里面,这样即使拖动窗口,后台的线程也可以刷新进度条。
下面的程序是我写着玩的,希望对你有一定的参考价值:
DWORD CALLBACK CalculateProc(LPVOID p)
{
THREAD_PARAM *param = (THREAD_PARAM *)p;
UINT n,result,i;
HWND hProgressBar;
n = param->n;
result = 1;
hProgressBar = ::GetDlgItem(param->hDlg,IDC_PROGRESS1);
DWORD dwError = GetLastError();
for(i = 1; i <= n; i++)
{
result *= i;
//显示进度
::SendMessage(hProgressBar,PBM_SETPOS,100 * i / n,0);
//看有没有取消的请求
if (WaitForSingleObject(param->hCancel,0) == WAIT_OBJECT_0)
return 0;
}
param->result = result;
return 0;
}
void CTempttDlg::OnCal()
{
UINT nID;
DWORD dwID;
nID = GetWindowLong(m_wndcal.m_hWnd,GWL_ID);
if (nID == IDC_CAL)
{
if (m_param == NULL) m_param = new THREAD_PARAM;
m_param->hDlg = this->m_hWnd;
m_param->n = 2000000;
m_param->hCancel = CreateEvent(NULL,FALSE,FALSE,NULL);
::SetWindowText(m_wndcal.m_hWnd,TEXT("取消计算"));
::SetWindowLong(m_wndcal.m_hWnd,GWL_ID,IDC_CANCLE);
//启动计算线程
CreateThread(NULL,0,CalculateProc,(LPVOID)m_param,0,&dwID);
}
else if (nID == IDC_CANCLE)
{
if (MessageBox(TEXT("真的要取消计算吗?"),TEXT("取消计算"),MB_YESNO) == IDYES)
{
SetEvent(m_param->hCancel);
::SetWindowText(m_wndcal.m_hWnd,TEXT("计算"));
::SetWindowLong(m_wndcal.m_hWnd,GWL_ID,IDC_CAL);
m_progress.SetPos(0);
}
}
}
Top
2 楼evlon(阿牛)回复于 2004-09-03 17:22:02 得分 10
把设置操作放在工作线程中.同意楼上!Top
3 楼gzl(HR)回复于 2004-09-04 11:00:54 得分 0
对话框在一个界面线程中,加/解密操作在主线程中。通过主线程向界面线程中postmessage来更新界面的。Top




