【问题标题】:Drawing permanent picture on a static control using CClientDC (Visual C++ 2010 MFC)使用 CClientDC (Visual C++ 2010 MFC) 在静态控件上绘制永久图片
【发布时间】:2013-06-29 10:15:36
【问题描述】:

总的来说,我对 MFC 和 windows 编程还很陌生,我需要制作一种交互式图形,我可以在其中单击画布中的不同点并在单击的点之间画线
到目前为止,我已经能够在静态图片框控件中绘制标准形状
但是问题是,如果我将对话框中包含绘制图形的部分拖到屏幕边缘之外,当我把它带回来时,绘制的图形会被删除
我需要它永久保持在静态控制中
在阅读了几个论坛问题后,我发现我需要从 CStatic 类派生出我自己的静态控件类,然后在 OnPaint() 函数中为这个新的静态控件编写我的代码,但我不明白如何正确执行,因为要使用OnPaint 函数和 WM_PAINT 正确我需要使用 Visual Studio 中提供的一些向导函数,但我找不到任何简单的教程来教如何做到这一点
任何想法将不胜感激
这是我到目前为止的代码

void Cpaint_using_dcDlg::OnBnClickedDraw()
{
    // TODO: Add your control notification handler code here
    COLORREF black = RGB(255, 0, 0);
    CPen pen(PS_SOLID, 1, black);
     CClientDC Dc(GetDlgItem(IDC_CANVAS));
    // CClientDC Dc(this);
    // Dc.MoveTo(0,0);
    Dc.SelectObject(&pen);
    CPoint point1(0,0);
    point1.x = 0;
    point1.y = 0;
    CPoint point2(0,0);
    point2.x = point1.x + 50;
    point2.y = point1.y + 50;
    Dc.Ellipse(CRect(point1, point2));
}

这会导致在 IDC_CANVAS 中绘制一个椭圆,它是一个静态图片框控件,每当按下命令按钮时

---- 更新 ----
我能够使用 OnInitDialog() 函数中的以下代码在我的对话框中创建静态控件

BOOL Cpaint_using_dcDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);         // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon

    // TODO: Add extra initialization here
    CRect rect;
    CWnd *pWnd = GetDlgItem(IDC_CANVAS);
    pWnd->GetWindowRect(&rect);
    ScreenToClient(&rect); //optional step - see below
    // my_canvas.Create(NULL, WS_CHILD|WS_VISIBLE|SS_BLACKFRAME|SS_BLACKRECT|SS_ETCHEDFRAME , rect, this, 0x1111);
    my_canvas.Create(NULL, WS_CHILD|WS_VISIBLE|SS_BLACKFRAME, rect, this, 0x1111);

    return TRUE;  // return TRUE  unless you set the focus to a control
}

下一步是能够在这个静态控件上绘制图形,即使这个对话框被另一个对话框重叠也不会消失。为此,在我的自定义静态控件的类中,我使用类向导包含了一个 OnPaint() 函数,并包含了绘制椭圆的代码,如下所示:

void CMy_Canvas::OnPaint()
{
    CPaintDC dc(this); // device context for painting
    // TODO: Add your message handler code here
    // Do not call CStatic::OnPaint() for painting messages
    CPen pen;
    dc.SelectObject(&pen);
    // CPoint curPos;
    // GetCursorPos(&curPos);
    CPoint point1(0,0);
    point1.x = 0;
    point1.y = 0;
    CPoint point2(0,0);
    point2.x = point1.x + 50;
    point2.y = point1.y + 50;
    dc.Ellipse(CRect(point1, point2));
}

但是现在它绘制了椭圆,但是使用my_canvas.Create(NULL, WS_CHILD|WS_VISIBLE|SS_BLACKFRAME, rect, this, 0x1111); 生成的静态控件的轮廓消失了。为什么会发生这种情况,我该如何避免?另外,我真正需要做的是让这个图表具有交互性,这样我就可以通过点击鼠标来改变我将在这个控件上显示的曲线的结构。哪个 WM_ 消息适合执行此操作?我假设它应该是 WM_LBUTTONUP 或 WM_LBUTTONDOWN 但我不确定。另外,假设我需要在画布上单击的两点之间画一条线。我应该把画这条线的代码放在哪里?它应该放在 OnPaint() 函数中还是鼠标事件处理函数中?

【问题讨论】:

  • 您是否在阅读论坛问题时从 CStatic 派生了自己的类?如果这样做,请使用 MFC 类向导创建类,这样在添加 OnPaint 处理程序时会更容易。
  • 我还没有完全弄清楚如何使用类向导来派生类,坦率地说,到目前为止我什至不确定这是否正是我需要做的;例如,假设我从 CStatic 派生了一个名为 CStatic_my 的类,它的对象应该代表我的自定义静态控件;我将如何将它放在我的对话框中?它是否在工具箱中显示为图标?还是我必须自己在 OnInitDialog() 中创建它,在这种情况下我可能还必须指定它的坐标,我不知道该怎么做
  • 类向导:右键单击项目,然后类向导,然后添加类(MFC 类),然后基 class=CStatic。您可以使用对话框编辑器将静态控件放入对话框中(并为控件/子类添加一个变量),但您也可以自己动态创建控件。使用对话框编辑器是更简单的方法。
  • “您可以使用对话框编辑器将静态控件放入对话框中(并为控件/子类添加变量)”。如果这是一个非常初学者的问题,我深表歉意,但我不确定这意味着什么。您的意思是我可以通过表单设计器包含我的自定义静态控件吗?此外,类向导创建了一种带有空构造函数和其他函数的模板。我是否需要在这些函数中包含任何代码才能开始使用我的派生类?或者我可以开始创建这个类的对象并使用 CStatic 提供的成员吗?
  • 我假设我需要首先在代表我的对话框的类中创建自定义静态控件的对象,但我不确定如何将它放置在我想要的位置

标签: mfc visual-c++-2010


【解决方案1】:

您不需要在 OnInitDialog 中创建自定义静态控件。使用您在可视化设计器中创建的静态控件 (IDC_CANVAS)。在该设计器中,右键单击控件并添加控件成员变量。将该控制成员变量类型从 CStatic 更改为 CMyCanvas。现在您的自定义控件类应该会收到 OnPaint 调用。

【讨论】:

  • 哇它好用。非常感谢。我已经注释掉了用于在OnInitDialog() 函数中创建控件的代码。它用我的CMy_Static 控件替换了我使用表单设计器放置的CStatic。我知道这一点是因为我在CMY_Static 的OnPaint() 中放置了绘制椭圆的代码。但是,我为表单设计器中的CStatic 控件定义的边框完全消失了。我在哪里以及如何指定 CMy_Static 的外观?
猜你喜欢
  • 2012-02-08
  • 2013-08-02
  • 1970-01-01
  • 2014-07-24
  • 2016-06-13
  • 1970-01-01
  • 1970-01-01
  • 2015-08-13
  • 1970-01-01
相关资源
最近更新 更多