在 MFC 应用中绘制图形C++
Drawing a Graph in C++ MFC App
我正在编写一个C++MFC应用程序来控制制造环境中的机器。 这个应用程序还需要在非常短的周期内分析大量信息。
出于测试目的和长期维护,我需要能够绘制来自控制台上的传感器的数据。我可能完全忽略了一个选项(随意提出其他选项),但我的研究使我开始使用图片控件。
我通过使用OnPaint()
成功地绘制了此控件。我的问题是我需要每隔几秒钟重新绘制一个新图像,并且我不能重复调用OnPaint()
或向其传递数据。
如何创建可用于在图片控件上重复绘制的新函数?此外,这是我第一次尝试 MFC 应用程序,因此请在适当的层面上进行解释。谢谢!
class CPicture : public CStatic
{
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnPaint();
};
BEGIN_MESSAGE_MAP(CPicture, CStatic)
ON_WM_PAINT()
END_MESSAGE_MAP()
void CPicture::OnPaint()
{
CPaintDC dc(this); // device context for painting
dc.SelectStockObject(BLACK_BRUSH);
dc.Rectangle(5, 50, 1000, 51);
}
我想问题是如何以及在哪里访问它
//Picture
class CPicture : public CStatic
{
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnPaint();
vector<Coordinates> GraphData;
};
void CPicture::OnPaint()
{
// device context for painting
CPaintDC dc(this);
// save current brush
CBrush *pOldBrush = (CBrush*)dc.SelectStockObject(BLACK_BRUSH);
int NumPoints = GraphData.size() - 1;
for (int N = 0; N <= NumPoints; N++) {
dc.Rectangle(GraphData[N].x, GraphData[N].y, GraphData[N].x, GraphData[N].y);
}
// select original brush into device contect
dc.SelectObject(pOldBrush);
}
可以在新数据到达时调用控件上的Invalidate()
,或使用RedrawWindow()
强制立即重绘:
CPicture myPicture;
myPicture.Invalidate();
或
myPicture.RedrawWindow();
我不能重复调用OnPaint()或将数据传递给它。
要传递数据,可以在CPicture
类(或程序中的其他位置)中声明包含数据的结构,然后可以从OnPaint()
中访问该数据:
struct myData {
int value1;
int value2; // or an array, or some other data structure
}
class CPicture : public CStatic
{
DECLARE_MESSAGE_MAP()
public:
myData m_data;
afx_msg void OnPaint();
};
在OnPaint()
中(还应选择原始画笔返回到设备上下文以避免资源泄漏):
void CPicture::OnPaint()
{
CPaintDC dc(this); // device context for painting
// save current brush
CBrush *pOldBrush = (CBrush*)dc.SelectStockObject(BLACK_BRUSH);
// check pOldBrush - could be NULL
// dc.Rectangle(5, 50, 1000, 51);
// access m_data here, for example
dc.Rectangle(m_data.value1, m_data.value2, 1000, 51);
// select original brush into device contect
dc.SelectObject(pOldBrush);
}
更新(使用线程):
假设以下内容(来自评论):
对于主线程,您有一个对话框
CLongbowDlg
。对于图形,您有一个派生自
CStatic
的PicControl
,并且该控件放置在对话框中。从主线程,启动工作线程来读取数据。
PicControl 和 CLongbowDlg 在同一个标头中定义,但 彼此独立。我需要能够调用 Invalidate() 或 从 CLongbowDlg 的函数内部重绘窗口(),因为它们 表示主线程。
我将尝试在这里简要描述其中一种可能性,因为这实际上应该是一个单独的问题。
首先,PicControl
的对象必须是CLongbowDlg
的成员,我假设是这种情况(我们称之为m_PicControl
) - 所以,在类CLongbowDlg
:
PicControl m_PicControl;
对于数据(我将使用上面的myData
作为示例数据):在您的主线程(对话框)中,创建一个类型为 myData
的变量:m_data
(对于较大的数据,您可以在堆上分配空间,或使用 CArray
或其他容器):
myData m_data;
在PicControl
创建一个类型为 myData*
的成员变量,并在 PicControl 构造函数中将其设置为 NULL。
myData *m_pData;
在OnInitDialog()
(主对话框)中,为m_picControl
提供指向数据的指针(或者最好创建一个函数来在 PicControl 中执行此操作):
m_picControl.m_pData = &m_data;
启动工作线程时,还要为其提供指向m_data
的指针和/或指向对话框本身的指针 (this
)。
确保使用关键部分保护数据。
当数据传入时,工作线程可以通过提供的指针写入数据。
在PicControl::OnPaint()
中,相同的数据可以通过m_pData
访问。
要启动重绘,有几种方法:
在
PicControl
或主对话框中使用计时器,并在每次计时器触发时调用Invalidate()
。要控制从工作线程重绘(例如,当一定数量的新数据到达时),可以使用
PostMessage()
将消息发布到主对话框(使用启动线程时提供的指针 -this
指针)。要接收消息,您必须在主对话框中创建一个消息处理程序,然后从那里调用
Invalidate()
m_picControl
(您也可以直接将消息发布到 PicControl,但我更喜欢通过主窗口执行此操作)。
- C++图形类指针混淆
- 我的代码中有错误吗?使用BGI图形的C++代码对我不起作用
- 如何在内核C++中使用1920x1080x16M图形或类似的16M颜色?(VGA)
- 这是实现图形的坏方法吗
- 打印 ONNXRUNTIME::图形没有模型
- 提升如何在图形可视化中写入边缘的权重?
- Doxygen - 如何在不生成图形的情况下生成文本调用关系结果
- C++ 中的图形菜单
- 将图形属性与 std::unique_ptr 捆绑在一起
- 从流到邻接列表的向量读取图形
- 替代在python中制作邻接列表与图形问题的字典?(如 C++ 中的 vector<vector<int&g
- 将图形表示为unordered_map<字符串、向量>时拓扑排序错误<string>
- 直接显示手动图形内存泄漏
- Directx 12 :在两个进程之间共享图形内存
- Microsoft C++ 用于图形 API 的 Rest SDK
- 如何将到达图形视图右侧(末端)的QGraphicsPixmapItem移动到左侧(开始)侧(就像在贪吃蛇游戏中发生的事情
- 图形初学者C++(跳过控制台)?
- 在 cpp 中最简单的图形实现
- 提升图形库:资源受限的最短周期
- 使用 stl 库创建图形是如何工作的?