testdlg.cpp

来自「用MFC类库开发了OS关机、重启、定时关机的应用程序」· C++ 代码 · 共 278 行

CPP
278
字号
// TestDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Test.h"
#include "TestDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTestDlg dialog

CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CTestDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CTestDlg)
	m_Hourt = 0;
	m_Minute = 0;
	fResult=TRUE;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	ShutDown_or_Restart=TRUE;
}

void CTestDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTestDlg)
	DDX_Text(pDX, IDC_EDIT_HOUR, m_Hourt);
	DDV_MinMaxInt(pDX, m_Hourt, 0, 24);
	DDX_Text(pDX, IDC_EDIT_MINUTE, m_Minute);
	DDV_MinMaxInt(pDX, m_Minute, 0, 60);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
	//{{AFX_MSG_MAP(CTestDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN_CALL_WINSHUT, OnBtnCallWinshut)
	ON_BN_CLICKED(IDC_BTN_CALL_RESTART, OnBtnCallRestart)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_BTN_APPLY, OnBtnApply)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTestDlg message handlers

BOOL CTestDlg::OnInitDialog()
{
	//CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	CDialog::OnInitDialog(); 

	// 设置定时器,每秒一次心跳 
	SetTimer(1, 1000, NULL); 

	// 将图标放入系统托盘 
	NOTIFYICONDATA nd; 
	nd.cbSize = sizeof (NOTIFYICONDATA); 
	nd.hWnd = m_hWnd; 
	nd.uID = IDI_ICON; 
	nd.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP; 
	nd.uCallbackMessage= WM_NOTIFYICON; 
	nd.hIcon = m_hIcon;  
	
	strcpy(nd.szTip, "我的闹钟");

	Shell_NotifyIcon(NIM_ADD, &nd); 
	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CTestDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CTestDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CTestDlg::OnBtnCallWinshut() 
{
	// TODO: Add your control notification handler code here
	ShutDown_or_Restart=FALSE;
	CTestDlg::ShutDown_Restart();
}

void  CTestDlg::ShutDown_Restart()
{
	TOKEN_PRIVILEGES tkp; 
	HANDLE hToken;
	if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))  
	{
		MessageBox("OpenProcessToken failed!"); 
	} 
	LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid); //获得本地机唯一的标识 
	tkp.PrivilegeCount = 1;   
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0); //调整获得的权限
	
	if (GetLastError() != ERROR_SUCCESS)  
	{
		MessageBox("AdjustTokenPrivileges enable failed!"); 
	}
	fResult =InitiateSystemShutdown(
		NULL,                 // 要关的计算机用户名,可在局域网网中关掉对方的机器,NULL表示关本机 
		"定时关机程序,WINDOWS将在上面的时间内关机,请做好保存工作!",  // 显示的消息
		30,                                // 关机所需的时间 
		TRUE,
		ShutDown_or_Restart);                             //设为TRUE为重起,设为FALSE为关机 
	if(!fResult)
	{
		MessageBox("InitiateSystemShutdown failed.");  
	}
	tkp.Privileges[0].Attributes = 0;
	AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0);  

	if (GetLastError() != ERROR_SUCCESS)  
	{
		MessageBox("AdjustTokenPrivileges disable failed.");  
	}
	
	ExitWindowsEx(EWX_SHUTDOWN,0);     //开始关机 
}

void CTestDlg::OnBtnCallRestart() 
{
	// TODO: Add your control notification handler code here
	ShutDown_or_Restart=TRUE;
	CTestDlg::ShutDown_Restart();
}

void CTestDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	static CString strTemp;
	static int Count = 0;
	COleDateTime dtTime;
	
	// 刷新显示的时间 
	//常在论坛里遇到人问怎么获得当前时间,这相知道了吧
	dtTime = COleDateTime::GetCurrentTime(); 
	strTemp.Format("现在时间 %02i:%02i:%02i ",dtTime.GetHour(),dtTime.GetMinute(),dtTime.GetSecond()); 
	GetDlgItem(IDC_CURTIME)->SetWindowText(strTemp);
	////////////设定关机时间
	if(dtTime.GetHour()==m_Hourt && dtTime.GetMinute()==m_Minute && dtTime.GetSecond()==0)
	{
		CTestDlg::OnBtnCallWinshut();
	}
	///////////////////////////////////////////////////////////////////
	// 刷新剩余时间值 
	/*if (nIDEvent == IDC_BTN_APPLY) Count = 0;//若用户重新定义了时间间隔,则重新开始计时 
	Count++; 
	int RestTime; 
	RestTime = m_Interval - Count/60; 
	if (RestTime <= 0) 
	{
		Count = 0;
	}*/
	int RestTime;
	if (m_Hourt==0)
	{
		RestTime=0;
	}
	else
	{
		RestTime=(m_Hourt-dtTime.GetHour())*60 + (m_Minute-dtTime.GetMinute());
	}	
	strTemp.Format("离下次提醒还差 %i 分钟", RestTime);
	GetDlgItem(IDC_RESTTIME)->SetWindowText(strTemp);
	
	CDialog::OnTimer(nIDEvent);
}

void CTestDlg::OnOK() 
{
	// TODO: Add extra validation here	
	OnSysCommand(SC_MINIMIZE, 0x0000); 
	return;
	//CDialog::OnOK();
}

void CTestDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
	// 释放定时器 
	KillTimer(1); 
	
	// 将图标从系统托盘中删除 
	NOTIFYICONDATA nd; 
	nd.cbSize = sizeof (NOTIFYICONDATA); 
	nd.hWnd = m_hWnd;
	nd.uID=IDR_MAINFRAME;
	nd.hIcon=NULL;
	nd.uCallbackMessage= WM_NOTIFYICON; 
	
	Shell_NotifyIcon(NIM_DELETE, &nd);

	CDialog::OnCancel();
}

afx_msg void CTestDlg::OnNotifyIcon(WPARAM wParam, LPARAM lParam) 
{
	//响应在托盘图标上的单击
	//wParam中是响应消息的图标ID,lParam中则是Windows的消息
	if((wParam == IDI_ICON)&&(lParam == WM_LBUTTONDOWN))
		ShowWindow(SW_SHOWNORMAL);
	if ((wParam == IDI_ICON)&&(lParam == WM_LBUTTONDBLCLK))
		ShowWindow(SW_SHOWNORMAL);
} 

afx_msg BOOL CTestDlg::OnQueryEndSession()
{
	// 在用户退出Windows时自动退出应用程序
	CTestDlg::OnCancel();
	return TRUE;
}

afx_msg void CTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	// TODO: Add your specialized code here and/or call the base class
	// 屏蔽最大化(MFC Bug),将最小化重定向至隐藏窗口
	if (nID == SC_MAXIMIZE)
		return;
	if (nID == SC_MINIMIZE)
		ShowWindow(SW_HIDE);
	else
		CWnd::OnSysCommand(nID, lParam);
}

void CTestDlg::OnBtnApply() 
{
	// TODO: Add your control notification handler code here
	// 重置时间间隔 
	UpdateData(); 
	OnTimer(IDT_APPLY);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?