关机、注销、登录、锁屏、资源管理器重启等消息

本文介绍Windows系统中的关键消息处理机制,包括关机、重启、电源变化、登录注销等场景下的消息捕获与响应方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关机、注销、登录、锁屏、资源管理器重启等消息

  • 关机、重启消息 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;
}
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值