首先我要实现的功能如下:
1. 例如在1个对话框中的任意位置画2个点,然后用1条红色线将两点连接起来
2. 当鼠标左键点击所画的点或线时,可以响应动作,比如打开另一个对话框;
3. 所画的点或线可以响应鼠标的右键操作,比如右键点击所画线可弹出一个菜单(就是实现右键菜单的效果)因为是第1次做绘图方面的东,所以大家帮帮忙~~
思路和例程都可以~
1. 例如在1个对话框中的任意位置画2个点,然后用1条红色线将两点连接起来
2. 当鼠标左键点击所画的点或线时,可以响应动作,比如打开另一个对话框;
3. 所画的点或线可以响应鼠标的右键操作,比如右键点击所画线可弹出一个菜单(就是实现右键菜单的效果)因为是第1次做绘图方面的东,所以大家帮帮忙~~
思路和例程都可以~
1.在OnPaint中:
CPen pen(PS_SOLID,1,RGB(255,0,0));
dc.SelectObject(&pen);
dc.MoveTo(pt1);
dc.LineTo(pt2);
pen.DeleteObject();
就可以了。至于2和3,你必须在对话框中将pt1和pt2作为成员变量。
然后分别响应OnLButtonDown和OnRButtonDown。
在事件处理中,判断点是否在pt1和pt2的连线上(应该允许一点误差,否则很难选中)。如果在,那么分别弹出对话框和显示菜单。
==这个地方,可以用变通的办法,计算鼠标点击点和pt1以及pt2的距离之和,并计算pt1和pt2间的距离,比较这两个距离之差,如果小于一个固定值,那么可以认为选中。这个固定值可以根据实际情况设定,比如3,这个值越大,越容易选中,因为允许的偏差越大。
...
CPoint point1,point2;
CPaintDC dc(this);
CPen pen(PS_SOLID,1,RGB(255,0,0));point1.x=30;
point1.y=80;
point2.x=80;
point2.y=30;dc.SelectObject(&pen);
dc.MoveTo(point1);
dc.LineTo(point2);
pen.DeleteObject();
...怎么回事啊.
if (IsIconic())
{
CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
CPaintDC dc(this);
改成
CClientDC dc(this);
但这样画图是不持久的,当界面刷新时线就没了,一般情况下,在对话框中应在OnPaint中画图。
IsIconic()是指最小化状态,is iconic=是不是图标化了
放在else里面拉
由于手头上暂时没有参考书,所以只好依靠大家了.
以下代码通过.实现的功能是在一个对话框中画一条线.
...
CPoint point1,point2;
CClientDC dc(this); //此处作了修改
CPen pen(PS_SOLID,1,RGB(255,0,0));point1.x=30;
point1.y=80;
point2.x=80;
point2.y=30;dc.SelectObject(&pen);
dc.MoveTo(point1);
dc.LineTo(point2);
pen.DeleteObject();
...好了,继续完成其他功能.
可是如果我是要实现"实时的改变点或线的位置"该怎么办?
也就是说,点和线的位置是在不断的变化中,是不可预料结果的.
该怎么办?
CPen pen(PS_SOLID,1,RGB(255,0,0));
dc.SelectObject(&pen);
dc.MoveTo(pt1);
dc.LineTo(pt2);
pen.DeleteObject();------------------------修改
CPen pen(PS_SOLID,1,RGB(255,0,0));
CPen *oldPen;
oldPen = dc.SelectObject(&pen);
dc.MoveTo(pt1);
dc,LineTo(pt2);
dc.SelectObject(oldPen);
pen.DeleteObject();
-------------------------
你把代码段放在OnPaint()中的else中。
-------------------------
关于第二个与第三个问题:
你可以在画线的同时保存这两个点,如果你觉的需要有很多个点,你就做成数组或
vector;
这样保存。
在有左键或右键消息的时候把这鼠标值转变成客户区值;
ScreenToClient(
LPPOINT lpPoint
)
判断这个点是否在鼠标值的范围内。
BOOL PtInRect(
CONST RECT *lprc, // rectangle
POINT pt // point
);
基本上可以解决你的问题。
----------------------------------
那我怎么在外部改变Point的坐标呢,比如说,通过Edit输入坐标之类的,当输入坐标后能立即显示出来.
我尝试了设置公共类变量,但是Point值确实已经改变,但是没有在界面上反应出来,非要最小化一次,或者窗口被覆盖一下才可以.
这是为什么呢?
1. 获取新的Point坐标,然后先在Button函数中画一次,
2. OnPaint中获得了该新坐标,在不停的重复画这样做就可以立即显示画线结果,并且被覆盖或者最小化后不会消失.还有没有更好的方法?
else
{
CDialog::OnPaint();
}
的CDialog::OnPaint()之后调用这个函数。
1.坐标声明成类变量
2.坐标改变的时候给变量赋上新值
3.OnPaint里面做画线功能
4.需要重画的地方写Invalidate();
----------------------------------------
这句太有用了,哈哈.画线已经成功.再问一下,如果想"擦除"所画的线,是不是就是把这条线画成和背景色一样的颜色?
有没有其他办法?
==================================
1. 画点和线:按照 happyparrot(快乐鹦鹉), pinel(), xiao_fang(frank)的方法都已实现.
2. 识别是否点击点:按照 cici2006(cici_2006) 的方法,把圆点看成一个矩形,虽然有小小误差,但如果圆点比较小的话,误差可以忽略不计.这样只要知道的圆心坐标,就可以确定一个同样以圆心为中心的矩形的坐标,然后判断鼠标是否点击在该矩形范围内即可.
3. 识别是否点击直线:按照 happyparrot(快乐鹦鹉) 的方法, 计算鼠标当前点击的那一个点到直线起点、终点的距离,再判断它们之和与直线长度之差.这里的误差值我定的是 0.5 (因为我画直线的宽度是6).效果不错.好了,结贴~~