美文网首页
Windows登录、锁屏的判定以及消息捕捉

Windows登录、锁屏的判定以及消息捕捉

作者: googoler | 来源:发表于2020-06-24 10:18 被阅读0次

    1、如果窗口想获取相关消息,需要注册Session的Notification,需要Wtsapi32.dll中的两个函数:WTSRegisterSessionNotificationWTSUnRegisterSessionNotification,分别在窗口创建和销毁的时候调用。

    typedef BOOL (WINAPI *WTSRegisterSessionNotification)(HWND, DWORD);
    typedef BOOL (WINAPI *WTSUnRegisterSessionNotification)(HWND);
    
    #define WTSAPI_DLL     _T("Wtsapi32.dll")
    
    #define MY_WTS_SESSION_FUNCTION(fnType, fnName, arg)  
        BOOL bRet = FALSE; 
        HMODULE hLibrary = ::LoadLibrary(WTSAPI_DLL); 
        if (hLibrary)  
       { 
           fnType fn  
               = (fnType)::GetProcAddress(hLibrary, fnName);  
           if (fn)
           {   
               bRet = fn##arg;
           }  
           ::FreeLibrary(hLibrary);  
       }  
        return bRet;
    
    
    BOOL MyWTSRegisterSessionNotification(HWND hWnd, DWORD dwFlag)
    {
       MY_WTS_SESSION_FUNCTION(WTSRegisterSessionNotification,
           "WTSRegisterSessionNotification", (hWnd, dwFlag));
    }
    
    BOOL MyWTSUnRegisterSessionNotification(HWND hWnd)
    {
       MY_WTS_SESSION_FUNCTION(WTSUnRegisterSessionNotification,
           "WTSUnRegisterSessionNotification", (hWnd));
    }
    

    这样,在SESSION切换的时候,窗口就可以收到一个WM_WTSSESSION_CHANGE消息。

    WTSRegisterSessionNotification(m_hWnd, NOTIFY_FOR_THIS_SESSION);
    
    WTSUnRegisterSessionNotification(m_hWnd);
     
    
    ON_MESSAGE(WM_WTSSESSION_CHANGE, OnSessionChange)
    
    OnSessionChange(WPARAM wParam, LPARAM lParam)
    {
        switch (wParam)
        {
         case WTS_CONSOLE_CONNECT:
                 break;
         case WTS_CONSOLE_DISCONNECT:
                break;
         case WTS_REMOTE_CONNECT:
                break;
         case WTS_REMOTE_DISCONNECT:
                break;
         case WTS_SESSION_LOGON:
                 break;
         case WTS_SESSION_LOGOFF:
                 break;
         case WTS_SESSION_LOCK: //锁住屏幕
                 break;
         case WTS_SESSION_UNLOCK://解锁屏幕
                break;
         case WTS_SESSION_REMOTE_CONTROL:
                 break;
          default:
                  break;
          }
    
     return 0;
    }
    

    2、如果不依赖窗口,需要判断当前系统是否处于锁屏状态,有一段比较tricky的代码……就是试图SwitchDesktop,如果失败就认为在锁屏。

    这种方法有另一个优点:可以判断ctrl+alt+delete后系统暂时“锁定”以及“解锁”的状态,而这种状态改变,窗口是没法收到WM_WTSESSIONCHANGE的。

    typedef HDESK (WINAPI *PFNOPENDESKTOP)(LPSTR, DWORD, BOOL, ACCESS_MASK);
    typedef BOOL (WINAPI *PFNCLOSEDESKTOP)(HDESK);
    typedef BOOL (WINAPI *PFNSWITCHDESKTOP)(HDESK);
    
    BOOL PP_IsWorkStationLocked()
    {
        // note: we can't call OpenInputDesktop directly because it's not
        // available on win 9x
        BOOL bLocked = FALSE;
    
        // load user32.dll once only
        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);
                   // cleanup
                   fnCloseDesktop(hDesk);
               }
           }
        }
    
       return bLocked;
    
    }
    

    参考:

    相关文章

      网友评论

          本文标题:Windows登录、锁屏的判定以及消息捕捉

          本文链接:https://www.haomeiwen.com/subject/gtzlfktx.html