分享
 
 
 

用vc.net实现记录开关机时间的程序

王朝vc·作者佚名  2006-01-17
窄屏简体版  字體: |||超大  

用vc.net实现记录开关机时间的程序

作者:西安 汪俊

下载源代码

虽然现在电脑大幅降价,但是多人公用一台电脑的情况仍然不少,特别是学生一族。有时候自己由于某种需要要知道别人什么时候使用这台电脑,那该怎么办呢?去网上找一个?但是不一定符合自己的要求,不如发扬DIY精神,自己做一个。那么就用vc.net来DIY一个吧。

编程思想:记录开机时间比较容易,只需要让程序随系统启动,启动时记录一个开机时间,关机时记录关机时间就可以了。

在正式开始之前,首先得了解这个小程序的编写步骤,让我们一步一步来:

实现开机自运行

实现运行时自动隐藏

实现可以热键呼出

实现记录时间

实现关机时记录时间

1、实现开机自运行

我在csdn网站上经常看到有人问这样的问题,其实要实现开机时就自动运行自己的程序并不难。在注册表的HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run键下可以看到有一系列键值,它们都是开机自动运行的软件的路径。那么我们要做的就是编程实现将我们的程序的路径也添加到这个键值下,就搞定了。著名的“windows优化大师”也就是用去掉不必要的开机运行软件这个方法来实现开机速度优化的。

既然要读写注册表,就要用到两个重要的操作注册表的函数:RegOpenKey()和RegSetValueEx()。前者用于打开注册表的键,后者则为打开的键设置键值,至于这两个API函数的具体参数,请参见MSDN。为了代码重用的要求,我为此封装了一个专门的函数,如下所示:

BOOL SetAutoRun(CString strPath)//开机自动运行

{

CString str;

HKEY hRegKey;

BOOL bResult;

str=_T("Software\\Microsoft\\Windows\\CurrentVersion\\Run");

if(RegOpenKey(HKEY_LOCAL_MACHINE, str, &hRegKey) != ERROR_SUCCESS)

bResult=FALSE;

else

{

_splitpath(strPath.GetBuffer(0),NULL,NULL,str.GetBufferSetLength(MAX_PATH+1),NULL);

strPath.ReleaseBuffer();

str.ReleaseBuffer();

if(::RegSetValueEx( hRegKey,

str,

0,

REG_SZ,

(CONST BYTE *)strPath.GetBuffer(0),

strPath.GetLength() ) != ERROR_SUCCESS)

bResult=FALSE;

else

bResult=TRUE;

strPath.ReleaseBuffer();

}

return bResult;

}

其中strPath参数表示要设置为自运行的程序的绝对路径。当设置成功时返回true,否则返回false。

这里又带来一个问题:既然需要本程序的绝对路径,那么怎么得到它呢?总不能指定一个值吧,那么当本程序的路径改变时就又要修改程序,太麻烦了。可以用这个封装的函数来实现:

//得到程序文件本身的路径(包括文件名)

CString GetMyPath()

{

CString strPath;

GetModuleFileName(NULL,strPath.GetBufferSetLength(MAX_PATH+1),MAX_PATH);

strPath.ReleaseBuffer();

return strPath;

}

其中GetModuleFileName()是一个得到路径的API函数。本函数将这个API函数封装在其中,为的是简化调用的目的。

当执行这个函数时,返回本程序所在的绝对路径,包括本程序的文件名。

好了,得到本程序的路径,然后将它加载到注册表中,下次系统启动时,我们的程序就能自动随之启动了。

2、实现运行时自动隐藏

这是一个很有趣很古老的话题,csdn上经常有人为此讨论不休,提出不少方案,比如在对话框的OnInitDialog()中添加一句:ShowWindow(SW_HIDE);,或者在对话框属性框中去掉对话框的Visible属性;或者将对话框移到桌面以外的地方去;或者首先将对话框最小化,然后实现最小化时隐藏……有趣的是这些很容易想到的常规方法都不能解决这个问题,或者说解决的不够好。我通过查找相关文章和多次修改代码,找出了真正解决这个问题的办法。

之所以用ShowWindow()函数失效,我认为可能是对话框的DoModal()在作怪,这么一来就只能绕开DoModal(),那么就自然想到可以把对话框变成一个无模式对话框。无模式对话框平时我们用到的不多,它与模式对话框不同,是用Create方法Create出来的,而不是DoModal()创建的。

假设建立一个VC.NET工程GetTime,首先在CGetTimeApp类中添加一个成员变量:CGetTimeDlg

*dlg;然后在InitInstance()中将原来的:

int nResponse = dlg.DoModal();

if (nResponse == IDOK)

{

// TODO: Place code here to handle when the dialog is

// dismissed with OK

}

else if (nResponse == IDCANCEL)

{

// TODO: Place code here to handle when the dialog is

// dismissed with Cancel

}

以及return FALSE;全部删除掉,改为:

dlg=new CGetTimeDlg;

m_pMainWnd = dlg;

return dlg-Create(IDD_GETTIME_DIALOG);

最后别忘了在ExitInstance()中加上一句:delete dlg;好了,这下把本程序的对话框变成了一个无模式对话框。不过既然是无模式对话框,就不能再用OnOK(),OnCancel()来退出了,要用DestroyWindow()。

由于在上面的代码中没有将对话框设为可见,所以运行时就实现了隐藏,而且在Windows任务栏上也没有显示。至此,第二个问题得到完美解决。

3、实现可以热键呼出

既然已经隐藏,别人看不到,但是程序的作者有必要和对话框发生交互,那么怎么在需要的时候让对话框出现呢?这个问题可以用热键呼出来实现。

要实现热键呼出的功能,首先要注册一个热键。注册热键的API函数是RegisterHotKey(),具体参数见MSDN。注册热键可以在对话框的OnInitDialog()中进行:

m_strKey="J";

RegisterHotKey(this-m_hWnd,0xa001,MOD_CONTROL,(UINT)m_strKey[0]);

其中m_strKey是改对话框类CGetTimeDlg的一个CString型成员变量。0xa001是热键ID,范围是从0x0000

到 0xBFFF,可以自己设定。

这两句的作用是注册一个Ctrl+J的热键。

再为该对话框类添加一个BOOL型成员变量:m_bShow;用来表示对话框当前是显示还是隐藏。当然这个变量

初始化为false,因为对话框开始时不可见。既然注册了热键,就要接收消息以判断用户是否按了热键,因此要重载对话框类的PreTranslateMessage(MSG*

pMsg),从消息中截获热键消息:

if(pMsg-message==WM_HOTKEY && pMsg-wParam==0Xa001)

{

if(m_bShow==true)

ShowWindow(SW_HIDE);

else

ShowWindow(SW_SHOW);

m_bShow=!m_bShow;

}

再在对话框的OnClose()中加上两句 :

UnregisterHotKey(this-m_hWnd,0Xa001);

DestroyWindow();

好了,现在运行看看,是不是能响应热键了?

4、实现记录时间

要记录时间,就要用到MFC的CTime类,这个类可以很方便地处理时间日期相关的问题。为了更高效地处理记录时间问题,我封装了一个函数:

void WriteTime(CString strNote)

{

CString strTime,str,strDate,strFileName;

int t;

DWORD dwAttr;

CTime time=CTime::GetCurrentTime();//得到当前系统时间

t=time.GetHour();

str.Format("%d",t);

strTime=str;

t=time.GetMinute();

str.Format("%d",t);

strTime=strTime+":"+str;

t=time.GetSecond();

str.Format("%d",t);

strTime=strTime+":"+str;

t=time.GetYear();

str.Format("%d",t);

strDate=str;

t=time.GetMonth();

str.Format("%d",t);

strDate=strDate+"-"+str;

t=time.GetDay();

str.Format("%d",t);

strDate=strDate+"-"+str;

strFileName="time.txt";

dwAttr=GetFileAttributes(strFileName);

if(dwAttr==0xFFFFFFFF)//如果该文件不存在就创建一个

{

CStdioFile file;

file.Open(strFileName,CFile::modeCreate|CFile::modeWrite);

file.Close();

}

CStdioFile file;

file.Open(strFileName,CFile::modeWrite);

file.SeekToEnd();//这一句很重要,不然会将以前写的覆盖

file.WriteString(strDate+" "+strTime+" "+strNote);

file.WriteString("\r\n");

file.Close();

}

其中strNote参数是一个备注,本函数的作用是将当前系统时间记录在一个time.txt文件中,比如:

2003-3-15 0:31:25 开机

开机是strNote(备注)。

因此,当要记录开机时间时可以调用WriteTime(“开机”);

要记录关机时间可以用WriteTime(“关机”);

5、实现关机时记录时间

如何在系统关闭也就是关机时得到通知呢?当关机时,系统向还在运行的程序发送WM_QUERYENDSESSION消息,以询问该程序是否可以结束,因此可以对这个消息进行响应,源码如下:

BOOL CGetTimeDlg::OnQueryEndSession()

{

if (!CDialog::OnQueryEndSession())

return FALSE;

WriteTime("关机");

// TODO: 在此添加专用的查询结束会话代码

return TRUE;

}

这里要注意一点:这种记录关机时间的方法有一定的局限,比如用户注销,重启时都可能被记录为关机。而且当强制关机时,系统不再向程序发送WM_QUERYENDSESSION消息,这时这种方法不起作用。如果大家有什么更好的办法,希望你们能告诉我。

自此这个小程序的全部代码编写完成,该程序在vc.net+win2000下调试通过。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有