关机、注销、登录、锁屏、资源管理器重启等消息
- 关机、重启消息 WM_QUERYENDSESSION:
关机、重启时windows会广播一个WM_QUERYENDSESSION 消息,接收到该消息后,应用可以做一些清理退出动作,如果未处理返回,win10等会出现应用程序阻止关机、重启的提示,win7等则会等待5s左右,然后强行关闭应用。使用时直接在 WindowProc 中处理 WM_QUERYENDSESSION 即可。 - 电源相关消息 WM_POWERBROADCAST:
睡眠、休眠、唤醒或电源设置改变等,系统会发送 WM_POWERBROADCAST 消息。使用:
1、注册消息:
//HPOWERNOTIFY hPowerNotify;//hPowerNotify类型,.h中声明
hPowerNotify = RegisterPowerSettingNotification(m_hWnd, &GUID_LIDSWITCH_STATE_CHANGE, DEVICE_NOTIFY_WINDOW_HANDLE);//注册WM_POWERBROADCAST消息
2、WindowProc 处理:
case WM_POWERBROADCAST://判断睡眠、休眠等
{
OutputDebugString(_T("WM_POWERBROADCAST "));
if (wParam == PBT_APMSUSPEND)//系统暂停运行
OutputDebugString(_T("power off"));
else if ((wParam == PBT_APMRESUMEAUTOMATIC) || (wParam == PBT_APMRESUMESUSPEND))//唤醒
OutputDebugString(_T("power ON"));
else
OutputDebugString(_T("other option"));
}
3、关闭、退出时清理:
WTSUnRegisterSessionNotification(m_hWnd);
- 登录、注销、锁屏等 WM_WTSSESSION_CHANGE 消息:
登录、注销、锁屏、用户切换等会导致 session 改变的操作,系统会发送 WM_WTSSESSION_CHANGE 消息。使用:
1、注册消息:
WTSRegisterSessionNotification(m_hWnd, NOTIFY_FOR_THIS_SESSION);
2、WindowProc 处理:
case WM_WTSSESSION_CHANGE://判断登录、注销、锁屏等
{
switch (wParam)
{
case WTS_CONSOLE_CONNECT:
OutputDebugString(_T("session login"));
break;
case WTS_CONSOLE_DISCONNECT:
OutputDebugString(_T("session logoff"));
break;
case WTS_SESSION_LOCK:
OutputDebugString(_T("session lock"));
break;
default:
break;
}
}
3、退出时取消注册:
WTSUnRegisterSessionNotification(m_hWnd);
4、使用时需要包含库:
#include <WtsApi32.h>
#pragma comment(lib,"WtsApi32.lib")
- 资源管理器重启:
资源管理器重启时可能需要添加托盘图标等。
1、.h函数声明
afx_msg LRESULT OnRestartExplorer(WPARAM wParam, LPARAM lParam);
2、.cpp声明:
const UINT WMEX_TASKBARCREATED = ::RegisterWindowMessage(TEXT("TaskbarCreated"));
3、消息映射中添加:
ON_REGISTERED_MESSAGE(WMEX_TASKBARCREATED, OnRestartExplorer)
4、重启处理函数:
LRESULT CPowerMassageDlg::OnRestartExplorer(WPARAM wParam, LPARAM lParam) //判断资源管理器重启
{
OutputDebugString(_T("RestartExplorer"));
return TRUE;
}
- 判断处于注销登录界面的方法(http://blog.csdn.net/u010780613/article/details/53834999):
typedef HDESK(WINAPI *PFNOPENDESKTOP)(LPSTR, DWORD, BOOL, ACCESS_MASK);
typedef BOOL(WINAPI *PFNCLOSEDESKTOP)(HDESK);
typedef BOOL(WINAPI *PFNSWITCHDESKTOP)(HDESK);
BOOL PP_IsWorkStationLocked()//判断是否处于锁屏界面
{
BOOL bLocked = FALSE;
static HMODULE hUser32 = LoadLibrary(_T("user32.dll"));
if (hUser32)
{
static PFNOPENDESKTOP fnOpenDesktop = (PFNOPENDESKTOP)GetProcAddress(hUser32, "OpenDesktopA");
static PFNCLOSEDESKTOP fnCloseDesktop = (PFNCLOSEDESKTOP)GetProcAddress(hUser32, "CloseDesktop");
static PFNSWITCHDESKTOP fnSwitchDesktop = (PFNSWITCHDESKTOP)GetProcAddress(hUser32, "SwitchDesktop");
if (fnOpenDesktop && fnCloseDesktop && fnSwitchDesktop)
{
HDESK hDesk = fnOpenDesktop("Default", 0, FALSE, DESKTOP_SWITCHDESKTOP);
if (hDesk)
{
bLocked = !fnSwitchDesktop(hDesk);
fnCloseDesktop(hDesk);
}
}
}
return bLocked;
}
使用:
if (!GetForegroundWindow() && PP_IsWorkStationLocked() || !m_bSystemRunning)//检测是否处于锁屏/登录等界面
OutputDebugString(_T("In login window."));
全部代码(把不相关的去掉了):
#include <WtsApi32.h>
#pragma comment(lib,"WtsApi32.lib")
// CPowerMassageDlg 对话框
const UINT WMEX_TASKBARCREATED = ::RegisterWindowMessage(TEXT("TaskbarCreated"));
BEGIN_MESSAGE_MAP(CPowerMassageDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_REGISTERED_MESSAGE(WMEX_TASKBARCREATED, OnRestartExplorer)
END_MESSAGE_MAP()
// CPowerMassageDlg 消息处理程序
BOOL CPowerMassageDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
hPowerNotify = RegisterPowerSettingNotification(m_hWnd, &GUID_LIDSWITCH_STATE_CHANGE, DEVICE_NOTIFY_WINDOW_HANDLE);//注册WM_POWERBROADCAST消息
WTSRegisterSessionNotification(m_hWnd, NOTIFY_FOR_THIS_SESSION);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
typedef HDESK(WINAPI *PFNOPENDESKTOP)(LPSTR, DWORD, BOOL, ACCESS_MASK);
typedef BOOL(WINAPI *PFNCLOSEDESKTOP)(HDESK);
typedef BOOL(WINAPI *PFNSWITCHDESKTOP)(HDESK);
BOOL PP_IsWorkStationLocked()//判断是否处于锁屏界面
{
BOOL bLocked = FALSE;
static HMODULE hUser32 = LoadLibrary(_T("user32.dll"));
if (hUser32)
{
static PFNOPENDESKTOP fnOpenDesktop = (PFNOPENDESKTOP)GetProcAddress(hUser32, "OpenDesktopA");
static PFNCLOSEDESKTOP fnCloseDesktop = (PFNCLOSEDESKTOP)GetProcAddress(hUser32, "CloseDesktop");
static PFNSWITCHDESKTOP fnSwitchDesktop = (PFNSWITCHDESKTOP)GetProcAddress(hUser32, "SwitchDesktop");
if (fnOpenDesktop && fnCloseDesktop && fnSwitchDesktop)
{
HDESK hDesk = fnOpenDesktop("Default", 0, FALSE, DESKTOP_SWITCHDESKTOP);
if (hDesk)
{
bLocked = !fnSwitchDesktop(hDesk);
fnCloseDesktop(hDesk);
}
}
}
return bLocked;
}
LRESULT CPowerMassageDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_QUERYENDSESSION://可判断关机、重启等
{
OutputDebugString(_T("WM_QUERYENDSESSION"));
}
break;
case WM_POWERBROADCAST://判断睡眠、休眠等
{
OutputDebugString(_T("WM_POWERBROADCAST "));
if (wParam == PBT_APMSUSPEND)//系统暂停运行
OutputDebugString(_T("power off"));
else if ((wParam == PBT_APMRESUMEAUTOMATIC) || (wParam == PBT_APMRESUMESUSPEND))//唤醒
OutputDebugString(_T("power ON"));
else
OutputDebugString(_T("other option"));
}
break;
case WM_DESTROY:
{
WTSUnRegisterSessionNotification(m_hWnd);
UnregisterPowerSettingNotification(hPowerNotify);
}
case WM_WTSSESSION_CHANGE://判断登录、注销、锁屏等
{
switch (wParam)
{
case WTS_CONSOLE_CONNECT:
OutputDebugString(_T("session login"));
break;
case WTS_CONSOLE_DISCONNECT:
OutputDebugString(_T("session logoff"));
break;
case WTS_SESSION_LOCK:
OutputDebugString(_T("session lock"));
break;
default:
break;
}
}
default:
break;
}
return CDialogEx::WindowProc(message, wParam, lParam);
}
LRESULT CPowerMassageDlg::OnRestartExplorer(WPARAM wParam, LPARAM lParam) //判断资源管理器重启
{
OutputDebugString(_T("RestartExplorer"));
return TRUE;
}
代码链接:
VS2015工程:http://download.csdn.net/detail/yangyang031213/9891578
https://github.com/yangyang0312/cpp/tree/master/windows/PowerMassage