如果系统处于活动状态,如何检入C ++?

问题描述 投票:7回答:4

我正在编写代码,只有当PC上没有人为活动时才需要运行,就像屏幕保护程序运行时一样。有关如何在Windows下的c ++中执行此操作的任何建议?

@talnicolas,只是使用未使用的资源,人们离开计算机多少次但是他们在另一个地方?

c++ windows background worker
4个回答
11
投票

你可以使用GetLastInputInfo来检查用户空闲的时间长短(不是在鼠标周围移动或在键盘上键入内容)和SystemParametersInfo来检查屏幕保护程序是否处于活动状态。

Example

#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>

// do something after 10 minutes of user inactivity
static const unsigned int idle_milliseconds = 60*10*1000;
// wait at least an hour between two runs
static const unsigned int interval = 60*60*1000;

int main() {
    LASTINPUTINFO last_input;
    BOOL screensaver_active;

    // main loop to check if user has been idle long enough
    for (;;) {
        if ( !GetLastInputInfo(&last_input)
          || !SystemParametersInfo(SPI_GETSCREENSAVERACTIVE, 0,  
                                   &screensaver_active, 0))
        {
            std::cerr << "WinAPI failed!" << std::endl;
            return ERROR_FAILURE;
        }

        if (last_input.dwTime < idle_milliseconds && !screensaver_active) {
            // user hasn't been idle for long enough
            // AND no screensaver is running
            Sleep(1000);
            continue;
        }

        // user has been idle at least 10 minutes
        do_something();
        // done. Wait before doing the next loop.
        Sleep(interval);
    }
}

请注意,我在Linux机器上编写了该代码,因此无法对其进行测试。


2
投票

使用SystemParametersInfo(...)

   private const int SPI_GETSCREENSAVERACTIVE = 16;
   SystemParametersInfo( SPI_GETSCREENSAVERACTIVE, 0, 
         ref isActive, 0 );
      return isActive;

参考:http://www.codeproject.com/KB/cs/ScreenSaverControl.aspx


2
投票

这只是对在Windows 8.1和Windows 10上测试的Niklas B.答案的一个小更新。

变更说明如下:

  • LASTINPUTINFO已经初步确定了cbSize
  • 而不是检查SPI_GETSCREENSAVERACTIVE,检查SPI_GETSCREENSAVERRUNNING
  • 计算idle_time并与idle_milliseconds进行比较
  • 用户仅在更改时收到通知,检查每隔约500毫秒执行一次
  • 由于Windows可以在4802之后立即触发事件ID 4803,因此可以确定屏幕保护程序仍在用户idle_time上,请参阅problem我有

此外,这仅在屏幕保护定时器小于屏幕电源关闭计时器时才有效!

#define start

#include <windows.h>
#include <iostream>

// do something after 10 minutes of user inactivity
static const unsigned int idle_milliseconds = 60*10*1000;

int main() {
    LASTINPUTINFO last_input;
    // without setting cbSize GetLastError() returns the parameter is incorrect
    last_input.cbSize = sizeof(last_input);  
    BOOL screensaver_running;

    DWORD idle_time;
    bool screensaverOn = false;

    // main loop to check if user has been idle long enough
    for (;;) {
        if ( !GetLastInputInfo( &last_input )
          || !SystemParametersInfo( SPI_GETSCREENSAVERRUNNING, 0,  
                               &screensaver_running, 0 ) )
        {
            std::cerr << "WinAPI failed!" << std::endl;
            return ERROR_FAILURE;
        }

        // calculate idle time
        idle_time = GetTickCount() - last_input.dwTime;

        if ( idle_time > this->user_idle_time && TRUE == screensaver_running )
        {
            if ( !screensaverOn )
            {
                // screensaver is running
                screensaverOn = true;
                notify( true );
            }
        }
        else if ( idle_time < this->user_idle_time && screensaverOn )
        {
            // screensaver is not running
            screensaverOn = false;
            notify( false );
        }
        // wait 500ms before next loop
        Sleep( 500 );
    }
}

0
投票

检查看起来相似的answer

但是,您需要确定“不活动”的含义。这会修改您问题的范围。

另请检查此代码

hdesk = OpenDesktop(TEXT("Screen-saver"),
                    0,
                    FALSE,
                    DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS);
if (hdesk)
{
   EnumDesktopWindows (hdesk, (WNDENUMPROC)KillScreenSaverFunc, 0);
   CloseDesktop (hdesk);
}

// ----------------------------------------------------------------

BOOL CALLBACK KillScreenSaverFunc (HWND hwnd, LPARAM lParam)
{
   PostMessage(hwnd, WM_CLOSE, 0, 0);
   return TRUE;
}

来自here

© www.soinside.com 2019 - 2024. All rights reserved.