C# 流量悬浮窗
最近觉得360太恶心了,果断卸载,但是又缺少一个显示流量的悬浮窗,觉定自己搞一个。
前言
刚开始用Qt(C++)写的发现体积太大,输出个HelloWorld就要几兆果断放弃,尝试了一下C#体积小,占内存小,于是转用C#。之前写Java,Android都是用的Eclipse,C#要用VS写,但VS太大了实在接受不了,网上搜了一下SharpDevelop挺好用的,先上个效果图:

如果要完美的话,可以添加右键菜单,网卡切换,网速限制,每个标签的点击显示应用详情事件,最小化到任务栏等等,由于时间关系就不写这么多了,就只写显示,拖动,锁定这几个功能
##布局
5个Label显示RAM,CPU,磁盘占用率,上、下传流量,怎么好看怎么摆放。
RAM需要背景显示占用百分比,占用率超过70%背景边框变红,需要继承Label重写OnPaintBackground
代码如下:
public partial class BGLabel : Label
{
public bool BackColorVisible=true;
public bool BorderColorVisible=true;
public int Taget=70;
public int Value=00;
public BGLabel()
{
}
protected override void OnPaintBackground (PaintEventArgs e){
base.OnPaintBackground(e);
if(BackColorVisible){
if(Value>=Taget){
Brush brush=new SolidBrush(Color.Red);
int height=Height*Value/100;
e.Graphics.FillRectangle(brush,0,Height-height,Width,Height);
}else{
Brush brush=new SolidBrush(Color.Green);
int height=Height*Value/100;
e.Graphics.FillRectangle(brush,0,Height-height,Width,Height);
}
}
if(BorderColorVisible&&Value>=Taget){
Pen pen = new Pen(Color.Red,1);
e.Graphics.DrawRectangle(pen,0,0,Width-1,Height-1);
}
}
}
##点击事件
按住鼠标左键拖动,应同学要求右键点击锁定,再次点击解除锁定
继承 IMessageFilter 接口
partial class MainForm: Form , IMessageFilter
重写 PreFilterMessage(ref Message m) 方法
private bool isLock=false;
private bool isMove=false;
private bool isClick=false;
private int curXPosition;
private int curYPosition;
// WM_MOUSEMOVE= $0200 移动鼠标
// WM_LBUTTONDOWN= $0201 按下鼠标左键
// WM_LBUTTONUP= $0202 释放鼠标左键
// WM_RBUTTONDOWN= $0204 按下鼠标右键
// WM_RBUTTONUP= $0205 释放鼠标右键
public bool PreFilterMessage(ref Message m)
{
if(m.Msg==0x0204){
isMove = true;
isClick = true;
return true;
}else if (m.Msg == 0x0205&&isClick){
isMove = false;
isLock=!isLock;
return true;
}else if (!isLock&&m.Msg == 0x0201){
isMove = true;
isClick = true;
curXPosition = MousePosition.X;
curYPosition = MousePosition.Y;
return false;
}else if(!isLock&&m.Msg == 0x0200&&isMove){
isClick=false;
this.Left += MousePosition.X - curXPosition;
this.Top += MousePosition.Y - curYPosition;
curXPosition = MousePosition.X;
curYPosition = MousePosition.Y;
return true;
}else if(!isLock&&m.Msg == 0x0202){
isMove = false;
return !isClick;
}
return false;
}
事件对应的Msg的ID请移步【C#】Message类的属性Msg所关联的消息ID
最后不要忘了在构造函数中添加过滤
Application.AddMessageFilter(this);
##获取占用率
使用性能计数器PerformanceCounter监控上下传流量,CPU,磁盘占用率,
使用GlobalMemoryStatus函数获取RAM占用率
public class Monitor
{
private Network network;
private Cpu cpu;
private Ram ram;
private Disk disk;
public Monitor()
{
PerformanceCounterCategory category = new PerformanceCounterCategory("Network Interface");
foreach (string name in category.GetInstanceNames())
{
if (name == "MS TCP Loopback interface")
continue;
Network n = new Network(name);
if(n.isConnect){
network=n;
break;
}
}
cpu=new Cpu();
ram=new Ram();
disk=new Disk();
}
public void refresh(){
network.refresh();
cpu.refresh();
ram.refresh();
disk.refresh();
}
public string getDownSpeed(){
return network.getFormatDownSpeed();
}
public string getUpSpeed(){
return network.getFormatUpSpeed();
}
public int getCpuUtil(){
return cpu.curValue;
}
public int getRamUtil(){
return ram.curValue;
}
public int getDiskUtil(){
return disk.curValue;
}
public bool isDownSpeedChange(){
return network.isDownSpeedChange;
}
public bool isUpSpeedChange(){
return network.isUpSpeedChange;
}
public bool isCpuUtilChange(){
return cpu.curValue!=cpu.oldValue;
}
public bool isRamUtilChange(){
return ram.curValue!=ram.oldValue;
}
public bool isDiskUtilChange(){
return disk.curValue!=disk.oldValue;
}
}
public class Network{
public string name { get; private set; }
public long downSpeed{ get; private set;}
public long upSpeed{ get; private set; }
public bool isDownSpeedChange{ get; private set; }
public bool isUpSpeedChange{ get; private set; }
public bool isConnect{ get; private set; }
private PerformanceCounter downCounter, upCounter;
private long downValue, upValue;
private long downValueOld, upValueOld;
private long downSpeedOld,upSpeedOld;
public Network(string name){
this.name=name;
downCounter = new PerformanceCounter("Network Interface", "Bytes Received/sec", name);
upCounter = new PerformanceCounter("Network Interface", "Bytes Sent/sec", name);
if(downCounter==null||upCounter==null)
return;
downValueOld=downCounter.NextSample().RawValue;
upValueOld=upCounter.NextSample().RawValue;
if(downSpeedOld>0||upValueOld>0)isConnect=true;
else isConnect=false;
}
public void refresh()
{
if(downCounter==null||upCounter==null){
downSpeed=0;
upSpeed=0;
return;
}
if(downCounter.NextSample()==null||upCounter.NextSample()==null){
downSpeed=0;
upSpeed=0;
return;
}
downValue = downCounter.NextSample().RawValue;
upValue = upCounter.NextSample().RawValue;
downSpeed = downValue - downValueOld;
upSpeed = upValue - upValueOld;
isDownSpeedChange=(downSpeed!=downValue);
isUpSpeedChange=(upSpeed!=upSpeedOld);
downSpeedOld=downSpeed;
upSpeedOld=upSpeed;
downValueOld=downValue;
upValueOld=upValue;
}
public string getFormatDownSpeed(){
return format(downSpeed);
}
public string getFormatUpSpeed(){
return format(upSpeed);
}
private string format(long num){
double n=num/1024.0;
if(n>=1000.0)return (n/1024).ToString("0.00")+"MB/s";
else if(n>=100.0)return n.ToString("0.0")+"KB/s";
else return n.ToString("0.00")+"KB/s";
}
}
public class Cpu{
public int curValue { get; private set; }
public int oldValue { get; private set; }
private PerformanceCounter counter;
public Cpu(){
counter = new PerformanceCounter("Processor", "% Processor Time","_Total");
curValue=(int)counter.NextValue();
}
public void refresh(){
oldValue=curValue;
curValue=(int)counter.NextValue();
}
}
public class Ram{
public struct MEMORYSTATUS
{
public uint dwLength;
public uint dwMemoryLoad;
public ulong dwTotalPhys;
public ulong dwAvailPhys;
public ulong dwTotalPageFile;
public ulong dwAvailPageFile;
public ulong dwTotalVirtual;
public ulong dwAvailVirtual;
public ulong dwAvailExtendedVirtual;
}
public int curValue { get; private set; }
public int oldValue { get; private set; }
private MEMORYSTATUS mStatus;
[DllImport("kernel32.dll")]
public static extern void GlobalMemoryStatus(ref MEMORYSTATUS stat);
public Ram(){
GlobalMemoryStatus(ref mStatus);
curValue=(int)(mStatus.dwMemoryLoad);
}
public void refresh(){
oldValue=curValue;
GlobalMemoryStatus(ref mStatus);
curValue=(int)(mStatus.dwMemoryLoad);
}
}
public class Disk{
public int curValue { get; private set; }
public int oldValue { get; private set; }
private PerformanceCounter counter;
public Disk(){
counter=new PerformanceCounter("PhysicalDisk", "% Disk Time", "_Total");
int num=(int)counter.NextValue();
curValue=num>100?100:num;
}
public void refresh()
{
oldValue=curValue;
int num=(int)counter.NextValue();
curValue=num>100?100:num;
}
}
最后添加timer,1s更新一次不变的就不更新了
private void timer_Tick(object sender, System.EventArgs e)
{
monitor.refresh();
if(monitor.isRamUtilChange()){
lab_0.Value=monitor.getRamUtil();
lab_0.Text="RAM\n"+monitor.getRamUtil()+"%";
}
if(monitor.isDownSpeedChange())
lab_1.Text=monitor.getDownSpeed();
if(monitor.isUpSpeedChange())
lab_2.Text=monitor.getUpSpeed();
if(monitor.isCpuUtilChange()){
lab_3.Value=monitor.getCpuUtil();
lab_3.Text="CPU "+monitor.getCpuUtil()+"%";
}
if(monitor.isDiskUtilChange()){
lab_4.Value=monitor.getDiskUtil();
lab_4.Text="DISK "+monitor.getDiskUtil()+"%";
}
}
到此结束,虽然有些Bug,但不影响使用

3万+

被折叠的 条评论
为什么被折叠?



