问:VC6的progress控件有时不刷新
用VC6做了一个串口下载程序的小程序,在界面上放一progress控件用于指示文件下载进度,正常情况,progress控件能够正常刷新,随着程序的下载进度条不断向前推进,不过偶尔进度条会停滞不前直至文件下载完成。如果在下载过程中,移动窗口,进度条必停,网上说要使用多线程,搞嵌入式的,对上位机不太了解,多线程=多任务?vc上怎么实现呢?
有没有比较简单的方法解决这个问题呢? 像你这种情况,最好使用多线程。否则有时候会有冲突。 正解,没有用多线程,刷新操作被抢占了。 我给你一个建议:
串口收发采用后台工作线程实现,然后,串口收发的进度写入到一个全局变量,然后,在进度条里面采用定时器,定时去读取这个变量,并更新进度。 谢谢各位!我再搜搜相关测资料,希望尽快把这个问题解决掉。 不用那么复杂。
在你设置了进度条新的位置之后,马上调用一下进度条控件的InvalidateRect()方法,还不行接着调用UpdateWindow()就ok了 楼上好!
如何得到progress控件的Rect区域呢? CRect rect;
CString str;
m_progress.GetWindowRect(rect) ;
str.Format("%d,%d,%d,%d",rect.top,rect.bottom ,rect.left,rect.right);
AfxMessageBox(str); 回复【5楼】jimo
-----------------------------------------------------------------------
回复【7楼】118139
-----------------------------------------------------------------------
m_ctrDownProgress.SetPos(counter/10);
CRect rect;
m_ctrDownProgress.GetWindowRect(rect);
m_ctrDownProgress.InvalidateRect(&rect,TRUE);
m_ctrDownProgress.UpdateWindow();
移动窗口的话,进度条还是会停止不前。 你可以先设进度条显示范围,比如
m_progress.SetRange(0,10);//类似把进度分成10等分
m_progress.SetPos(0); //指向开头。。
然后根据下载完成度的百份比来 设制进度条 前进的百分比
比如上面是设置成了10等分
则,如果数据下载了占整个容量的10份之1时,那就是1等分
就 1代入进去
m_progress.SetPos(1);
这时进度条就前进了一格。。。
如果数据下载了占整个容量一半时,那就是5等分
SetPos设成5 进度条就前进了一半
m_progress.SetPos(5);
文件所接收结束,那就设SetPos为10,进度条指向底部
m_progress.SetPos(10); //写页面地址,及bin文件大小
filelength_b = file.GetLength();
filelength_k = filelength_b/1024;//多少K字节
filelength_b = filelength_b%1024;//按1K取模
m_ctrDownProgress.SetRange(0, filelength_k/10);
m_ctrDownProgress.SetPos(0);
tbuffer = page_begin&0xff;//页面低8位地址
tbuffer = (page_begin>>8)&0xff;//页面高8位地址
tbuffer = filelength_k&0xff;
tbuffer = (filelength_k>>8)&0xff;
tbuffer = filelength_b&0xff;
tbuffer = (filelength_b>>8)&0xff;
bWriteState = WriteFile(hCom, tbuffer, 6, &dwBytesWrite, NULL);
if (bWriteState)
{
bReadState = ReadFile(hCom,rbuffer,6,&dwBytesRead,NULL);
PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
if (bReadState)
{
if(memcmp(rbuffer, tbuffer, 6) != 0)
{
AfxMessageBox("下载文件失败, page and size!");
return;
}
}
}
/*----------------------------- 下载前的交互end -------------------------------------/
/****************************** 下载bin文件 begin ***************************************/
do
{
uLen = file.Read(tbuffer, 1024);
if (uLen)
{
//写串口
bWriteState = WriteFile(hCom, tbuffer, uLen, &uLen, NULL);
Sleep(60);
//读串口
if(bWriteState)//如果写成功
{
bReadState=ReadFile(hCom,rbuffer,uLen,&uLen,NULL);
PurgeComm(hCom, PURGE_RXCLEAR | PURGE_TXCLEAR);
counter++;
if(counter%10 == 0)
{
m_ctrDownProgress.SetPos(counter/10);
CRect rect;
m_ctrDownProgress.GetWindowRect(rect);
m_ctrDownProgress.InvalidateRect(&rect,TRUE);
m_ctrDownProgress.UpdateWindow();
}
if (bReadState)//如果读成功
{
if(memcmp(tbuffer, rbuffer, uLen) != 0)// 比较写和读的内容
{
AfxMessageBox("下载文件失败:不一致!");
GetDlgItem(IDC_TEXT)->SetWindowText(" ");
return;
}
}
}
else
{
AfxMessageBox("下载文件失败:写失败!");
GetDlgItem(IDC_TEXT)->SetWindowText(" ");
return;
}
}
} while(uLen == 1024);
/****************************** 下载bin文件 end ***************************************/
AfxMessageBox("文件下载完成!");
GetDlgItem(IDC_TEXT)->SetWindowText(" ");
} 可以这样
比如随便
要写入一个总字节数为 51045字节的数据
先设进度条10等分
m_ctrDownProgress.SetRange(0,10);
然后再定个变量kk 用来做倍数,计算百分比用
因为10等分所以计算
kk=51045/10//kk=5104;
然后在写入成功的函数中
counter++; //这里counter 累加值要改成是当前写入的实际字节数
然后
step=counter/kk //除以倍数kk,得到步进数,最高值只会到10;
代入
m_ctrDownProgress.SetPos(step); //然后给进制条..完成。
具体修改
在开头
filelength_b = file.GetLength();
kk=filelength_b/10; //倍数给KK
m_ctrDownProgress.SetRange(0,10); //这里设成10等分
m_ctrDownProgress.SetPos(0);
下部份交互区里面
if(bWriteState)//如果写成功
{
bReadState=ReadFile(hCom,rbuffer,uLen,&uLen,NULL);
PurgeComm(hCom, PURGE_RXCLEAR | PURGE_TXCLEAR);
counter++; //counter这里要变成具体的写入字节数
step=counter/kk //除以倍数,得到步进数
m_ctrDownProgress.SetPos(step) ;
这样就够了
页:
[1]