急;如何禁止客户区重绘?

littleleaf2008 2004-05-03 09:19:57
我根据从串口读到的数据使客户区的某些区域作相应的颜色变化,如果没有任何东西覆盖它的画,一切正常,但是如果有东西覆盖一下画界面再离开的话界面马上就回到了最初始状态,这不是我此时需要的画面状态,我要如何才能使我的界面在任何东西覆盖后不被改变?请高手们赐教,不甚感激!
...全文
269 17 点赞 打赏 收藏 举报
写回复
17 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
Elusive 2004-05-03
应该在OnPaint里调啊 它会自动处理重绘
  • 打赏
  • 举报
回复
littleleaf2008 2004-05-03
我在OnTimer()里读取串口数据,数据到手后,在一个自定义的消息函数里根据数据的范围更新方块图,譬如在合格的数据范围内方块图变成绿色,方块图中的缺口范围最大.我就是在我的自定义消息函数里平移的图片,同时也调用了ExtFloodFill().
  • 打赏
  • 举报
回复
Elusive 2004-05-03
你在哪个函数里绘的图(比如ExtFloodFill())?
基本上还是不明白你在作甚?
  • 打赏
  • 举报
回复
littleleaf2008 2004-05-03
问题的详细情况如下:
我在界面上有一副方块图,方块图中有一小缺口,当从串口的数据读取的数据越接近我的目标数据,小缺口将变得越大(我通过图像平移实现的),当然方块图的颜色也应根据数据作相应的变化,如果在此变化过程中无东西覆盖方块图区域,一切如愿,但是如果有东西覆盖过方块图,我的界面回到了最始状态(含缺口范围和方块图颜色).我希望我的界面在被别的窗口覆盖后,方块图的状态不改变,我该怎么办?由于方块图不是一个很有规则的矩形,所以颜色上的变化我是用的CDC::ExtFloodFill()函数实现的.我知道可能要在OnPaint()中重画,但我不知道该重画的范围.也就是被别的窗口覆盖过的区域.
因为我界面上有好几个方块图,每个方块图又有颜色和形状的问题,而不是单纯的把某一块变成某一颜色,所以不怎么好采用设置变量的方法.因此我想知道将重画的区域,自己在OnPaint()中画成我需要的颜色和形状.该怎么办呢?
  • 打赏
  • 举报
回复
red-fly 2004-05-03
假设你要把客户区分成三行,根据所读的数据分别填充不同的颜色,则你要定义三个变量:
COLORREF clrTop, clrMiddle, clrBottom;
在OnPaint里:
CRect rc;
GetClientRect( rc );
dc.FillRect( 0,0,rc.Width(), rc.Height()/3, clrTop );
dc.FillRect( 0, rc.Height()/3, rc.Width(), rc.Height*2/3, clrMiddle );
dc.FillRect( 0, rc.Height()*2/3, rc.Width(), rc.Height(), clrBottom );
在你接收函数里:
//lpBuf
if ( lpBuf[0] == '0' )
clrTop = RGB(...);
else if ( lpBuf[0] == '1' )
clrTop = RGB(...);
else if ( lpBuf[1] == '0' )
clrMiddle = RGB(...);
... // etc.
Invalidate();
//all is ok
  • 打赏
  • 举报
回复
red-fly 2004-05-03
对界面“颜色” 的操作,要放到窗体的OnPaint函数里,即你要设置多个变量来记录你的颜色,然后在OnPaint里对“各个区域”进行填充
当你从串口收到数据后,你根据数据来改变相应区域的标志颜色,然后再调用Invalidate或者InvalidateRect函数来“重画”窗体,(这个重画过程就是程序自动调用OnPaint的过程)

我要怎样才知道该重画的范围,也就是被别的窗口覆盖过的范围,有这样的函数或别的什么方法吗?
--------------------------
直接调用Invalidate函数即可,OnPaint会为你做的
  • 打赏
  • 举报
回复
UDX协议 2004-05-03
ValidateRect
ValidateRgn
SetRedraw(false);
  • 打赏
  • 举报
回复
Elusive 2004-05-03
实在不懂你要干啥子

一般做个buffer,读入数据后更新它,OnPaint根据buffer绘图
  • 打赏
  • 举报
回复
littleleaf2008 2004-05-03
Elusive:但是我要怎样才知道该绘哪个区域呢?
  • 打赏
  • 举报
回复
Elusive 2004-05-03
你怎么做的?在OnPaint里绘图就可以啊
  • 打赏
  • 举报
回复
菜牛 2004-05-03
程序哪有做得那么死的,绘制代码肯定要在响应WM_PAINT里做,看你说了那么多,根本是概念错误:你要做的不是禁止客户区重绘,而是如何响应客户区重绘。
最一般的方法,就是保存你的图形数据,在重绘的时候绘制出图形来。在OnTimer里,只是改变图形数据,然后刷新。
实在没有办法,可一定义一个类的成员变量,类型为位图或者DC,作为内存DC,在OnTimer里在内存DC上绘图,然后刷新,在OnDraw()里(CView)或者OnPaint()里(CDialog)将内存DC绘制到屏幕上(BitBlt)。
至于有效矩形的问题,是为了提高绘制效率,比如通过计算,只将内存DC中的一个区域绘制到屏幕对应的区域,减少了数据传输量,当然会快上那么一点点,如果不是大量绘图运算,没有必要管它。而且,如果想你说的想在有效矩形里重新绘制局部,那么在响应WM_PAINT里重新绘制所有图形也没有问题了?还说那么多干什么!
  • 打赏
  • 举报
回复
littleleaf2008 2004-05-03
普通的对话框可以响应WM_NCACTIVATE,WM_ACTIVATE吗?为什么我在类向导中没找到?
  • 打赏
  • 举报
回复
red-fly 2004-05-03
界面在将覆盖的那一瞬间和覆盖后重新出现的那一瞬间,windows将分别给它发送什么消息
--------------------------------------------------------------------------------
我不十分清楚,可能会有WM_NCACTIVATE,WM_ACTIVATE,另外WM_PAINT肯定会有,而WM_PAINT只在界面重新出现后的一刻才会有,而前两个应该是界面出现和后都会有
  • 打赏
  • 举报
回复
hab1980 2004-05-03
你要做的就是在OnDraw里面绘制你想要看到的客户区,系统导致的重绘系统自己会计算要重绘的区域的。
  • 打赏
  • 举报
回复
red-fly 2004-05-03
ExtFloodFill()的前三个参数你记住就行了,当你收到串口数据时,就改变坐标和颜色,然后调用Invalidate

至于什么范围,你不用管,你只需要在OnPaint里边调用ExtFloodFill(),当然,前三个参数要用全局的,因为你在接收串口数据时要改变它

如果你的“方块图”有多块,则你要多要几个类内的全局变量以记录每个块的数据,如果是块数不固定,则可能还要动态类内全局变量(或者你声明一个足够大的组来存放所有块的数据)
这里的数据是指坐标和颜色,即你要改变的部分
在OnPaint里边,需要随着串口数据的改变面改变的有关函数,都要用类内全局变量,至于她画的是哪一块,你就不用管了,因为在接收串口数据时会改变
  • 打赏
  • 举报
回复
littleleaf2008 2004-05-03
如果word2000的界面覆盖了vc界面,这时windows将发送什么消息给vc界面.如果vc重新出现,windows又将发送什么消息给vc.也就是界面在将覆盖的那一瞬间和覆盖后重新出现的那一瞬间,windows将分别给它发送什么消息?
  • 打赏
  • 举报
回复
littleleaf2008 2004-05-03
ExtFloodFill(point,color1,color2)函数:发射性地填充point周围color1的点为color2(当然point应为color1),若point不为color1,而在其它地方有,ExtFloodFill不填充.现在我想找到point(也就是填充的起始点),因此我得到重绘的区域或是起始点.该如何办?
  • 打赏
  • 举报
回复
相关推荐
发帖
界面
加入

1.5w+

社区成员

VC/MFC 界面
申请成为版主
帖子事件
创建了帖子
2004-05-03 09:19
社区公告
暂无公告