一.原理解释
1.效果呈现
其中物理运行内存和虚拟运行内存是实时跳动的。
2.检索电脑的磁盘名称
要检索电脑的磁盘名称,需要用到WMI(Windows Management Instrumentation),即windows管理工具。其中还需要使用到WQL(它是用于从 WMI 获取信息的语言)。System.Management命名空间,它提供对一组丰富的管理信息和管理事件(它们是关于符合Windows Management Instrumentation (WMI) 基础结构的系统、设备和应用程序的)的访问。应用程序和服务可以使用从ManagementObjectSearcher 和 ManagementQuery 派生的类,查询感兴趣的管理信息(例如在磁盘上还剩多少可用空间、当前 CPU 利用率是多少、某一应用程序正连接到哪一数据库等等);或者应用程序和服务可以使用 ManagementEventWatcher类预订各种管理事件。
3.检索电脑的磁盘大小
检索电脑的磁盘大小则需要使用System.IO命名空间下的DriveInfo类,它提供对有关驱动器信息的访问。
4.检索电脑的运行内存大小
检索电脑的物理和虚拟内存则需要使用Microsoft.VisualBasic.Devices命名空间的Computer类。
5.绘制效果图
在界面上绘图则需要使用System.Drawing命名空间的Graphics类。
二.具体代码
下面的代码仅展示了主要部分
using System;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Management;
using System.IO;
using Microsoft.VisualBasic.Devices;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Task.Run(new Action(DisplayMemory));
}
private void Form1_Load(object sender, EventArgs e)
{
//WQL的select操作,查询电脑的磁盘信息
SelectQuery selectQuery = new SelectQuery
{
QueryString = "select * from win32_logicaldisk"
};
ManagementObjectSearcher searcher = new ManagementObjectSearcher
{
Query = selectQuery
};
//显示电脑的磁盘信息
foreach (ManagementObject obj in searcher.Get())
{
cbox_diskName.Items.Add(obj["name"].ToString());
}
cbox_diskName.SelectedIndex = 0;
}
private void button1_Click(object sender, EventArgs e)
{
//获取驱动器的空间总量信息
DriveInfo driveInfo = new DriveInfo(cbox_diskName.Text);
var totalSize = driveInfo.TotalSize;
var totalFreeSpace = driveInfo.TotalFreeSpace;
//绘制饼状图
Graphics graphics = this.CreateGraphics();
var diskProportion = (float)totalFreeSpace / (float)totalSize * 360;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphics.FillPie(new SolidBrush(Color.Orange), 75, 100, 200, 200, 180, 360 - diskProportion);
graphics.FillPie(new SolidBrush(Color.Green), 75, 100, 200, 200, 540 - diskProportion, diskProportion);
graphics.DrawString("已使用:"+ (int)((float)(totalSize - totalFreeSpace)/1024/1024/1024) + "GB", new Font("宋体", 10), new SolidBrush(Color.Black), 140, 320);
graphics.DrawString("未使用:" + (int)((float)totalFreeSpace/1024/1024/1024) + "GB", new Font("宋体", 10), new SolidBrush(Color.Black), 140, 340);
graphics.FillRectangle(new SolidBrush(Color.Orange), 110, 320, 25, 10);
graphics.FillRectangle(new SolidBrush(Color.Green), 110, 340, 25, 10);
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
//获取光标的X,Y轴坐标
textBox1.Text = e.X.ToString();
textBox2.Text = e.Y.ToString();
}
private void DisplayMemory()
{
while (true)
{
//获取物理内存信息
Computer computer = new Computer();
var totalPhysicalMemory = computer.Info.TotalPhysicalMemory;
var availablePhysicalMemory = computer.Info.AvailablePhysicalMemory;
//获取虚拟内存信息
var totalVirtualMemory = computer.Info.TotalVirtualMemory;
var availableVirtualMemory = computer.Info.AvailableVirtualMemory;
//绘制物理内存信息
Bitmap image = new Bitmap(panel1.Width, panel1.Height);
Graphics graphics = Graphics.FromImage(image);
panel1.BackColor = Color.Gray;
var memoryProporation = (float)(totalPhysicalMemory - availablePhysicalMemory) / totalPhysicalMemory * panel1.Height;
graphics.FillRectangle(new SolidBrush(Color.Green), 0, panel1.Height - memoryProporation, panel1.Width, memoryProporation);
panel1.BackgroundImage = image;
//绘制虚拟内存信息
Bitmap image1 = new Bitmap(myPanel1.Width, myPanel1.Height);
Graphics graphics1 = Graphics.FromImage(image1);
myPanel1.BackColor = Color.Gray;
var memoryProporation1 = (float)(totalVirtualMemory - availableVirtualMemory) / totalVirtualMemory * myPanel1.Height;
graphics1.FillRectangle(new SolidBrush(Color.Green), 0, myPanel1.Height - memoryProporation1, myPanel1.Width, memoryProporation1);
myPanel1.BackgroundImage = image1;
}
}
}
}
三.注意事项
1.在绘制饼状图时,图形的边沿会有锯齿出现,呈现的效果很差。此时需要将Graphics对象的SmoothingMode属性设置为AntiAlias。
2.在不断刷新绘制Panel对象时,画面会有明显的闪烁,影响视觉观感。此时可以使用双缓冲绘制,但是在Form对象里无法设置Pannel控件的DoubleBuffered属性,因为它是protected的。
此时我们可以在From窗体中添加一个组件,用于继承Panel类,在构造函数中将DoubleBuffered属性设为true,至此问题得到解决。