小弟最近在做毕设时需要打开一副BMP图片,然后拖动鼠标在图片上画出一个矩形。但因为图片很大,发现拖动矩形的时候,画矩形的速度跟不上鼠标的移动速度。后来改了一下,把图片的句柄改为全局变量,但又出现拖动鼠标,绘出的矩形是一抹黑。我表达的很不清楚,贴出主要代码来,我初来咋到,希望gg jj们帮帮忙,不胜感激!
BOOL CMyDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
// TODO: Add your specialized creation code here
HBITMAP hBmp=(HBITMAP)::LoadImage(NULL,lpszPathName,
IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if(hBmp==NULL)
return FALSE;
if(m_bmp.m_hObject!=NULL)
m_bmp.DeleteObject();
m_bmp.Attach(hBmp);
BITMAP bmpInfo;
m_bmp.GetBitmap(&bmpInfo);
m_nWidth=bmpInfo.bmWidth;
m_nHeight=bmpInfo.bmHeight;
m_bFlag=TRUE;
return TRUE;
}void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CMyDoc* pDoc =GetDocument();
int nHitTest;
nHitTest=pDoc->m_rectTracker.HitTest(point); CPoint scrollPos=GetScrollPosition();
CPoint offset;
offset.x=point.x+scrollPos.x;
offset.y=point.y+scrollPos.y;
if(pDoc->m_bFlag){ //是否打开了一副图片
if(nHitTest<0){
pDoc->m_rectTracker.m_rect.SetRect(-1,-1,-1,-1);
pDoc->m_startPt=offset;
m_bDrag=TRUE;
}
else{
pDoc->m_rectTracker.Track(this,offset,TRUE);
pDoc->m_rectTracker.m_rect.NormalizeRect();
OnDraw(this->GetDC());
}
} CScrollView::OnLButtonDown(nFlags, point);
}void CMyView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CMyDoc* pDoc =GetDocument();
CPoint scrollPos=GetScrollPosition();
CPoint offset;
offset.x=point.x+scrollPos.x;
offset.y=point.y+scrollPos.y;
if(m_bDrag){
pDoc->m_rectTracker.m_rect.SetRect(pDoc->m_startPt,offset);
pDoc->m_rectTracker.m_rect.NormalizeRect();
OnDraw(this->GetDC());
}
CScrollView::OnMouseMove(nFlags, point);
}void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
if(pDoc->m_bFlag==FALSE)
return;
//HBITMAP hBmp=(HBITMAP)::LoadImage(NULL,"D:\\afx\\example01.bmp",
// IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
//CBitmap bmp;
//bmp.Attach(hBmp);
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);
dcMem.SelectObject(&pDoc->m_bmp); //dcMem.SelectObject(&bmp);
pDoc->m_rectTracker.Draw(&dcMem);
pDC->BitBlt(0,0,pDoc->m_nWidth,pDoc->m_nHeight,&dcMem,0,0,SRCCOPY);
dcMem.DeleteDC();
}画出的橡皮筋一抹黑。在OnDraw里换成注释的代码又出现橡皮筋跟不上鼠标的问题,主要是装载图片太慢了。
另外当移动滚动条后,再拖动鼠标画橡皮筋,画出的矩形位置不对,我实在太菜了,实在不知道该怎么处理了,还请大大们帮帮忙,再次感谢!!
BOOL CMyDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
// TODO: Add your specialized creation code here
HBITMAP hBmp=(HBITMAP)::LoadImage(NULL,lpszPathName,
IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if(hBmp==NULL)
return FALSE;
if(m_bmp.m_hObject!=NULL)
m_bmp.DeleteObject();
m_bmp.Attach(hBmp);
BITMAP bmpInfo;
m_bmp.GetBitmap(&bmpInfo);
m_nWidth=bmpInfo.bmWidth;
m_nHeight=bmpInfo.bmHeight;
m_bFlag=TRUE;
return TRUE;
}void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CMyDoc* pDoc =GetDocument();
int nHitTest;
nHitTest=pDoc->m_rectTracker.HitTest(point); CPoint scrollPos=GetScrollPosition();
CPoint offset;
offset.x=point.x+scrollPos.x;
offset.y=point.y+scrollPos.y;
if(pDoc->m_bFlag){ //是否打开了一副图片
if(nHitTest<0){
pDoc->m_rectTracker.m_rect.SetRect(-1,-1,-1,-1);
pDoc->m_startPt=offset;
m_bDrag=TRUE;
}
else{
pDoc->m_rectTracker.Track(this,offset,TRUE);
pDoc->m_rectTracker.m_rect.NormalizeRect();
OnDraw(this->GetDC());
}
} CScrollView::OnLButtonDown(nFlags, point);
}void CMyView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CMyDoc* pDoc =GetDocument();
CPoint scrollPos=GetScrollPosition();
CPoint offset;
offset.x=point.x+scrollPos.x;
offset.y=point.y+scrollPos.y;
if(m_bDrag){
pDoc->m_rectTracker.m_rect.SetRect(pDoc->m_startPt,offset);
pDoc->m_rectTracker.m_rect.NormalizeRect();
OnDraw(this->GetDC());
}
CScrollView::OnMouseMove(nFlags, point);
}void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
if(pDoc->m_bFlag==FALSE)
return;
//HBITMAP hBmp=(HBITMAP)::LoadImage(NULL,"D:\\afx\\example01.bmp",
// IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
//CBitmap bmp;
//bmp.Attach(hBmp);
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);
dcMem.SelectObject(&pDoc->m_bmp); //dcMem.SelectObject(&bmp);
pDoc->m_rectTracker.Draw(&dcMem);
pDC->BitBlt(0,0,pDoc->m_nWidth,pDoc->m_nHeight,&dcMem,0,0,SRCCOPY);
dcMem.DeleteDC();
}画出的橡皮筋一抹黑。在OnDraw里换成注释的代码又出现橡皮筋跟不上鼠标的问题,主要是装载图片太慢了。
另外当移动滚动条后,再拖动鼠标画橡皮筋,画出的矩形位置不对,我实在太菜了,实在不知道该怎么处理了,还请大大们帮帮忙,再次感谢!!
pDC->BitBlt(0,0,pDoc->m_nWidth,pDoc->m_nHeight,&dcMem,0,0,SRCCOPY);这句话改一下:
CRect rectClient;
GetClientRect(&rectClient);
pDoc->m_rectTracker.Draw(&dcMem);
pDC->BitBlt(0,0,min(rectClient.Width()+1,pDoc->m_nWidth),min(rectClient.Height()+1,pDoc->m_nHeight),&dcMem,0,0,SRCCOPY);
pDoc->m_rectTracker.m_rect.SetRect(pDoc->m_startPt,offset);
m_startPt是记录鼠标按下的点,offset是算上了拖动滚动条后的点
对,你猜的真是我想做的。我是不用改变位图的,只要画出个矩形就行。异或画图我还是第一次听说,方便的话能给一个例子吗?3q
{
CClientDC dc(m_pWnd);
int iOld = dc.SetROP2(R2_NOTXORPEN);
CPoint pt(x,y);
CRect rcFocuse;
if( bDrawOld )
{
rcFocuse = CRect(m_ptStart, m_ptOld);
rcFocuse.NormalizeRect();
if( !rcFocuse.IsRectEmpty() )
DrawRect(dc, rcFocuse);
}
if( bDrawNew )
{
rcFocuse = CRect(m_ptStart, pt);
rcFocuse.NormalizeRect();
if( !rcFocuse.IsRectEmpty() )
DrawRect(dc, rcFocuse);
}
dc.SetROP2(iOld);
}
给你个函数,实现你说的功能.这个函数在OnMouseMove里调用,传入OnMouseMove函数的x,y坐标值(要调整一下,避免移动到窗口外面),另外在OnLButtonDown里记录下起点坐标m_ptStart,在OnMouseMove里将m_ptStart符值给m_ptOld,用来进行擦除操作
if(m_bDrag){
pDoc->m_ptOld=point;
DoDrawDragFocus(point.x,point.y,FALSE,TRUE);
}
我这样调用画出来的矩形也有很多黑色的竖条纹。
改成了
dc.Rectangle(rcFocuse);
您那句在我这里没编译过去
在OnMouseMove里要这样调DoDrawDragFocus(point.x,point.y,TRUE,TRUE);
意思是擦掉上次旧的,在新位置画出新的.在调用完后,要记得写m_ptOld = CPoint(nX, nY);记录下这次画点位置.
在OnLButtonUp里要这样调DoDrawDragFocus(nX, nY, XK_TRUE, XK_FALSE);
意思是擦掉最后一次的框框
在OnPaint里要这样调DoDrawDragFocus( 0, 0, XK_TRUE, XK_FALSE );
{
hDC.DrawFocusRect( rc );
}
那个是我自己写的接口,主要是为了扩充,可以修改这里面的代码,或者派生类去修改,改变拖动时的效果...