首先看一下效果圖!!
vs2017做的,我覺得跟vc6上做都是一樣的。
在MFC的view.h頭文件和view.cpp 裏新建自己的函數,
void CMFC1View::Bresenhamline(int x0, int y0, int x1, int y1, int color)
{
{
CDC *p;
p = GetDC();
int x, y, dx, dy, e;
p = GetDC();
int x, y, dx, dy, e;
dx = x1 - x0;
dy = y1 - y0;
dy = y1 - y0;
e = -dx;
x = x0;
y = y0;
x = x0;
y = y0;
if ((dx >= 0 && dy >= 0) || (dx <= 0 && dy <= 0)) //如果k大於0
{
if ((dx<0) || (dx == 0 && dy<0)) //dx小於0說明終點x
{
dx = -dx;//
x = x1;//
dy = -dy;
y = y1;
{
if ((dx<0) || (dx == 0 && dy<0)) //dx小於0說明終點x
{
dx = -dx;//
x = x1;//
dy = -dy;
y = y1;
}
if (dy<dx) //第一種情況,k-(0,1)//////////////
{
e = -dx;
for (int i = 0;i<dx;i++)
{
p->SetPixel(x, y, color);
x++;
e = e + dy + dy;
if (e >= 0)
{
y++;
e = e - dx - dx;
}
}
}
else //第二種情況,k-(1,max)
{
e = -dy;
for (int i = 0;i<dy;i++)
{
p->SetPixel(x, y, color);
y++;
e = e + dx + dx;
if (e >= 0)
{
x++;
e = e - dy - dy;
}
}
}
}
else //如果k小於0
{
int tempx, tempy; //保存x和y的絕對值
if (dx<0) //dx小於0說明終點x
{
tempx = -dx;
tempy = dy;
}
if (dy<0)
{
tempx = dx;
tempy = -dy;
}
if (dy<dx) //第一種情況,k-(0,1)//////////////
{
e = -dx;
for (int i = 0;i<dx;i++)
{
p->SetPixel(x, y, color);
x++;
e = e + dy + dy;
if (e >= 0)
{
y++;
e = e - dx - dx;
}
}
}
else //第二種情況,k-(1,max)
{
e = -dy;
for (int i = 0;i<dy;i++)
{
p->SetPixel(x, y, color);
y++;
e = e + dx + dx;
if (e >= 0)
{
x++;
e = e - dy - dy;
}
}
}
}
else //如果k小於0
{
int tempx, tempy; //保存x和y的絕對值
if (dx<0) //dx小於0說明終點x
{
tempx = -dx;
tempy = dy;
}
if (dy<0)
{
tempx = dx;
tempy = -dy;
}
if (tempx>tempy) //第三種情況,k-(-1,0)
{
if (dx<0) //dx小於0說明終點x
{
dx = -dx;
x = x1;
dy = -dy;
y = y1;
}
e = -dx;
for (int i = 0;i<dx;i++)
{
p->SetPixel(x, y, color);
x++;
e = e - dy - dy;
if (e >= 0)
{
y--;
e = e - dx - dx;
}
}
}
else //第四種情況,k-(-1,min)
{
if (dy<0)//dx小於0說明終點x
{
dx = -dx;
x = x1;
dy = -dy;
y = y1;
}
e = -dy;
for (int i = 0;i<dy;i++)
{
p->SetPixel(x, y, color);
y++;
e = e - dx - dx;
if (e >= 0)
{
x--;
e = e - dy - dy;
}
}
}
}
{
if (dx<0) //dx小於0說明終點x
{
dx = -dx;
x = x1;
dy = -dy;
y = y1;
}
e = -dx;
for (int i = 0;i<dx;i++)
{
p->SetPixel(x, y, color);
x++;
e = e - dy - dy;
if (e >= 0)
{
y--;
e = e - dx - dx;
}
}
}
else //第四種情況,k-(-1,min)
{
if (dy<0)//dx小於0說明終點x
{
dx = -dx;
x = x1;
dy = -dy;
y = y1;
}
e = -dy;
for (int i = 0;i<dy;i++)
{
p->SetPixel(x, y, color);
y++;
e = e - dx - dx;
if (e >= 0)
{
x--;
e = e - dy - dy;
}
}
}
}
}
在view.cpp裏重載鼠標的左鍵按下和彈起兩個函數,在view.h 定義公有的cpoint x1,x2;
void CMFC1View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息處理程序代碼和/或調用默認值
x1 = point;
CView::OnLButtonDown(nFlags, point);
}
{
// TODO: 在此添加消息處理程序代碼和/或調用默認值
x1 = point;
CView::OnLButtonDown(nFlags, point);
}
void CMFC1View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息處理程序代碼和/或調用默認值
x2 = point;
Bresenhamline(x1.x,x1.y,x2.x,x2.y,255);//直接調用函數,不會重繪製,
CView::OnLButtonUp(nFlags, point);
}
然後在鼠標彈起的函數裏調用就行,也可以先調用invalidate()函數,invalidate()函數會自動調用ondraw()函數,區別是一個是ondraw()裏調的後面的會覆蓋前面的,直接調用的不會覆蓋原來的畫出來的直線或者圓。哪個都行,看你的需要。
void CMFC1View::OnDraw(CDC* pDC)
{
CMFC1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if(m_nshape==1)
Bresenhamline(x1.x, x1.y, x2.x, x2.y, 255);//ondraw()裏調用會覆蓋前面畫的圖
if (m_nshape == 2)
{
radius = (x2.y - x1.y)*(x2.y - x1.y) + (x2.x - x1.x)*(x2.x - x1.x);
radius = sqrt(radius);
MidPointCircle(x1.x, x1.y, radius, 255);
}
// TODO: 在此處爲本機數據添加繪製代碼
}
{
CMFC1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if(m_nshape==1)
Bresenhamline(x1.x, x1.y, x2.x, x2.y, 255);//ondraw()裏調用會覆蓋前面畫的圖
if (m_nshape == 2)
{
radius = (x2.y - x1.y)*(x2.y - x1.y) + (x2.x - x1.x)*(x2.x - x1.x);
radius = sqrt(radius);
MidPointCircle(x1.x, x1.y, radius, 255);
}
// TODO: 在此處爲本機數據添加繪製代碼
}
以上是直線的輸出兩種方法哪個都行。
--------------------------------------------------------------------------
直線的函數是可以直接調用的,但是圓的函數涉及到,求半徑的問題,所以我在頭文件的公有數據裏定義了radius,方便直接調用,
圓的view.h 和view.cpp裏定義兩個函數。
int CMFC1View::DrawPoint(int x0, int y0, int x, int y, int color)
{
CDC *PDc = GetDC();
{
CDC *PDc = GetDC();
PDc->SetPixel(x + x0, y + y0, 255);
PDc->SetPixel(-x + x0, y + y0, 255);
PDc->SetPixel(-x + x0, -y + y0, 255);
PDc->SetPixel(x + x0, -y + y0, 255);
PDc->SetPixel(y + x0, x + y0, 255);
PDc->SetPixel(-y + x0, x + y0, 255);
PDc->SetPixel(-y + x0, -x + y0, 255);
PDc->SetPixel(y + x0, -x + y0, 255);
return (0);
}
void CMFC1View::MidPointCircle(int x0, int y0, int radus, int color)
{
}
void CMFC1View::MidPointCircle(int x0, int y0, int radus, int color)
{
int x, y, d;
x = 0;y = radus;d = int(1.25 - radus);
while (y >= x)
{
DrawPoint(x0, y0, x, y, color);
if (d<0)
{
d = d + 2 * x + 3;x++;
}
else
{
d = d + 2 * (x - y) + 5;x++;y--;
}
}
}
x = 0;y = radus;d = int(1.25 - radus);
while (y >= x)
{
DrawPoint(x0, y0, x, y, color);
if (d<0)
{
d = d + 2 * x + 3;x++;
}
else
{
d = d + 2 * (x - y) + 5;x++;y--;
}
}
}
圓的兩個函數,一個是定義八分之一的圓,另一個函數負責畫出對稱點,
radius=sqrt((x2.y-x1.y)*(x2.y-x1.y)+(x2.x-x1.x)*(x2.x-x1.x));
記得加上#include<cmath>
再把圓心和半徑傳進去進行,
invalidate()這個函數會自動調用ondraw() 函數,
如果不涉及到菜單項就不用invalidate() 調用ondraw()函數,而是 直接在你需要的地方調用該函數就行。
希望對你有幫助,