搜索
bottom↓
回复: 11

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

[复制链接]

出0入31汤圆

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

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入22汤圆

发表于 2010-4-2 08:31:19 | 显示全部楼层
像你这种情况,最好使用多线程。否则有时候会有冲突。

出0入0汤圆

发表于 2010-4-2 09:27:15 | 显示全部楼层
正解,没有用多线程,刷新操作被抢占了。

出0入0汤圆

发表于 2010-4-2 10:07:02 | 显示全部楼层
我给你一个建议:
串口收发采用后台工作线程实现,然后,串口收发的进度写入到一个全局变量,然后,在进度条里面采用定时器,定时去读取这个变量,并更新进度。

出0入31汤圆

 楼主| 发表于 2010-4-2 12:35:21 | 显示全部楼层
谢谢各位!我再搜搜相关测资料,希望尽快把这个问题解决掉。

出0入0汤圆

发表于 2010-4-2 19:17:55 | 显示全部楼层
不用那么复杂。
在你设置了进度条新的位置之后,马上调用一下进度条控件的InvalidateRect()方法,还不行接着调用UpdateWindow()就ok了

出0入31汤圆

 楼主| 发表于 2010-4-8 15:17:06 | 显示全部楼层
楼上好!
如何得到progress控件的Rect区域呢?

出0入0汤圆

发表于 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);

出0入31汤圆

 楼主| 发表于 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();

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

出0入0汤圆

发表于 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);

出0入31汤圆

 楼主| 发表于 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[0] = page_begin&0xff;//页面低8位地址
                tbuffer[1] = (page_begin>>8)&0xff;//页面高8位地址
                tbuffer[2] = filelength_k&0xff;
                tbuffer[3] = (filelength_k>>8)&0xff;
                tbuffer[4] = filelength_b&0xff;
                tbuffer[5] = (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(" ");
        }

出0入0汤圆

发表于 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) ;

这样就够了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 06:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表