使用CClientDC在静态控件上绘制永久图片(Visual C+;+;2010 MFC)

使用CClientDC在静态控件上绘制永久图片(Visual C+;+;2010 MFC),mfc,visual-c++-2010,Mfc,Visual C++ 2010,一般来说,我对MFC和windows编程相当陌生,我需要制作一种交互式图形,在该图形中,我可以单击画布中的不同点,并在单击的点之间绘制线 到目前为止,我已经能够在静态picturebox控件中绘制标准形状 但是,问题是,如果我将包含by draw figure的对话框部分拖到屏幕边缘之外,当我将其移回时,所绘制的图形将被擦除 我需要它永久保持在静态控件中 在阅读了几个论坛问题后,我发现我需要从CStatic类派生出自己的静态控件类,然后在OnPaint()函数中为这个新的静态控件编写代码,但我无

一般来说,我对MFC和windows编程相当陌生,我需要制作一种交互式图形,在该图形中,我可以单击画布中的不同点,并在单击的点之间绘制线
到目前为止,我已经能够在静态picturebox控件中绘制标准形状
但是,问题是,如果我将包含by draw figure的对话框部分拖到屏幕边缘之外,当我将其移回时,所绘制的图形将被擦除
我需要它永久保持在静态控件中
在阅读了几个论坛问题后,我发现我需要从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_画布内绘制一个椭圆,该画布是一个静态图片框控件,只要按下命令按钮

----更新----
我能够在我的diaog框中使用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_uu消息适合这样做?我假设应该是
WM_LBUTTONUP
WM_LBUTTONDOWN
,但我不确定。另外,假设我需要在画布上单击的两点之间画一条线。我应该把画这条线的代码放在哪里?它应该放在OnPaint()函数还是鼠标事件处理程序函数中?

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

在论坛问题中阅读时,您是否从CStatic派生了自己的类?如果这样做,请使用MFC类wizzard创建类,这样在添加OnPaint处理程序时会更容易。我还没有完全弄清楚如何使用类向导派生类,坦率地说,到目前为止,我甚至不确定这是否正是我需要做的;例如,假设我从CStatic派生了一个名为CStatic_my的类,它的对象应该表示我的自定义静态控件;我该如何准确地将其放置在对话框中?它是否在工具箱中显示为图标?或者我必须自己在OnInitDialog()中创建它,在这种情况下,我可能还必须指定它的坐标,我不知道如何将wizzard文档化:右键单击project,然后单击Class wizzard,然后添加Class(MFC Class),然后单击base Class=CStatic。您可以使用对话框编辑器将静态控件放入对话框(并为控件添加一个变量/将其子类化),但也可以自己动态创建控件。使用对话框编辑器是更简单的方法。“您可以使用对话框编辑器将静态控件放入对话框(并为控件添加变量/为其子类)”。我很抱歉,如果这是一个非常初级的问题,但我不知道这意味着什么。你是说我可以通过表单设计器包含自定义静态控件吗?此外,类向导创建了一种带有空构造函数和其他函数的模板。要开始使用派生类,是否需要在这些函数中包含任何代码?或者我可以开始创建这个类的对象并使用CStatic提供的成员吗?我假设我需要在代表我的对话框的类中创建自定义静态控件的对象,但我不确定如何将其放置在我想要的位置。谢谢。我已经注释掉了用于在
OnInitDialog()函数中创建控件的代码。它将使用表单设计器放置的
CStatic
替换为我的
CMy_Static
控件。我之所以知道这一点,是因为我在CMY\u Static的
OnPaint()中放置了绘制椭圆的代码。但是,我在表单设计器中为
CStatic
控件定义的边界完全消失了。在何处以及如何指定CMy\U Static的外观?