在本文中,将探讨如何在Windows 10操作系统中使用C++和MFC(Microsoft Foundation Classes)来监控电脑的电源状态。特别地,将关注屏幕的开启、关闭和调暗状态,这对于开发桌面壁纸更换程序等应用程序非常有用。
在Michael Dunn于2006年12月29日发表的文章《Vista Goodies inC++: Monitoring the Computer's Power Status》中,他讨论了如何确定电源来源、电源方案、电源状况和电源状态。本文将基于Dunn的方法进行扩展,但专注于屏幕状态的监控。
本项目是一个基于对话框的MFCWindows应用程序,使用Visual Studio 2015 Community Edition在运行Windows 10Creator's Update的电脑上开发。虽然未在其他版本上测试,但代码应该可以在Windows Vista或更高版本上运行。
为了捕获电源设置事件(如关闭显示器)生成的通知消息,使用RegisterPowerSettingNotification
函数。为了释放这个捕获的通知,需要建立一个变量来注销通知。
在程序的OnInitDialog
函数中,插入以下代码:
m_hScreenStateNotify = RegisterPowerSettingNotification(
this->m_hWnd, &GUID_CONSOLE_DISPLAY_STATE, DEVICE_NOTIFY_WINDOW_HANDLE);
在OnDestroy
函数中,释放注册:
void CDetectScreenSleepDlg::OnDestroy()
{
CDialogEx::OnDestroy();
UnregisterPowerSettingNotification(m_hScreenStateNotify);
}
消息处理函数的核心部分与Dunn的文章类似,包含在消息处理函数中。需要添加一个消息处理函数来处理WM_POWERBROADCAST
消息。
UINT CDetectScreenSleepDlg::OnPowerBroadcast(UINT nPowerEvent, LPARAM nEventData)
{
CString sMsg;
sMsg.Format(_T("Power Broadcast messages: %d"), m_nPowerMessages);
POWERBROADCAST_SETTING *pps = (POWERBROADCAST_SETTING*)nEventData;
if(GUID_CONSOLE_DISPLAY_STATE != pps->PowerSetting)
{
return 0;
}
UINT uData = pps->Data[0];
int nMax = m_lcEvents.GetItemCount();
CTime tNow = CTime::GetCurrentTime();
sMsg.Format(_T("%u"), uData);
CString sStatus[3] = { _T("Off"), _T("On"), _T("Dimmed") };
int nItem = m_lcEvents.InsertItem(nMax, sMsg);
m_lcEvents.SetItemText(nItem, 1, sStatus[uData]);
m_lcEvents.SetItemText(nItem, 2, tNow.Format(_T("%a %B %d, %y %I:%M:%S %p")));
return CDialogEx::OnPowerBroadcast(nPowerEvent, nEventData);
}
在壁纸设置程序中,设置了一个程序变量为TRUE
(进行壁纸更改)当显示器处于开启状态,而当显示器状态为OFF
或DIMMED
时设置为FALSE
。