内存DC可不可以通过设置映射模式将兼容位图的SIZE变小点

conterc 2008-12-14 05:40:59
要画一个很大的网格,大小有16000*16000,滚动窗口,直接画的话,在拖动滚动条的时候会发生闪烁,网上说用双缓冲解决,在创建兼容位图的时候,由于面积过大而创建失败,虽说XP没有16M的限制,但是当面积大于8000*6000左右的时候就会创建失败,网上还有说用CreateDIBSection创建,但是查了一下不知道咋用,是不是和CreateCompatibleBitmap一样,创建成功之后,选进兼容DC就可以了.
现在想到可不可以通过设置兼容DC的映射模式,来创建一个小一点的位图,然后在上面画很细的线(小于1像素),然后再用StretchBlt放大显示在屏幕上.不可以这个方法可行不.
另外这个小的位图占用的内存会不会小一点.
...全文
147 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
conterc 2008-12-16
  • 打赏
  • 举报
回复
我自己的方法,对着zhoujianhei 提供的开了一遍后,屏幕全灰(线的颜色),笔的宽度或放大的问题?无解

然后又下载CZOOMVIEW,很好的一个类,不过跟踪了半天,怎么实现的看不明白,MFC刚接触,只有等以后懂的多点后再来学习了.

回jameshooo:放在背景里动态绘制,会闪烁,不知道是不是我没找到不闪烁的原因.

最后根据Tinary3v0 的方法,现在正在尝试中,正在解决如何得到滚动条的位置及偏移.......

谢谢大家提供了这么多的方法,不胜感激......
jameshooo 2008-12-15
  • 打赏
  • 举报
回复
网格可以不用画那么大,放在背景里动态绘制,填满客户区即可。
cnzdgs 2008-12-15
  • 打赏
  • 举报
回复
可以试试。
Tinary3v0 2008-12-15
  • 打赏
  • 举报
回复
楼主的图太大了 反正一屏显示不出来 那你干脆用算法来做么 何必非要创建这么大的位图呢??

楼主创建一个1024*768大小(绘图区大小)的内存图片,然后直接使用函数在上面绘图就行了,绘制的时候参考滚动条的位置,将绘图起点坐标偏移一下就行了。

例如你要绘制(0,0)到(2000,2000)的图片 直接使用
MoveTo(0,0); LineTo(2000,2000);(OnDraw当中)

当滚动条发生移动后,肯定会产生偏移了,以前的(0,0)可能变成了(-100,-100 )(2000,2000)则变成了(1900,1900)
如果你绘制:MoveTo(-100,-100); LineTo(1900,1900);就是移动后的效果了么

创建多大的位图并不重要,重要的是你的算法上要能够在绘图区显示你要显示的内容。

设:放大倍数为zm x偏移xmod y偏移为ymod
楼主只需要进行一下运算就可以将以前(x0,y0)变换成(xn, yn)
xn = x0*zm + xmod;
yn = y0*zm + ymod;
因此在内存中创建绘图区大小的内存位图,不管你是画(-10000,-10000)还是画(10000,10000),画是画了,但是能留在内存位图上
只有内存绘图区域上的那些部分,而且显示的时候也只能显示这一部分。
下面是内存绘图的时候的代码(参考,移动滚动条的时候使用):
CDC *pdc=this->GetDC();
CDC MenDC;
CBitmap bm;

CRect rt;
GetClientRect(&rt);
MenDC.CreateCompatibleDC(pdc);
bm.CreateCompatibleBitmap(pdc,rt.Width(),rt.Height());
MenDC.SelectObject(&bm);
//-------------------------------------------------------------------

MenDC.FillSolidRect(0,0,rt.Width(),rt.Height(),RGB(255,255,255));

xn = x0*zm + xmod;
yn = y0*zm + ymod;

xn1 = x01*zm + xmod;
yn1 = y01*zm + ymod;

MenDC.MoveTo( xn, yn);
MenDC.LineTo(xn1,yn1);

//-------------------------------------------------------------------
pdc->BitBlt(0,0,rt.Width(),rt.Height(),&MenDC,0,0,SRCCOPY);

MenDC.DeleteDC();
bm.DeleteObject();
ReleaseDC(pdc);

在OnDraw当中只需要:
xn = x0*zm + xmod;
yn = y0*zm + ymod;

xn1 = x01*zm + xmod;
yn1 = y01*zm + ymod;

pDC.MoveTo( xn, yn);
pDC.LineTo(xn1,yn1);


剩下的工作就是要准确的确定放大倍数 zm 以及偏移量xmod ymod (根据滚动条位置得到)
ilovedrv 2008-12-14
  • 打赏
  • 举报
回复
参考CZoomView实现,双缓冲,映射,兼容位图都用到了

http://www.codeproject.com/KB/docview/McCZoomView.aspx


void CZoomView::OnPaint()
{
CPaintDC dc(this); // device context for painting
OnPrepareDC(&dc);
SetMapMode(&dc);

//////////////////////////////////////////////////////////////////////////
// Set the same viewport origin, because our bitmap (use for flicker-free)
// is created for drawing area only.
CPoint viewportOrg = dc.GetViewportOrg();
m_pdcMemory->SetViewportOrg(viewportOrg);
//////////////////////////////////////////////////////////////////////////

CBitmap* pOldBitmap = m_pdcMemory->SelectObject(m_pBitmap);
CRect rectUpdate(0,0,0,0);
dc.GetClipBox(&rectUpdate);
rectUpdate.InflateRect(1,1,1,1);
m_pdcMemory->SelectClipRgn(NULL);
m_pdcMemory->IntersectClipRect(&rectUpdate);
CBrush backgroundBrush((COLORREF) ::GetSysColor(COLOR_WINDOW));
CBrush* pOldBrush = m_pdcMemory->SelectObject(&backgroundBrush);
m_pdcMemory->PatBlt(rectUpdate.left,rectUpdate.top,
rectUpdate.Width(),rectUpdate.Height(),
PATCOPY);

//////////////////////////////////////////////////////////////////////////
// draw section
OnDraw(m_pdcMemory);
//////////////////////////////////////////////////////////////////////////

dc.BitBlt(rectUpdate.left,rectUpdate.top,
rectUpdate.Width(), rectUpdate.Height(),
m_pdcMemory,rectUpdate.left,rectUpdate.top,
SRCCOPY);
m_pdcMemory->SelectObject(pOldBitmap);
m_pdcMemory->SelectObject(pOldBrush);
}




zhoujianhei 2008-12-14
  • 打赏
  • 举报
回复
需要用到 SetWindowOrg,SetViewportOrg,SetWindowExt,SetViewportExt 几个函数,具体可参考。

http://www.cppblog.com/cppblog/archive/2008/11/10/9715.html

http://www.cppblog.com/cppblog/archive/2006/07/12/9716.aspx

19,464

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧