我打算在一个视图中粘贴很多个位图,也就是鼠标左键点击一下就粘贴一个位图,现在遇到的问题就是,当我第一次点击的时候能够正确粘贴位图,但是点击第二次的时候,第一次的位图消失了,而第二次的位图能够正确粘贴,请哪位高手能指教一下小弟,万分感谢。能不能给出原代码,谢谢救命之恩了
解决方案 »
- 问个udp 广播问题
- 网页中超链接问题
- CView继承类获得文档类指针出错
- 有没有好的办法把十六进制串"4A6F6E6573",换为二进制串"0100101001101111011011100110010101110011"
- c++ builder 和 c#哪个开发界面 比较好?
- 那位大虾知道那里有vc类库方面的书下载!
- richedit问题。绝对菜。
- 请做过监视QQ消息程序的高手进入
- 在vc中CString和char*如何实现转换!
- 好烦! 怎么知道WINDOWS 系统打印机 当前的状态,是忙 还是空闲,或者是根本就没有连接呢!!
- 在对话框中如何定义控件的大小和位置?
- 在vc6 IDE下如何实现每次编译的时候都编译一个指定的文件?
{//»­½Úµã
CConfigureDoc* pDoc=GetDocument();
CBitmap bitmap;
bitmap.LoadBitmap (bitmapid);
BITMAP bmpInfo;
bitmap.GetBitmap (&bmpInfo);
CDC dcMemory;
dcMemory.CreateCompatibleDC (pDC);
CBitmap* pOldBitmap=dcMemory.SelectObject (&bitmap); CSize size;
size=bitmap.GetBitmapDimension ();
m_cNodeSize=size; CPoint bpt;//·ÅÖù¦ÄÜ¿éµÄ×ø±ê
bpt.x =pt.x -bmpInfo.bmWidth/2;
bpt.y =pt.y -bmpInfo.bmHeight/2;
CConfigNode* ds;
ds=new CConfigNode(pDoc);
// CMapIntToDataStruct ds=pDoc->m_pMap;
// int ct;
// int key;
// ct=ds.GetCount();
// if(ct==0)
// key=1;
// else
// key=ct+1;
// ds.SetAt(key,pNode); ds->LeftLinkPoint =CPoint(pt.x-size.cx/2,pt.y );
ds->RightLinkPoint =CPoint(pt.x+size.cx /2,pt.y); pDC->BitBlt (bpt.x,bpt.y,bmpInfo.bmWidth ,bmpInfo.bmHeight ,&dcMemory,0,0,SRCCOPY);
// dcMemory.SelectObject (pOldBitmap);
//»­½ÚµãÓëÖ±ÏßµÄÁ¬½Ó×ø±êµã
// pDC->Ellipse (ds->LeftLinkPoint.x-2,ds->LeftLinkPoint.y-2,ds->LeftLinkPoint.x+2,ds->LeftLinkPoint.y+2);
// pDC->Ellipse (ds->RightLinkPoint.x-2,ds->RightLinkPoint.y-2,ds->RightLinkPoint.x+2,ds->RightLinkPoint.y+2); return TRUE;
}
void CConfigView::OnDraw (CDC* pDC)
{//ÔÚÊÓͼÖл­Í¼
// if (GetDocument()->DrawTree(pDC, m_ptStart, m_pSelectedNode) == -1)
// TRACE0("´íÎó: CConfigureDoc::DrawTreeµ÷ÓÃʧ°Ü!!\n");
CConfigureDoc* pDoc=GetDocument();
ASSERT_VALID(pDoc);
BOOL flag;
flag=GetSelectionState();
UINT bitmap;
if(flag && pDoc!=NULL)
{
bitmap=GetDrawBitmapId();
Draw(pDC,m_pMousePt,bitmap);
pDoc->SetFunctionPoint (m_pMousePt);
pDoc->IncreaceCounter ();
pDoc->InsertNode (bitmap);
}
}
我就看了ondraw,没看draw
我感觉ondraw里面没有循环能实现ondraw吗?
在你每次粘贴一个位图的同时
把这个位图的信息保存到一个链表/数组里面
ondraw的时候
遍粒这个链表/数组,draw
文档类里面一个Clist,存放位置和位图信息
视图类里面一个draw函数,根据位置来显示位图
视图类里面的ondraw函数,遍离clist,调用draw
在视图中添加变量:CDC m_memdc;
在视图初始化的时候,
CClientDC dc(this);
CRect rect;
GetClientRect(&rect);
CBitmap bm;
bm.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());//和视图一样大小的bm
m_memdc.CreateCompatibleDC(&dc);在mouse_down事件处理中,只用在m_memdc中画图:
CDC tmpdc;
//加载位图,把位图选入tmpdc,我就不写了
m_memdc.Bitblt(x,y,bm.Width(),bm.Height(),&tmpdc,0,0,SRCCOPY);
//将tmpdc拷贝到m_memdc,位置可以选鼠标单击的位置
CRect rect;
GetClientRect(&rect);
InvalidateRect(rect,false); //强制刷新,系统会调用ondraw在ondraw中:
CRect rect;
GetClientRect(&rect);
pDC->bitblt(0,0,rect.Width(),rect.Height(),&m_memdc,0,0,SRCCOPY);//基本上这就可以实现你要的功能
要注意的是:要在适当的时候和地方释放资源,比如位图,DC等。
你的draw函数怎么做的?
ondraw的函数里面循环clist
对每个位图都draw
不可以吗?
void CConfigView::OnLButtonDown (UINT nFlags,CPoint point)
{
BOOL flag;
flag=GetSelectionState();
UINT bitmapid;
CBitmap bitmap;
if(m_bSelectFlag&&flag)
{
CDC tmpdc;
tmpdc.CreateCompatibleDC (&m_memDC);
bitmapid=GetDrawBitmapId();
bitmap.LoadBitmap (bitmapid);
BITMAP bmpInfo;
bitmap.GetBitmap (&bmpInfo);
CBitmap* pOldBitmap=tmpdc.SelectObject (&bitmap);
CSize size;
size=bitmap.GetBitmapDimension ();
m_cNodeSize=size;
m_memDC.BitBltpoint.x,point.y,bmpInfo.bmWidth ,
bmpInfo.bmHeight ,&tmpdc,0,0,SRCCOPY);
m_pMousePt=point; CRect rect;
GetClientRect(&rect);
InvalidateRect(rect,false);
}
CView::OnLButtonDown (nFlags,point);
}
void CConfigView::OnDraw (CDC* pDC)
{
CRect rect;
GetClientRect(&rect);
pDC->BitBlt(0,0,rect.Width(),rect.Height
(),&m_memDC,0,0,SRCCOPY);}
void CConfigView::OnInitialUpdate ()
{
m_zoomNum = CSize(100, 100);
m_zoomDenom = CSize(100, 100); CClientDC dc(this);
CRect rect;
GetClientRect(&rect);
CBitmap bm;
bm.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());
m_memDC.CreateCompatibleDC(&dc);
CScrollView::OnInitialUpdate();
}
你应该找本书看看
只需要重绘现在clientrect里面的这几个
ondraw的时候
要比较位置和getclipbox这个rect的位置
如果需要ondraw就draw,否则不draw
CDC tmpdc;
tmpdc.CreateCompatibleDC (&m_memDC);
可以把这个tmpdc做成全局的,这样每次增加贴图先往这个内存中贴完后再把这个tmpdc贴到窗口中去,ok?
CDC* MemDC = new CDC;
CBitmap *oldBitmap;MemDC->CreateCompatibleDC(pDC);
oldBitmap = MemDC->SelectObject(&blank);//draw the elements
MyCollection.Draw(MemDC);pDC->BitBlt(0,0,FrameWidth,FrameHeight,MemDC,0,0,SRCCOPY);
MemDC->SelectObject(oldBitmap);delete MemDC;
CDC memdc;
memdc.CreateCompatibleDC(&dc);
memdc.SelectObject( &bitmap ); CDC pDC;
// create a compatible memory dc
pDC.CreateCompatibleDC(&dc);
// associate the back bitmap object to the compatible memory dc object
pDC.SelectObject(&m_bitmapObj);
//paint the compatible dc with back bitmap to the first compatible dc with window default paint
memdc.BitBlt( 0,
0,
recttree.Width(),
recttree.Height(),
&pDC,
recttree.left,
recttree.top,
SRCAND);
1, draw(point, bitmap)
{
画图}
2,onlbuttonup(point)
{
draw(point, bitmap);
cdocument *pdoc = getdocument();
pdoc->m_list.add(point, bitmap); //point位置信息, bitmap位图信息
InvalidateRect(rect); //这个rect可以优化,getclipbox和你位图的位置比较找到最小的区域
}
3,ondraw()
{
for(pdoc->m_list)
{
if( 比较位置和rect)
draw()
}
}大概是这样的,还有很多小东西需要修
你试试吧
OnLButtonDown里做对CDC拷贝,蒋新增加的图拷贝到全局的DC对象中
OnDraw 或 OnPaint 做
pDC->BitBlt
将全局DC对象画在窗口上
CBitmap m_bitmap;
m_bitmap.LoadBitmap (bitmapid);void CConfigView::OnLButtonDown (UINT nFlags,CPoint point)
{//»­½Úµã if (!m_dcToPaint.m_hDC)
{
dcMemory.CreateCompatibleDC (pDC);
}
CDC dcMemory;
dcMemory.CreateCompatibleDC (pDC);
CBitmap* pOldBitmap=dcMemory.SelectObject (&m_bitmap); CSize size;
size=m_bitmap.GetBitmapDimension ();
m_cNodeSize=size; CPoint bpt;
bpt.x =pt.x -bmpInfo.bmWidth/2;
bpt.y =pt.y -bmpInfo.bmHeight/2;
m_dcToPaint.BitBlt (bpt.x,bpt.y,bmpInfo.bmWidth ,bmpInfo.bmHeight ,&dcMemory,0,0,SRCAND);
dcMemory.SelectObject (pOldBitmap);
dcMemory.DeleteDC();
}void CConfigView::OnDraw (CDC* pDC)
{
pDC->BitBlt (bpt.x,bpt.y,bmpInfo.bmWidth ,bmpInfo.bmHeight ,&m_dcToPaint,0,0,SRCCOPY);
}z最后在程序退出前
m_dcToPaint.DeleteDC();
m_bitmap.DeleteObject();
void CConfigView::OnDraw (CDC* pDC)
{
pDC->BitBlt (0,0,(窗口宽),(窗口高),&m_dcToPaint,0,0,SRCCOPY);
}
if (!m_dcToPaint.m_hDC)
{
dcMemory.CreateCompatibleDC (pDC);
}
CDC dcMemory;
不大对,你看呢?
嗬嗬,写错了
CPaintDC dc(this); // device context for painting
dcToPaint.CreateCompatibleDC (&dc);dcMemory创建也这样
dcMemory.CreateCompatibleDC (&dc);
BOOL CGdiObject::Attach(HGDIOBJ hObject)
{
ASSERT(m_hObject == NULL); // only attach once, detach on destroy
if (hObject == NULL)
return FALSE;
CHandleMap* pMap = afxMapHGDIOBJ(TRUE); // create map if not exist
ASSERT(pMap != NULL);
pMap->SetPermanent(m_hObject = hObject, this);
return TRUE;
}
请问原因何在?
竟然还没有解决 sinhighly(非典型程序员) :
void CConfigView::OnDraw (CDC* pDC)
{
pDC->BitBlt (bpt.x,bpt.y,bmpInfo.bmWidth ,bmpInfo.bmHeight ,&m_dcToPaint,0,0,SRCCOPY);
}加入point1有一个位图
现在在point2又画了一个位图,
加入point1和point2都在重绘区域
你point1的那个位图重绘了吗?
look look 上面的代码
前面绘的图都画在m_dcToPaint全局变量里了,好像没有丢吧pscqll(飞翔) :
算了,我还是自己调以下在给你吧
{
CTestpaintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDC->BitBlt (0,0,10000,10000,&m_dcToPaint,0,0,SRCCOPY);}void CTestpaintView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CPaintDC dc(this);
CRect rectclient;
//get rect of this tree control
GetClientRect(&rectclient); if (!m_dcToPaint.m_hDC)
{
m_dcToPaint.CreateCompatibleDC (&dc);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dc, rectclient.Width(), rectclient.Height());
m_dcToPaint.SelectObject( &bitmap );
CBrush brush;
brush.CreateSysColorBrush(COLOR_WINDOW);
m_dcToPaint.FillRect(rectclient,&brush);
}
CDC dcMemory;
dcMemory.CreateCompatibleDC (&dc);
CBitmap* pOldBitmap=dcMemory.SelectObject (&m_bitmap); CSize size;
size=m_bitmap.GetBitmapDimension ();
size.cx = 32;
size.cy = 32; CPoint bpt;
bpt.x =point.x -size.cx/2; //bmpInfo.bmWidth/2;
bpt.y =point.y -size.cy/2;//bmpInfo.bmHeight/2;
m_dcToPaint.BitBlt (bpt.x,bpt.y,size.cx ,size.cy ,&dcMemory,0,0,SRCCOPY);
dcMemory.SelectObject (pOldBitmap);
dcMemory.DeleteDC();
RedrawWindow();
CView::OnLButtonDown(nFlags, point);
}