InvalidateRect(rect) 防止图片移动时发生闪烁
InvalidateRect(rect), 他运行时, rect区域以背景刷清屏。rect以外的区域不调用背景刷。而是将屏幕上现有的内容(如图片图形等)作为背景,在这个背景上直接绘图。
若是,图片和背景反差非常大。则使用Invalidate() 会发生闪烁
而使用Invalidate(rect), 则能够将闪烁减少到图片的边缘位置
详细方法例如以下:
平移时,假设直接翻盖原来的图片,则不会闪烁,但是这时,图片移动后。原图片的边缘位置已经无效,但是因为我们没有清屏,所以它还显示在图片上,这是不应该的。
假设能让图片直接覆盖原有的图片。而且,又让图片失效的边缘部分清屏的话。那我们就能够解决问题了。
首先, 我们确定好边缘处须要刷新的区域shuanxinRect
然后。调用InvalidateRect(rect) 就可以
注意,移动时。不要使的整个客户区clientRect都清屏。由于那样,会产生闪烁。
我们的原则是:改直接覆盖的。则直接覆盖。改清屏的则清屏
同一时候,要注意:InvalidateRect(rect) 使用的是对话框的坐标系,而不是画图控件的坐标系。
所以,若是两坐标系不同的话,先要通过 kongJian->ClientToScreen(&rect); this->ScreenToClient(&rect) 进行转换,转换完成后,才干够调用InvalidateRect(rect);
以下是我在项目中摘取的一段演示样例程序:使用四个方向键来控制图片的平移
void CShowImageDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此加入消息处理程序代码和/或调用默认值
switch (nChar)
{
case VK_LEFT:
m_isKeyMoving=TRUE;
if(!m_lock) //移动图片 用方向键控制移动图片
{
GetDlgItem(IDC_MOVE)->SetFocus();
CRect rect;
m_RectTracker.GetTrueRect(&rect);
m_RectTracker.m_rect.SetRect(rect.TopLeft().x-10,rect.TopLeft().y,rect.BottomRight().x-10,rect.BottomRight().y);
m_RectTracker.GetTrueRect(&rect); // 调整以后,取得的新矩形位置
m_pGraphics->DrawImage(m_pImageObj,rect.TopLeft().x,rect.TopLeft().y,rect.Width(),rect.Height());
CRect clientRect;
m_image.GetClientRect(&clientRect);
CRect shuanxinRect;
if (rect.BottomRight().x<clientRect.BottomRight().x) //确定刷新区域
{
shuanxinRect.TopLeft().x=rect.BottomRight().x;
if(rect.TopLeft().y>0)
shuanxinRect.TopLeft().y=rect.TopLeft().y;
else
shuanxinRect.TopLeft().y=0;
shuanxinRect.BottomRight().x=clientRect.BottomRight().x;
shuanxinRect.BottomRight().y=clientRect.BottomRight().y;
//clientRect与rect shuanxinRect 用的都是m_image客户区坐标。 而InvalidateRect RedrawWindow用的却是对话框客户区坐标
//所以在使用InvalidateRect RedrawWindow 之前 必须将其它坐标系下的坐标进行转换,否则不能按预想的运行
m_image.ClientToScreen(shuanxinRect);
this->ScreenToClient(shuanxinRect);
RedrawWindow(shuanxinRect);
}
DrawRectLock();
}else{
GetDlgItem(IDC_LOCK)->SetFocus();
int width=0;
int height=0;
int x=0;
int y=0;
CRectTracker_Lock *p=headRectTraker;
if(p!=NULL)
{
//画区域
width=m_step;
height=p->rectLock.m_rect.Height();
x=p->rectLock.m_rect.TopLeft().x-m_step;
y=p->rectLock.m_rect.TopLeft().y;
int image_x=p->radio_distance_x*m_pImageObj->GetWidth()-((double)m_step/m_RectTracker.m_rect.Width())*m_pImageObj->GetWidth();
int image_y=p->radio_distance_y*m_pImageObj->GetHeight();
int image_width=((double)m_step/m_RectTracker.m_rect.Width())*m_pImageObj->GetWidth();
int image_height=p->radio_height*m_pImageObj->GetHeight();
Pen pen(Color(255,255,0,0),2);
m_pGraphics->DrawRectangle(&pen,x,y,width,height);
CRect rect2;
m_RectTracker2.m_rect.SetRect(0,0,image_width,image_height);
m_RectTracker2.GetTrueRect(&rect2);
RectF rect2Des;
rect2Des.X=rect2.TopLeft().x;
rect2Des.Y=rect2.TopLeft().y;
rect2Des.Width=rect2.Width();
rect2Des.Height=rect2.Height();
m_image2.ClientToScreen(rect2);
this->ScreenToClient(rect2);
Graphics graphics2(m_image2.GetDC()->GetSafeHdc());
graphics2.DrawImage(m_pImageObj,rect2Des,image_x,image_y,image_width,image_height,UnitPixel);
}
}
break;
case VK_RIGHT:
m_isKeyMoving=TRUE;
if(!m_lock) //移动图片 用方向键控制移动图片
{
GetDlgItem(IDC_MOVE)->SetFocus();
CRect rect;
m_RectTracker.GetTrueRect(&rect);
m_RectTracker.m_rect.SetRect(rect.TopLeft().x+10,rect.TopLeft().y,rect.BottomRight().x+10,rect.BottomRight().y);
m_RectTracker.GetTrueRect(&rect); // 调整以后,取得的新矩形位置
m_pGraphics->DrawImage(m_pImageObj,rect.TopLeft().x,rect.TopLeft().y,rect.Width(),rect.Height());
CRect clientRect;
m_image.GetClientRect(&clientRect);
CRect shuanxinRect;
if (rect.TopLeft().x>clientRect.TopLeft().x)
{
shuanxinRect.TopLeft().x=clientRect.TopLeft().x;
shuanxinRect.TopLeft().y=clientRect.TopLeft().y;
shuanxinRect.BottomRight().x=rect.TopLeft().x;
shuanxinRect.BottomRight().y=clientRect.BottomRight().y;
//clientRect与rect shuanxinRect 用的都是m_image客户区坐标, 而InvalidateRect RedrawWindow用的却是对话框客户区坐标
//所以在使用InvalidateRect RedrawWindow 之前 必须将其它坐标系下的坐标进行转换。否则不能按预想的运行
m_image.ClientToScreen(shuanxinRect);
this->ScreenToClient(shuanxinRect);
RedrawWindow(shuanxinRect);
}
DrawRectLock();
}
break;
case VK_DOWN:
m_isKeyMoving=TRUE;
if(!m_lock) //移动图片 用方向键控制移动图片
{
GetDlgItem(IDC_MOVE)->SetFocus();
CRect rect;
m_RectTracker.GetTrueRect(&rect);
m_RectTracker.m_rect.SetRect(rect.TopLeft().x,rect.TopLeft().y+10,rect.BottomRight().x,rect.BottomRight().y+10);
m_RectTracker.GetTrueRect(&rect); // 调整以后,取得的新矩形位置
m_pGraphics->DrawImage(m_pImageObj,rect.TopLeft().x,rect.TopLeft().y,rect.Width(),rect.Height());
CRect clientRect;
m_image.GetClientRect(&clientRect);
CRect shuanxinRect;
if (rect.TopLeft().y>clientRect.TopLeft().y)
{
shuanxinRect.TopLeft().x=clientRect.TopLeft().x;
shuanxinRect.TopLeft().y=clientRect.TopLeft().y;
shuanxinRect.BottomRight().x=clientRect.BottomRight().x;
shuanxinRect.BottomRight().y=rect.TopLeft().y;
//clientRect与rect shuanxinRect 用的都是m_image客户区坐标, 而InvalidateRect RedrawWindow用的却是对话框客户区坐标
//所以在使用InvalidateRect RedrawWindow 之前 必须将其它坐标系下的坐标进行转换,否则不能按预想的运行
m_image.ClientToScreen(shuanxinRect);
this->ScreenToClient(shuanxinRect);
RedrawWindow(shuanxinRect);
}
DrawRectLock();
}
break;
case VK_UP:
m_isKeyMoving=TRUE;
if(!m_lock) //移动图片 用方向键控制移动图片
{
GetDlgItem(IDC_MOVE)->SetFocus();
CRect rect;
m_RectTracker.GetTrueRect(&rect);
m_RectTracker.m_rect.SetRect(rect.TopLeft().x,rect.TopLeft().y-10,rect.BottomRight().x,rect.BottomRight().y-10);
m_RectTracker.GetTrueRect(&rect); // 调整以后,取得的新矩形位置
m_pGraphics->DrawImage(m_pImageObj,rect.TopLeft().x,rect.TopLeft().y,rect.Width(),rect.Height());
CRect clientRect;
m_image.GetClientRect(&clientRect);
CRect shuanxinRect;
if (rect.BottomRight().y<clientRect.BottomRight().y)
{
shuanxinRect.TopLeft().x=clientRect.TopLeft().x;
shuanxinRect.TopLeft().y=rect.BottomRight().y;
shuanxinRect.BottomRight().x=clientRect.BottomRight().x;
shuanxinRect.BottomRight().y=clientRect.BottomRight().y;
//clientRect与rect shuanxinRect 用的都是m_image客户区坐标, 而InvalidateRect RedrawWindow用的却是对话框客户区坐标
//所以在使用InvalidateRect RedrawWindow 之前 必须将其它坐标系下的坐标进行转换,否则不能按预想的运行
m_image.ClientToScreen(shuanxinRect);
this->ScreenToClient(shuanxinRect);
RedrawWindow(shuanxinRect);
}
DrawRectLock();
}
break;
}
CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}
浙公网安备 33010602011771号