简介
本文使用的开发模板和第三方库:
- C++ WinUI 开发工具。
- Win2d for WinUI3 库(微软开发的,基于 Direct2D 技术,GPU加速的平面绘图工具)。
项目地址
Win2dDemo
CPU ,GPU 消耗情况:
软件截图:
主要功能
- 显示采集的信号曲线。本文使用随机数模拟信号曲线,可以替换成真实的信号采集函数。
- 可以保存曲线数据到本地,并加载数据。
- 支持窗口缩放,坐标系x,y轴范围修改,刻度数量,颜色修改。
实现逻辑
- 通过定时器,每隔100ms调用一次采样函数,绘图函数实现画面更新。因为需要修改 UI,最好使用
DispatcherTimer
.
// 在类的头文件中声明定时器。
Microsoft::UI::Xaml::DispatcherTimer m_drawingTimer{};
// 在源文件中初始化定时器。
auto duration = TimeSpan{ std::chrono::milliseconds{100} };
m_drawingTimer.Interval(duration);
m_drawingTimer.Tick({ this, &CurvePainter::OnDrawingTimer_Tick });
m_drawingTimer.Start();
- 在 xaml 中添加绘图控件
CanvasControl
,添加图片控件Image
。在 c++ 代码中,将绘图的内容显示到Image
中就可以了。
<canvas:CanvasControl
x:Name="CanvasControl"
CreateResources="CanvasControl_CreateResources"
SizeChanged="CanvasControl_SizeChanged">
<Image x:Name="UIImage" />
</canvas:CanvasControl>
- Win2d 主要通过
CanvasDrawingSession
会话进行绘图,每次绘图需要创建一个会话,在会话变量销毁的时候,才会更新图片。
(a) 基本用法
// 在窗口大小改变的时候,需要更新 imageSource.
CanvasImageSource imageSource = CanvasImageSource(CanvasControl(), width, height, dpi);
UIImage().Source(imageSource);
// 通过 imageSource 就可以创建绘图的会话。
CanvasDrawingSession ds = m_imageSource.CreateDrawingSession(m_canvasBackground);
// 绘制文本
ds.DrawTextW(text, position, color, fontSize) ;
// 绘制线段
ds.DrawLine(point1, point2, lineColor, lineWidth);
// 填充矩形
ds.FillRectangle(rect, color);
(2)绘制一条完整的曲线。 可以使用函数 ds.DrawGeometry(geometry, color, width)
// 第一步,创建一个 PathBuilder, 将需要绘制的点通过 for 循环添加进去。
CanvasPathBuilder path{CanvasControl()};
// 添加起点。
path.BeginFigure(float2{ x,y });
// 添加其余的点。
for (int j = 1; j < m_linesYAxisData[i].size(); j++)
{
x = m_xAxisAbsValues[j];
y = SignalValueToAbsValue(m_linesYAxisData[i][j]);
path.AddLine(float2{ x,y });
}
// 结束添加
path.EndFigure(CanvasFigureLoop::Open);
// 第二步,创建 CanvasGeometry
CanvasGeometry geometry = CanvasGeometry::CreatePath(path);
// 第三步,调用 ds.DrawGeometry
ds.DrawGeometry(geometry, color, width);
参考资料
- Win2d 库参考文档: https://microsoft.github.io/Win2D/WinUI3/html/Introduction.htm
- C++/WinRT 参考文档: https://learn.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/
- Windows App SDK API 参考文档:https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/
- C++/WinRT 扩展WinRT 函数参考文档:https://learn.microsoft.com/en-us/uwp/cpp-ref-for-winrt/winrt#cwinrt-functions-that-extend-windows-runtime-apis