头疼,我想刷新屏幕上指定的一块区域怎么做?

时间:2022-12-09 15:04:56
注意我说的是屏幕上的

比如我现在整个屏幕都被CWindowDC dc(GetDesktopWindow()) 的DC给FillRect成了   RGB 0,0,255蓝色

我想让屏幕刷新

我试过 ::InvalidateRect  搞不定。。

我是屏幕指定区域刷新

哪位大神有方法实现~~~~~~~~~~~~~~

28 个解决方案

#1


你得在InvalidateRect(GetDesktopWindow(),...)的同时在你的OnPaint里面继续CWindowDC dc(GetDesktopWindow())、FillRect。

#2


LZ放心,凡是刷新重绘肯定得用InvalidateRect

#3


抱歉 我刚上 我现在试试你的方法

#4


还是不行,我把代码贴出来吧

// 全局变量
CWnd *pWnd;
CRect m_rt;

// 填充桌面为蓝色(按钮1事件)
pWnd = GetDesktopWindow();
pWnd->GetWindowRect(m_rt);

CWindowDC dc(GetDesktopWindow());
dc.FillRect(m_rt,&CBrush(RGB(0,0,255)));
ReleaseDC(&dc);

// 使用InvalidateRect(按钮2事件)
InvalidateRect(m_rt,TRUE);

// OnPaint中(在CDialog::OnPaint();上面增加的语句)
CWindowDC dc(GetDesktopWindow());
dc.FillRect(m_rt,&CBrush(RGB(0,0,255)));
ReleaseDC(&dc);



我这样操作出来的结果还是没有刷新,如果被刷新成功的话,那么屏幕上的m_rt区域蓝色应该都被刷掉

。。。。。。。

#5


引用 4 楼 yann2 的回复:
还是不行,我把代码贴出来吧

C/C++ code

// 全局变量
    CWnd *pWnd;
    CRect m_rt;

// 填充桌面为蓝色(按钮1事件)
    pWnd = GetDesktopWindow();
    pWnd->GetWindowRect(m_rt);

    CWindowDC dc(GetDesktopWindow());
……


LZ到底是要做什么?把这个区域去掉?用SelectClipRgn吧

#6


比如我用CWindowDC dc(GetDesktopWindow())   的DC在屏幕上画了CPoint的曲线

画完以后我想擦掉这些线 那么我就要刷新屏幕 ::InvalidteRect(NULL,NULL,TRUE); 刷新一下曲线确实消失了但这是刷新整个屏幕 屏幕会闪烁

所以我想只刷新一块区域   

#7


引用 6 楼 yann2 的回复:
比如我用CWindowDC dc(GetDesktopWindow()) 的DC在屏幕上画了CPoint的曲线

画完以后我想擦掉这些线 那么我就要刷新屏幕 ::InvalidteRect(NULL,NULL,TRUE); 刷新一下曲线确实消失了但这是刷新整个屏幕 屏幕会闪烁

所以我想只刷新一块区域


明白了。
沿着这条线的点,以每个点坐标为中心画一个很小的RECT(也可以适当隔几个点画这个RECT,这个RECT可以稍微大一点,这样隔开取的点就少。),然后InvalidteRect这些RECT(循环这个线上的点的RECT),这样就不是刷新整个屏幕,擦了线而且屏幕不会闪。

#8


InvalidteRect我不会用  这是实话

比如我InvalidteRect(CRect,TRUE);

同时在OnPaint中  用CWindowDC的DC来FillRect整个CRect吗

#9


引用 8 楼 yann2 的回复:
InvalidteRect我不会用 这是实话

比如我InvalidteRect(CRect,TRUE);

同时在OnPaint中 用CWindowDC的DC来FillRect整个CRect吗


不用。InvalidteRect就是擦除你不需要的区域。

#10


你的意思是直接  InvalidteRect(CRect,TRUE);??????就行了么

#11


你可以把InvalidteRect想象成一块橡皮擦,InvalidteRect(CRect)中的CRect是橡皮擦的大小以及要擦除的区域,如果橡皮小的话擦得慢,但是擦得很准确,而且因为变化的范围很小,不会闪烁。如果大的话擦得快,但是变化的范围大会产生屏幕闪烁。

#12


比如擦一条线,如果橡皮很大的话,一次就擦了,但是会闪烁,这就相当于InvalidteRect(NULL, NULL, TRUE)或者Invalidte。如果橡皮小的话,你就得沿着这条线的轨迹擦,但是不会闪烁。就相当于:
for(遍历这条线)
{
    InvalidteRect(RECT/*沿着这条线的RECT*/, ...);
}

#13


加一个STATI或图片控件上去,在他们上边DRAW,然后只刷新他们就可以

#14



OnMouseMove:
CWindowDC dc(GetDesktopWindow());
dc.MoveTo(m_pt);
dc.LineTo(point);
ReleaseDC(&dc);
m_pt = point;
这是桌面上绘制出来的点


我在一个按钮中:
CRect rt;
rt.SetRect(m_pt.x - 200,m_pt.y - 200,m_pt.x + 200,m_pt.y + 200);
InvalidateRect(rt,TRUE);
m_pt是OnMouseMove中最后一个点的位置,这里将他扩大200个像素

使用了 InvalidateRect(rt,TRUE);
没有任何效果


OnPaint中我没做处理



不知道我这是哪错了,这个你能举例写一下整个InvalidteRect怎么写吗。。

#15


引用 13 楼 lixiaohuprogram 的回复:
加一个STATI或图片控件上去,在他们上边DRAW,然后只刷新他们就可以


我是桌面DC画线  这个方法行不通

#16


InvalidateRect(rt,TRUE);
应该是
::InvalidateRect(GetDesktopWindow(),rt,TRUE);
吧。
而且你得确保你画的线的坐标在rt区域范围内。

#17


不行。。。。。。。

我都写成

CRect rt;
rt.SetRect(m_pt.x - 1200,m_pt.y - 1200,m_pt.x + 1200,m_pt.y + 1200);
::InvalidateRect(GetDesktopWindow()->m_hWnd,rt,TRUE);



刷新不了

#18


引用 17 楼 yann2 的回复:
不行。。。。。。。

我都写成

CRect rt;
rt.SetRect(m_pt.x - 1200,m_pt.y - 1200,m_pt.x + 1200,m_pt.y + 1200);
::InvalidateRect(GetDesktopWindow()->m_hWnd,rt,TRUE);



刷新不了


那就有可能是你的rt的范围有问题。rt的值你不能随便写,像m_pt.x - 1200这种肯定不行,还不如rt.left=0;rt.right=0。最好计算好rt的范围,不要随便写。

#19


而且InvalidateRect后,不能有OnMouseMove消息,不然又会画另一条线。

#20


rt.SetRect(0,0,1366,768);
::InvalidateRect(GetDesktopWindow()->m_hWnd,rt,TRUE);

还是不行。。。杯具啊杯具


1366 768是我屏幕大小

#21


把画过线的屏幕截图来看看

#22


哥们可以和你QQ聊么。。我干脆把DEMO工程发你   你看呢

#23


你QQ多少,我加你

#24


1551989520

#25


感谢!

这个问题下次有空要好好深入一下  先记下来了。。让我很蛋疼的问题

#26


 

#27


 

#28


你好,请问这个问题解决了吗,可否分享一下,我也遇到这样的问题了 呵呵

#1


你得在InvalidateRect(GetDesktopWindow(),...)的同时在你的OnPaint里面继续CWindowDC dc(GetDesktopWindow())、FillRect。

#2


LZ放心,凡是刷新重绘肯定得用InvalidateRect

#3


抱歉 我刚上 我现在试试你的方法

#4


还是不行,我把代码贴出来吧

// 全局变量
CWnd *pWnd;
CRect m_rt;

// 填充桌面为蓝色(按钮1事件)
pWnd = GetDesktopWindow();
pWnd->GetWindowRect(m_rt);

CWindowDC dc(GetDesktopWindow());
dc.FillRect(m_rt,&CBrush(RGB(0,0,255)));
ReleaseDC(&dc);

// 使用InvalidateRect(按钮2事件)
InvalidateRect(m_rt,TRUE);

// OnPaint中(在CDialog::OnPaint();上面增加的语句)
CWindowDC dc(GetDesktopWindow());
dc.FillRect(m_rt,&CBrush(RGB(0,0,255)));
ReleaseDC(&dc);



我这样操作出来的结果还是没有刷新,如果被刷新成功的话,那么屏幕上的m_rt区域蓝色应该都被刷掉

。。。。。。。

#5


引用 4 楼 yann2 的回复:
还是不行,我把代码贴出来吧

C/C++ code

// 全局变量
    CWnd *pWnd;
    CRect m_rt;

// 填充桌面为蓝色(按钮1事件)
    pWnd = GetDesktopWindow();
    pWnd->GetWindowRect(m_rt);

    CWindowDC dc(GetDesktopWindow());
……


LZ到底是要做什么?把这个区域去掉?用SelectClipRgn吧

#6


比如我用CWindowDC dc(GetDesktopWindow())   的DC在屏幕上画了CPoint的曲线

画完以后我想擦掉这些线 那么我就要刷新屏幕 ::InvalidteRect(NULL,NULL,TRUE); 刷新一下曲线确实消失了但这是刷新整个屏幕 屏幕会闪烁

所以我想只刷新一块区域   

#7


引用 6 楼 yann2 的回复:
比如我用CWindowDC dc(GetDesktopWindow()) 的DC在屏幕上画了CPoint的曲线

画完以后我想擦掉这些线 那么我就要刷新屏幕 ::InvalidteRect(NULL,NULL,TRUE); 刷新一下曲线确实消失了但这是刷新整个屏幕 屏幕会闪烁

所以我想只刷新一块区域


明白了。
沿着这条线的点,以每个点坐标为中心画一个很小的RECT(也可以适当隔几个点画这个RECT,这个RECT可以稍微大一点,这样隔开取的点就少。),然后InvalidteRect这些RECT(循环这个线上的点的RECT),这样就不是刷新整个屏幕,擦了线而且屏幕不会闪。

#8


InvalidteRect我不会用  这是实话

比如我InvalidteRect(CRect,TRUE);

同时在OnPaint中  用CWindowDC的DC来FillRect整个CRect吗

#9


引用 8 楼 yann2 的回复:
InvalidteRect我不会用 这是实话

比如我InvalidteRect(CRect,TRUE);

同时在OnPaint中 用CWindowDC的DC来FillRect整个CRect吗


不用。InvalidteRect就是擦除你不需要的区域。

#10


你的意思是直接  InvalidteRect(CRect,TRUE);??????就行了么

#11


你可以把InvalidteRect想象成一块橡皮擦,InvalidteRect(CRect)中的CRect是橡皮擦的大小以及要擦除的区域,如果橡皮小的话擦得慢,但是擦得很准确,而且因为变化的范围很小,不会闪烁。如果大的话擦得快,但是变化的范围大会产生屏幕闪烁。

#12


比如擦一条线,如果橡皮很大的话,一次就擦了,但是会闪烁,这就相当于InvalidteRect(NULL, NULL, TRUE)或者Invalidte。如果橡皮小的话,你就得沿着这条线的轨迹擦,但是不会闪烁。就相当于:
for(遍历这条线)
{
    InvalidteRect(RECT/*沿着这条线的RECT*/, ...);
}

#13


加一个STATI或图片控件上去,在他们上边DRAW,然后只刷新他们就可以

#14



OnMouseMove:
CWindowDC dc(GetDesktopWindow());
dc.MoveTo(m_pt);
dc.LineTo(point);
ReleaseDC(&dc);
m_pt = point;
这是桌面上绘制出来的点


我在一个按钮中:
CRect rt;
rt.SetRect(m_pt.x - 200,m_pt.y - 200,m_pt.x + 200,m_pt.y + 200);
InvalidateRect(rt,TRUE);
m_pt是OnMouseMove中最后一个点的位置,这里将他扩大200个像素

使用了 InvalidateRect(rt,TRUE);
没有任何效果


OnPaint中我没做处理



不知道我这是哪错了,这个你能举例写一下整个InvalidteRect怎么写吗。。

#15


引用 13 楼 lixiaohuprogram 的回复:
加一个STATI或图片控件上去,在他们上边DRAW,然后只刷新他们就可以


我是桌面DC画线  这个方法行不通

#16


InvalidateRect(rt,TRUE);
应该是
::InvalidateRect(GetDesktopWindow(),rt,TRUE);
吧。
而且你得确保你画的线的坐标在rt区域范围内。

#17


不行。。。。。。。

我都写成

CRect rt;
rt.SetRect(m_pt.x - 1200,m_pt.y - 1200,m_pt.x + 1200,m_pt.y + 1200);
::InvalidateRect(GetDesktopWindow()->m_hWnd,rt,TRUE);



刷新不了

#18


引用 17 楼 yann2 的回复:
不行。。。。。。。

我都写成

CRect rt;
rt.SetRect(m_pt.x - 1200,m_pt.y - 1200,m_pt.x + 1200,m_pt.y + 1200);
::InvalidateRect(GetDesktopWindow()->m_hWnd,rt,TRUE);



刷新不了


那就有可能是你的rt的范围有问题。rt的值你不能随便写,像m_pt.x - 1200这种肯定不行,还不如rt.left=0;rt.right=0。最好计算好rt的范围,不要随便写。

#19


而且InvalidateRect后,不能有OnMouseMove消息,不然又会画另一条线。

#20


rt.SetRect(0,0,1366,768);
::InvalidateRect(GetDesktopWindow()->m_hWnd,rt,TRUE);

还是不行。。。杯具啊杯具


1366 768是我屏幕大小

#21


把画过线的屏幕截图来看看

#22


哥们可以和你QQ聊么。。我干脆把DEMO工程发你   你看呢

#23


你QQ多少,我加你

#24


1551989520

#25


感谢!

这个问题下次有空要好好深入一下  先记下来了。。让我很蛋疼的问题

#26


 

#27


 

#28


你好,请问这个问题解决了吗,可否分享一下,我也遇到这样的问题了 呵呵