CPU温度小工具之数据呈现
在上一篇文字里,已经写了如何获取数据。其实,在农历新年前,那部分代码衣服自己洗就已经写好了,丢在那里了。
我今天要说的,在任务栏显示数据,可不是在系统托盘区域显示图标,那个在 NET 里用 NotifyIcon 控件就可以做到的。按惯例,先上图。
这个是任务栏在底部的时候
这个是任务栏在右部的时候
至于任务栏在左边和在上边,原理都是一样的。
我在网上也确实搜索了一把,关于 NET 来实现这样效果的资料好少,年少不学 C++,老来就空叹气。
再说原理前,提一哈句柄这个概念,在 C++ 里,几乎所有的界面、控件都有句柄。例如一个窗体,一个按钮,桌面,和今天的主体“任务栏”都有句柄。这里说的是几乎,因为还有用 DirectUI 实现的界面是没有句柄的,例如 QQ、MSN、百度Hi、YY 等,DirectUI ,这是题外话了。
我们对句柄操作实际上就是对控件或者说所代表的内存进行操作。从广泛意义上来说,var obj=document.createElement(“div”); 这里的 obj 变量就可以理解为一个句柄。
实现原理是酱紫的,我们创建一个控件比如说 Label ,然后设置它的父容器为任务栏,最后再设置它的位置。就可以达到要求了。
任务栏主要有两块,一是显示当前运行的程序,我这里自己取名字叫工具条,二是显示程序的托盘图标,我取名字叫托盘栏。
第一步,引入相关的 C++ API。什么 FindWindow 、GetWindowRect 什么的。
[DllImport(“user32.dll”, EntryPoint = “FindWindowEx”, SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport(“user32.dll”)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport(“user32.dll”)]
static extern int GetWindowRect(IntPtr hwnd, out Rect lpRect);
[DllImport(“user32.dll”, EntryPoint = “MoveWindow”)]
static extern int MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, int bRepaint=1);
[DllImport(“user32.dll”)]
static extern int SetParent(IntPtr wnd, IntPtr newParentWnd);
第二步,拿到我们需要操作的对象的句柄。
IntPtr trayHwnd = FindWindow(“Shell_TrayWnd”, null); //获取任务栏整体句柄
IntPtr notifyHwnd = FindWindowEx(trayHwnd, IntPtr.Zero, “TrayNotifyWnd”, null);//获取任务栏托盘区域句柄
IntPtr toolbarHwnd = FindWindowEx(trayHwnd, IntPtr.Zero, “ReBarWindow32”, null);//获取任务栏工具条区域句柄
IntPtr imeHwnd = FindWindowEx(toolbarHwnd, IntPtr.Zero, “CiceroUIWndFrame”, null);//获取语言栏区域句柄
第三步,开始获取相关尺寸。
Rect box = new Rect();
GetWindowRect(toolbarHwnd, out box);
//获取任务栏尺寸
int boxWidth = box.Right – box.Left;
int boxHeight = box.Bottom – box.Top;
//判断任务栏是水平还是垂直。true 为水平,false 为垂直
bool position = boxWidth > boxHeight ? true : false;
Rect ime = new Rect();
int d = GetWindowRect(imeHwnd, out ime);
//获取语言栏尺寸
int imeWidth = 0;
int imeHeight = 0;
if (d != 0)
{
imeWidth = ime.Right – ime.Left;
imeHeight = ime.Bottom – ime.Top;
}
frmHwnd = FindWindow(null, “SysMonitor”); //查找程序窗体
第四步,开始计算目的坐标。
if (frmHwnd != IntPtr.Zero)
{
int x1, y1; //窗体目标坐标
int x2, y2;//语言栏目标坐标
if (position)
{
x1 = boxWidth – w;
y1 = (boxHeight – h) / 2;
x2 = x1 – imeWidth-10; //这里多减的 10 是为了增加间隙,漂亮点
y2 = 0;
}
else
{
int diff = 2; //垂直方向,扣减宽度更美观
//如果为垂直方向,修改宽度以适应任务栏宽度
w = boxWidth – diff;
x1 = box.Left==0?0:diff;
y1 = boxHeight – h;
x2 = x1;
y2 = boxHeight – imeHeight – h;
}
this.Width = w;
this.Height = h;
lblInfo.Width = w;
lblInfo.Height = h;
int c = SetParent(frmHwnd, toolbarHwnd);//设置任务栏为窗体的父窗体
第五步,移动 CPU 温度窗体和语言栏到目的位置。
MoveWindow(frmHwnd, x1, y1, w, h);//移动显示CPU温度的窗体
MoveWindow(imeHwnd, x2, y2, imeWidth, imeHeight);//移动语言栏窗体
写到这里,整体结构就算完了。不要忘记了添加一个 Timer 喔,定时获取最新的 CPU 温度并显示出来。
最后生成的 exe 我就不放上来了。如果大家有需要的话,留言衣服自己洗会发给你们。代码优化的事情就交给你们去做拉。
CPU 温度工具到这里就算完拉。剩下的一个未完成的是在直接在桌面上绘制内容,相信我,这对我来说很有用的。
最后的最后,我那些亲爱的朋友们,我想你们了。