首先我要实现的功能如下:
1. 例如在1个对话框中的任意位置画2个点,然后用1条红色线将两点连接起来
2. 当鼠标左键点击所画的点或线时,可以响应动作,比如打开另一个对话框;
3. 所画的点或线可以响应鼠标的右键操作,比如右键点击所画线可弹出一个菜单(就是实现右键菜单的效果)因为是第1次做绘图方面的东,所以大家帮帮忙~~
思路和例程都可以~

解决方案 »

  1.   

    这个,用CDC类绘图是很容易的啊。
    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的连线上(应该允许一点误差,否则很难选中)。如果在,那么分别弹出对话框和显示菜单。
      

  2.   

    在事件处理中,判断点是否在pt1和pt2的连线上(应该允许一点误差,否则很难选中)。
    ==这个地方,可以用变通的办法,计算鼠标点击点和pt1以及pt2的距离之和,并计算pt1和pt2间的距离,比较这两个距离之差,如果小于一个固定值,那么可以认为选中。这个固定值可以根据实际情况设定,比如3,这个值越大,越容易选中,因为允许的偏差越大。
      

  3.   

    我编译了代码,可以通过,但是什么都没有啊.我把下面的代码段写在一个Button的函数里
    ...
    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();
    ...怎么回事啊.
      

  4.   

    这是我的OnPaint,应该在哪呢?我试还是不行哦
    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();
    }
      

  5.   

    当然是放在else中的CDialog::OnPaint();上面了如果通过单击一个按钮来画图,就如pinel所说,应将
    CPaintDC dc(this);
    改成
    CClientDC dc(this);
    但这样画图是不持久的,当界面刷新时线就没了,一般情况下,在对话框中应在OnPaint中画图。
      

  6.   

    晕倒
    IsIconic()是指最小化状态,is iconic=是不是图标化了
    放在else里面拉
      

  7.   

    pinel() 的观点是对的,测试通过,可以放在一个Button函数里.
    由于手头上暂时没有参考书,所以只好依靠大家了.
    以下代码通过.实现的功能是在一个对话框中画一条线.
    ...
    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();
    ...好了,继续完成其他功能.
      

  8.   

    xiao_fang(frank) 的说法也是对的.
    可是如果我是要实现"实时的改变点或线的位置"该怎么办?
    也就是说,点和线的位置是在不断的变化中,是不可预料结果的.
    该怎么办?
      

  9.   

    同意并修改
    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
    );
    基本上可以解决你的问题。
      

  10.   

    代码段放在OnPaint()中的else中,
    ----------------------------------
    那我怎么在外部改变Point的坐标呢,比如说,通过Edit输入坐标之类的,当输入坐标后能立即显示出来.
    我尝试了设置公共类变量,但是Point值确实已经改变,但是没有在界面上反应出来,非要最小化一次,或者窗口被覆盖一下才可以.
    这是为什么呢?
      

  11.   

    我现在的解决方法是:
    1. 获取新的Point坐标,然后先在Button函数中画一次,
    2. OnPaint中获得了该新坐标,在不停的重复画这样做就可以立即显示画线结果,并且被覆盖或者最小化后不会消失.还有没有更好的方法?
      

  12.   

    如果是这样,那么你应该单独封装一个函数。该函数的参数为CDC和CPoint,当点击按钮时,获取点击位置,调用该函数进行绘制,这里不要调用OnPaint。在OnPaint中,需要在:
    else
    {
    CDialog::OnPaint();
    }
    的CDialog::OnPaint()之后调用这个函数。
      

  13.   

    不用画两次的。
    1.坐标声明成类变量
    2.坐标改变的时候给变量赋上新值
    3.OnPaint里面做画线功能
    4.需要重画的地方写Invalidate();
      

  14.   

    谢谢大家~4.需要重画的地方写Invalidate();
    ----------------------------------------
    这句太有用了,哈哈.画线已经成功.再问一下,如果想"擦除"所画的线,是不是就是把这条线画成和背景色一样的颜色?
    有没有其他办法?
      

  15.   

    所有的功能都已实现.现总结如下:
    ==================================
    1. 画点和线:按照 happyparrot(快乐鹦鹉), pinel(), xiao_fang(frank)的方法都已实现.
    2. 识别是否点击点:按照 cici2006(cici_2006) 的方法,把圆点看成一个矩形,虽然有小小误差,但如果圆点比较小的话,误差可以忽略不计.这样只要知道的圆心坐标,就可以确定一个同样以圆心为中心的矩形的坐标,然后判断鼠标是否点击在该矩形范围内即可.
    3. 识别是否点击直线:按照 happyparrot(快乐鹦鹉) 的方法, 计算鼠标当前点击的那一个点到直线起点、终点的距离,再判断它们之和与直线长度之差.这里的误差值我定的是 0.5 (因为我画直线的宽度是6).效果不错.好了,结贴~~