当前位置:C++技术网 > 精选软件 > win32获取和显示电脑开机运行了多长时间

win32获取和显示电脑开机运行了多长时间

更新时间:2016-01-14 00:40:58浏览次数:1+次

    通过这个小功能的实现,我竟然发现的联想笔记本持续运行了7天!!而我记得,我每天都关机了的。不过插着电源线,如此看来,电脑并没有真正关机,而只是睡眠了而已。

    下面是程序的运行效果图:

程序检测到电脑已经运行了7天4个小时了

【程序检测到电脑已经运行了7天4个小时了】
    实现这个功能的技术点有:获取电脑启动以来已经运行的时间值、将以毫秒计的时间值拆分(天数、小时、分钟、秒数和毫秒数)、显示时间(因为一直累计时间,所以显示动态的增加时间)。
    获取电脑已经运行的时间可以使用函数GetTickCount,此函数直接返回一个毫秒计的时间值。函数使用很简单,使用一个DWORD类型的变量接受返回值即可。
    然后就是使用算法来切割时间了。我们使用了两种算法,第一种比较乱,不过可以实现。第一种切割时间的算法如下:
//第一种切割方法比较乱,不过可以正确的切割,没有加入毫秒值
h = dwTime/3600;
d = h/24;
m = (dwTime-(h*3600))/60;
s = dwTime-(h*3600)-(m*60);
h = h%24;
    因为这种方法比较乱,所以放弃使用。进而使用了第二种算法。第二种算法的基本思想是:首先按照天数所需要的毫秒数取出满了一天的时间,得到天数,使用整数除法即可做到。然后将不足一天的毫秒数取模得到余数。再将余数除以满足一个小时的时间毫秒数,得到小时数,然后将这个时间取模得到不足一个小时的时间数,然后依次类推,得到所有度量的时间。如此就完成了时间的切割。按照这种方法,可以很好的扩展切割的时间,还可以增加月份和年份的切割。第二种切割时间的算法代码如下:
//第二种切割方法思路比较清晰
//先将够数的部分除出来,然后将剩余的取模,循环执行下去切割
//切割天数
d = dwTime/(24*60*60*1000);
dwTime %= 24*60*60*1000;
//切割小时数
h = dwTime/3600/1000;
dwTime %=3600*1000;
//切割分钟数
m = dwTime /60/1000;
dwTime %=60*1000;
//切割秒数和毫秒数
s = dwTime/1000;
ms = dwTime%1000;
    然后将切割得到的时间,格式化到字符串中,然后让客户区重绘并擦除背景。在WM_PAINT消息中,显示出电脑自开机以来持续运行的时间数。如果要动态的显示时间,则可以在WM_CREATE中创建一个计时器,调用函数SetTimer,设定一个时间间隔。那么我们获取和分割时间、格式化字符串都在计时器消息WM_TIMER中完成。时间间隔设置的越小,毫秒变化的越快。不过我们的计时器是不影响电脑已经运行的时间的,我们只是获取时间而已,所以电脑运行的时间不受计时器的时间间隔的影响。

    下面是完整的代码:


#include "windows.h"
#include <tchar.h>
TCHAR tip[100]=_T("");
TCHAR txt[100]=_T("C++技术网www.cjjjs.com");
// - 项目是Unicode字符集
LRESULT CALLBACK WinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    static int d,h,m,s,ms;
    switch (message)
    {

        case WM_CREATE:
            {
                SetTimer(hwnd,1,50,NULL);
            }
            return 0;
        case WM_TIMER:
            {
                DWORD dwTime = GetTickCount();//ms
                //第一种切割方法比较乱,不过可以正确的切割
                //h = dwTime/3600;
                //d = h/24;
                //m = (dwTime-(h*3600))/60;
                //s = dwTime-(h*3600)-(m*60);
                //h = h%24;

                //第二种切割方法思路比较清晰
                //先将够数的部分除出来,然后将剩余的取模,循环执行下去切割
                //切割天数
                d = dwTime/(24*60*60*1000);
                dwTime %= 24*60*60*1000;
                //切割小时数
                h = dwTime/3600/1000;
                dwTime %=3600*1000;
                //切割分钟数
                m = dwTime /60/1000;
                dwTime %=60*1000;
                //切割秒数和毫秒数
                s = dwTime/1000;
                ms = dwTime%1000;
                wsprintf(tip,_T("已开机:%d天%d小时%d分%d秒%d"),d,h,m,s,ms);
                InvalidateRect(hwnd,0,1);
            }
            return 0;
        case WM_PAINT:
            hdc = BeginPaint(hwnd,&ps);
            TextOut(hdc,2,10,txt,lstrlen(txt));
            TextOut(hdc,2,30,tip,lstrlen(tip));
            EndPaint(hwnd,&ps);
            return 0;
        case WM_DESTROY:
            PostQuitMessage(0); 
            return 0;
        default:
        break;//跳出到默认处理
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrev,LPSTR lpCmd,int iShow)
{
    TCHAR ClassName[] = _T("MyClass");
    TCHAR title1[] = _T("C++技术网http://www.cjjjs.com");
    WNDCLASS wndClass;
    wndClass.cbClsExtra=0;
    wndClass.cbWndExtra=0;
    wndClass.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    wndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    wndClass.hInstance = hInstance;
    wndClass.lpfnWndProc = WinProc;
    wndClass.lpszClassName = ClassName;
    wndClass.lpszMenuName=NULL;
    wndClass.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;

    if(!RegisterClass(&wndClass))return 0;
    HWND hwnd = CreateWindow(ClassName,title1,WS_OVERLAPPEDWINDOW,10,100,350,400,NULL,NULL,hInstance,NULL);
    ShowWindow(hwnd,SW_SHOWNORMAL);

    MSG msg;
    while (GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}