MFC – 定时关闭一个软件 关闭自己

作者: admin 分类: C++ 发布时间: 2019-10-29 16:15

关闭进程的方法:

int TerminateProcessFromId()   //关闭进程 
{ 
       BOOL bRet=FALSE; 
       if(hProcess!=NULL) 
       { 
              bRet=::TerminateProcess(hProcess,0); 
       } 
       ::CloseHandle(hProcess); 
       return 0; 
}

开始按钮的事件

void CchenDlg::OnBnClickedBtnStart()
{
    // TODO: 在此添加控件通知处理程序代码
    CString currPID;
    DWORD dwId;//当前PID
    m_currPID.GetWindowTextW(currPID);
    dwId = _ttoi(currPID); 
    hProcess=::OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwId);
    if(hProcess==NULL)
    {
        MessageBox(L"没有找到程序,请输入正确的PID");
    }
    else{
        SetTimer(1,1000,NULL);
        MessageBox(L"操作成功,开始监听");
    }
}

OnTimer中的操作

void CchenDlg::OnTimer(UINT_PTR nIDEvent)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值

    CDialogEx::OnTimer(nIDEvent);
    CString localTime; 
    tm=CTime::GetCurrentTime();
    int hour = tm.GetHour();
    CTime closeTm;
    //这里设置一下结束时间
    closeTm =CTime(tm.GetYear(),tm.GetMonth(),tm.GetDay(),4,0,0,-1);
    
    CTimeSpan s;
    if(hour>4)
    {
        //说明要跨越天数
        //先获取当天最后一秒的时间
        CTime finallyTime =CTime(tm.GetYear(),tm.GetMonth(),tm.GetDay(),23,59,59,-1);
        CTimeSpan finallySpan = finallyTime-tm;
        //closeTm = closeTm+finallySpan+hour4;
        s = finallySpan + CTimeSpan(0,4,0,1);//4小时
    }
    else
    {
         s = closeTm-tm;
         if(s<=0)
         {
            //说明时间到了
            TerminateProcessFromId();
            m_time.SetWindowTextW(L"(0秒)程序已关闭");
            KillTimer(1);
            
         }
    }
    int m_hour= s.GetHours();
    int m_min = s.GetMinutes();
    int m_s = s.GetSeconds();
    CString timeStr;
    timeStr.Format(_T("%d时%d分%d秒"),m_hour,m_min,m_s);
    localTime=tm.Format("%Y年%m月%d日 %X");
    m_CurrTime.SetWindowTextW(localTime);
    m_time.SetWindowTextW(timeStr);
}

如果想关闭自身,则需要获得自身PID  VC获取自身PID 
环境:VC6,windowsXP SP3
在VC中获取PID实际上很简单,来看下代码:
 include  <windows.h> 
 include  <stdio.h> 
 int main()
 {
     DWORD _PID;
     _PID=::GetCurrentProcessId();
     printf("%d\n",_PID);
     return 0;
 }
 ————————————————
 版权声明:本文为CSDN博主「sunnysab」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
 原文链接:https://blog.csdn.net/sunnysab/article/details/9367077

CTime以及其它时间差CTimeSpan

一、DateTimePicker控件

引用一个DateTimePicker控件,关联变量m_date为DateTimeCtrl类型,然后在响应事件中加入如下代码:

   CTime tm;
   m_date.GetTime(tm);
   CString strDate=tm.Format(“%Y-%m-%d”);

就可以获取了…但是不知为何这个还和Vc的版本问题有关,开始时候我用的版本总是出错,或者srtDate为空,或者不是用户选择的日期,后来换了一个VC版本就能得到正确的数据了…

另外如果关联一个CTime类型的变量也能解决上面的问题,但是初始化的日期是1970-01-01而上面方法中初始化的日期是当前日期…所以根据用户需要的设定可以选择任何一种方法进行解决…

二、CTimeSpan获取时间差

要获取两个时间差,如两个CTime的时间差,可以使用MFC中的CTimeSpan类。CTime time1 = CTime::GetCurrentTime(); …其它代码… CTime time2 = CTime::GetCurrentTime(); // 两个CTime相减得到CTimeSpan CTimeSpan timeSpan = time2 – time1; // 得到总的秒数 int nTSeconds = timeSpan.GetTotalSeconds();

     注意GetTotalSeconds与GetSeconds的区别:GetTotalSeconds返回总的秒数,GetSeconds返回总是小于60,如:如果时间经过了100秒, GetTotalSeconds返回100,而GetSeconds返回40,因为有60秒转为一分钟了,同时使用GetMinutes会返回1,即1分40秒。

其它类似函数:GetDays(); // 返回日数 GetHours(); // 返回小时数(-23至23之间)GetTotalHours(); // 返回总的小时数 GetMinutes(); // 返回分钟数(-59至59之间)GetTotalMinutes(); // 返回总的分钟数 GetSeconds(); // 返回秒数(-59至59之间)GetTotalSeconds(); // 返回总的秒数三、CTime总结

1.初始化

     m_begintime=CTime(2004,1,1,0,0,0,-1);//参数依次为year,month,day,hour,minite,second
     m_endtime =CTime::GetCurrentTime();//当前时间

2.日期比较

CTimeSpan span;

span=time1-time2;

得到两时间的间隔.

可以取得span.GetHours().等

3.access数据库查询

使用DateDiff()函数,具体参照access帮助

CString timesql;
timesql.Format(” Where DateDiff(‘d’,%s,’%s’)<=0″,”日期”,m_begintime.Format(“%Y-%m-%d”));

4读取日期字段(odbc)

    CDBVariant var;
      recset.GetFieldValue(i,var);
     s.Format(“%d-%d-%d”,(var.m_pdate)->year,(var.m_pdate)->month,
      (var.m_pdate)->day);

5.CTime转换为CString

例:
   m_begintime.Format(“%Y-%m-%d”);//2004-10-03

6.CString转换为CTime

    //s=”2004-10-5″
   int first=s.Find(‘-‘);
    int second=s.Find(‘-‘,first+1);

    int year=atoi(s.Left(4));
    int month=atoi(s.Mid(first+1,second-first+1));
    int day=atoi(s.Mid(second+1,s.GetLength()-second-1));
    CTime temp(year,month,day,0,0,0);

7.判断CString是否表示的正确日期格式

//判断是否为2004-01-13 ch 可代表其他分隔符
bool IsDate(CString str,char ch)
{
if(str.IsEmpty()) return false;
//日期分段
int first=str.Find(ch);
int second=str.Find(ch,first+1);

int year=atoi(str.Left(4));
int month=atoi(str.Mid(first+1,second-first+1));
int day=atoi(str.Mid(second+1,str.GetLength()-second-1));
    //判断
if (year < 2000 || year >= 2010)
{
   return false;
}
else if (month< 1 || month >12)
{
   return false;
}
else if (day< 1 || day > 31)
{
   return false;
}
else if (month == 4 || month == 6 || month == 9 || month == 11)
{
   if(day > 30)
   {
    return false;
   }
   else
   {
    return true;
   }
}
else if (month == ‘2’)
{
   if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
   {
    if (day>29)
    {
     return false;
    }
    else
    {
     return true;
    }
   }
   else if (day>28)
   {
    return false;
   }
   return true;
}
else
{
   return true;
}
   

}

四、

在MFC中操作时间的类主要有两对:CTime和CTimeSpan与COleDateTime和COleDateTimeSpan,CTime和CTimeSpan主要封装了ANSI time_t和关于time_t的Run-Time库的主要函数,CTime里面使用的成员变量是time_t类型,该类型是个long型,由于long类型的原因,所以该类只能处理4294967296秒约68年的数据,所以用CTime只能处理1970年到2038年的日期。
    幸好,MFC同时提供了COleDateTime和COleDateTimeSpan类,使用该两个类完全可以代替CTime和CTimeSpan,COleDateTime和COleDateTimeSpan类所使用的成员变量是DATE类型,该类型是个double类型,而且使用的单位是日,所以可以处理从100年1月1日到9999年12月31日的日期时间,COleDateTime类的日期计算主要是操作公有成员变量COleDateTime::m_dt,该变量是DATE即double类型,该变量是为零时是1899年12月30日0时0分0秒,大于零时的日期比1899年12月30日0时0分0秒大,反之亦然,例如:
COleDateTime t;
t.m_dt=0;
AfxMessageBox(t.Format(“%Y-%m-%d %H:%M:%S”));
运行的结果是:1899-12-30 00:00:00

COleDateTime t;
t.m_dt=39444.437731;
AfxMessageBox(t.Format(“%Y-%m-%d %H:%M:%S”));
运行的结果是:2007-10-28 10:30:20

反过来以可以得到变量的值,例如:
COleDateTime t(2004,12,28,22,22,22);
CString str;
str.Format(“%f”,t.m_dt);
AfxMessageBox(str);
运行的结果是:38349.932199

COleDateTimeSpan类是用于对COleDateTime类的两个时间的时间间隔的计算,COleDateTimeSpan类使用的成员变量COleDateTimeSpan::m_span是一个double类型是用于记录两个COleDateTime::m_dt的时间差,例如:
COleDateTime t1(2006,1,1,0,0,0);
COleDateTime t2(2007,1,1,0,0,0);
COleDateTimeSpan ts=t2-t1;
CString str;
str.Format(“%f”,ts.m_span);
AfxMessageBox(str);
运行的结果是:365.000000

反过来也可以得到日期
COleDateTime t1(2006,1,1,0,0,0);
COleDateTimeSpan ts;
ts.m_span=400.0;
COleDateTime t2=t1+ts;
AfxMessageBox(t2.Format(“%c”));
运行的结果是:02/05/07 00:00:00

可是在使用COleDateTimeSpan类中以下的几个函数可要小心,这不知道是不是MFC的一个Bug,
double GetTotalDays( ) const;
double GetTotalHours( ) const;
double GetTotalMinutes( ) const;
double GetTotalSeconds( ) const;
几个函数的返回值都是double类型
但是,如double GetTotalSeconds( ) const;在MFC内部的原形是:
_AFXDISP_INLINE double COleDateTimeSpan::GetTotalSeconds() const
{ ASSERT(GetStatus() == valid);
   long lReturns = (long)(m_span * 24 * 60 * 60 + AFX_OLE_DATETIME_HALFSECOND);
   return lReturns;
}
看到没有,它返回的实际是个long类型,并不是一个double类型,所以在使用这几个函数的时候计算两个时间的间隔不要太大,特别是GetTotalSeconds( )函数,如计算两个时间的间隔大于68年时就会溢出,所以我建议直接读取COleDateTimeSpan::m_span变量的值,这是一个单位为日的时间间隔,例如:
COleDateTime t1(2000,1,1,0,0,0);
COleDateTime t2(2070,1,1,0,0,0);
COleDateTimeSpan ts=t2-t1;
CString str;
str.Format(“%f”,ts.GetTotalSeconds());
AfxMessageBox(str);
运行的结果是:-2085892096.000000
这个结果明显是一个溢出,如果使用
str.Format(“%f”,ts.m_span*86400);
则会得到2209075200.000000。

所以灵活使用COleDateTime类的m_dt变量和COleDateTimeSpan类的m_span变量操作会得到意想不到的收获

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

发表评论

标签云