zchong 发表于 2010-4-2 07:20:44

问:VC6的progress控件有时不刷新

用VC6做了一个串口下载程序的小程序,在界面上放一progress控件用于指示文件下载进度,正常情况,progress控件能够正常刷新,随着程序的下载进度条不断向前推进,不过偶尔进度条会停滞不前直至文件下载完成。
如果在下载过程中,移动窗口,进度条必停,网上说要使用多线程,搞嵌入式的,对上位机不太了解,多线程=多任务?vc上怎么实现呢?
有没有比较简单的方法解决这个问题呢?

zxq6 发表于 2010-4-2 08:31:19

像你这种情况,最好使用多线程。否则有时候会有冲突。

mlhorizon 发表于 2010-4-2 09:27:15

正解,没有用多线程,刷新操作被抢占了。

oldtom 发表于 2010-4-2 10:07:02

我给你一个建议:
串口收发采用后台工作线程实现,然后,串口收发的进度写入到一个全局变量,然后,在进度条里面采用定时器,定时去读取这个变量,并更新进度。

zchong 发表于 2010-4-2 12:35:21

谢谢各位!我再搜搜相关测资料,希望尽快把这个问题解决掉。

jimo 发表于 2010-4-2 19:17:55

不用那么复杂。
在你设置了进度条新的位置之后,马上调用一下进度条控件的InvalidateRect()方法,还不行接着调用UpdateWindow()就ok了

zchong 发表于 2010-4-8 15:17:06

楼上好!
如何得到progress控件的Rect区域呢?

118139 发表于 2010-4-8 16:11:08

CRect rect;
    CString str;
       
        m_progress.GetWindowRect(rect) ;
   str.Format("%d,%d,%d,%d",rect.top,rect.bottom ,rect.left,rect.right);
    AfxMessageBox(str);

zchong 发表于 2010-4-8 16:22:48

回复【5楼】jimo
-----------------------------------------------------------------------

回复【7楼】118139
-----------------------------------------------------------------------

m_ctrDownProgress.SetPos(counter/10);

CRect rect;
m_ctrDownProgress.GetWindowRect(rect);
m_ctrDownProgress.InvalidateRect(&rect,TRUE);
m_ctrDownProgress.UpdateWindow();

移动窗口的话,进度条还是会停止不前。

118139 发表于 2010-4-8 16:45:09

你可以先设进度条显示范围,比如

         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);

zchong 发表于 2010-4-8 17:35:16

//写页面地址,及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(" ");
        }

118139 发表于 2010-4-8 21:23:58

可以这样
比如随便
要写入一个总字节数为 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]
查看完整版本: 问:VC6的progress控件有时不刷新