C# 流量悬浮窗

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,但不影响使用

Github: https://github.com/kunorz/FloatingWindow

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值