Winapi 以编程方式阻止Windows屏幕保护程序启动
有没有推荐的方法来阻止Windows屏幕保护程序启动?我发现的最接近的是,但是我真正想做的就是告诉Windows计算机不是空闲的,而不是欺骗当前设置的屏幕保护程序值。Winapi 以编程方式阻止Windows屏幕保护程序启动,winapi,windows-vista,windows-xp,screensaver,Winapi,Windows Vista,Windows Xp,Screensaver,有没有推荐的方法来阻止Windows屏幕保护程序启动?我发现的最接近的是,但是我真正想做的就是告诉Windows计算机不是空闲的,而不是欺骗当前设置的屏幕保护程序值。 详细说明了C++中需要做的事情。 网站中的实际代码片段: LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_SYSCOMMA
详细说明了C++中需要做的事情。 网站中的实际代码片段:
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_SYSCOMMAND:
{
switch (wParam)
{
case SC_SCREENSAVE:
return 0;
case SC_MONITORPOWER:
return 0;
}
break;
}
case WM_CLOSE:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}微妙。告诉Windows系统未空闲的官方方法是SetThreadExecutionState。这将重置空闲计时器(或关闭它,如果您通过
ES_CONTINUOUS
)。但是,即使SetThreadExecutionState重置空闲计时器,它也不会停止屏幕保护程序 我用来重置空闲状态。这就绕过了一个群体策略,该策略倾向于在不合适的时候启动我的屏幕保护程序(并锁定机器):当我阅读一个长文档、研究一段复杂的代码时,或者在会议期间说话/听/不经常打字时
由于让鼠标每秒沿对角线跳1px可能会有点烦人,我打算用它来编写一个基本上做相同事情的脚本,但只在配置键盘/鼠标空闲超时后,并且可能使用Shift键(或滚动锁)而不是鼠标移动。
具体而言,SPI_SETSCREENSAVEACTIVE
参数
这不管用吗?我很惊讶我没有在这里看到它。请注意,SetThreadExecutionState根本不会影响屏幕保护程序,只会影响显示器的睡眠。为了进行测试,我将屏幕保护程序设置为1分钟,并需要密码 我尝试在VB.Net中捕获SC_屏幕保存并返回-1。如前所述,它在没有屏幕保护程序密码时工作,但如果屏幕保护程序密码处于活动状态,将失败。(我在Windows XP中试用过)。我还将其放入计时器的滴答事件中,每1000毫秒一次:
Static dir As Integer = 4
Cursor.Position = Cursor.Position + New Size(dir, dir)
dir = -dir
它不起作用。光标来回摆动,1分钟后屏幕保护程序会在短时间内闪烁,然后关闭。屏幕保护程序只打开一小会儿,时间不够长,不需要密码。但是,闪光仍然是丑陋的
然后我尝试使用user32.dll的SetCursorPos和GetCursorPos。你可以在平沃克查一下。结果同上
然后我偷看了一下这个问题中其他地方提到的“JiggleMouse”代码。JiggleMouse使用SendInputSendInput有效屏幕保护程序不闪烁。我把SendInput的调用放在一个计时器内,计时器每50秒触发一次(刚好小于屏幕保护程序的最小超时60秒)。将鼠标移动0,0的增量就足够了,没有实际的移动。这确实有效。要放入勾号事件的代码:
Dim i(0) As INPUT
i(0).dwType = INPUT.InputType.INPUT_MOUSE
i(0).mkhi = New MOUSEKEYBDHARDWAREINPUT
i(0).mkhi.mi = New MOUSEINPUT
i(0).mkhi.mi.dx = 0
i(0).mkhi.mi.dy = 0
i(0).mkhi.mi.mouseData = 0
i(0).mkhi.mi.dwFlags = MOUSEINPUT.MouseEventFlags.MOUSEEVENTF_MOVE
i(0).mkhi.mi.time = 0
i(0).mkhi.mi.dwExtraInfo = IntPtr.Zero
SendInput(1, i(0), Marshal.SizeOf(i(0)))
这来自pinvoke.com:
Public Declare Function SendInput Lib "user32" (ByVal nInputs As Integer, ByRef pInputs As INPUT, ByVal cbSize As Integer) As Integer
Public Structure INPUT
Enum InputType As Integer
INPUT_MOUSE = 0
INPUT_KEYBOARD = 1
INPUT_HARDWARE = 2
End Enum
Dim dwType As InputType
Dim mkhi As MOUSEKEYBDHARDWAREINPUT
End Structure
Public Structure MOUSEINPUT
Enum MouseEventFlags As Integer
MOUSEEVENTF_MOVE = &H1
MOUSEEVENTF_LEFTDOWN = &H2
MOUSEEVENTF_LEFTUP = &H4
MOUSEEVENTF_RIGHTDOWN = &H8
MOUSEEVENTF_RIGHTUP = &H10
MOUSEEVENTF_MIDDLEDOWN = &H20
MOUSEEVENTF_MIDDLEUP = &H40
MOUSEEVENTF_XDOWN = &H80
MOUSEEVENTF_XUP = &H100
MOUSEEVENTF_WHEEL = &H800
MOUSEEVENTF_VIRTUALDESK = &H4000
MOUSEEVENTF_ABSOLUTE = &H8000
End Enum
Dim dx As Integer
Dim dy As Integer
Dim mouseData As Integer
Dim dwFlags As MouseEventFlags
Dim time As Integer
Dim dwExtraInfo As IntPtr
End Structure
Public Structure KEYBDINPUT
Public wVk As Short
Public wScan As Short
Public dwFlags As Integer
Public time As Integer
Public dwExtraInfo As IntPtr
End Structure
Public Structure HARDWAREINPUT
Public uMsg As Integer
Public wParamL As Short
Public wParamH As Short
End Structure
Const KEYEVENTF_EXTENDEDKEY As UInt32 = &H1
Const KEYEVENTF_KEYUP As UInt32 = &H2
Const KEYEVENTF_UNICODE As UInt32 = &H4
Const KEYEVENTF_SCANCODE As UInt32 = &H8
Const XBUTTON1 As UInt32 = &H1
Const XBUTTON2 As UInt32 = &H2
<StructLayout(LayoutKind.Explicit)> Public Structure MOUSEKEYBDHARDWAREINPUT
<FieldOffset(0)> Public mi As MOUSEINPUT
<FieldOffset(0)> Public ki As KEYBDINPUT
<FieldOffset(0)> Public hi As HARDWAREINPUT
End Structure
将函数SendInput Lib“user32”(ByVal nInputs作为整数,ByRef pInputs作为输入,ByVal cbSize作为整数)公开声明为整数
公共结构投入
将InputType枚举为整数
输入\鼠标=0
键盘输入=1
输入硬件=2
结束枚举
Dim dwType作为InputType
将mkhi调暗为MOUSEKEYBDHARDWAREINPUT
端部结构
公共结构鼠标输入
将MouseEventFlags枚举为整数
MOUSEEVENTF_MOVE=&H1
MOUSEEVENTF_LEFTDOWN=&H2
MOUSEEVENTF_LEFTUP=&H4
MOUSEEVENTF_RIGHTDOWN=&H8
MOUSEEVENTF_RIGHTUP=&H10
MOUSEEVENTF_MIDDLEDOWN=&H20
MOUSEEVENTF_MIDDLEUP=&H40
MOUSEEVENTF_XDOWN=&H80
MOUSEEVENTF_XUP=&H100
MOUSEEVENTF_滚轮=&H800
MOUSEEVENTF_VIRTUALDESK=&H4000
MOUSEEVENTF_绝对值=&H8000
结束枚举
作为整数的Dim dx
作为整数的Dim-dy
将mouseData设置为整数
将dwFlags变暗为MouseeEventFlags
将时间变暗为整数
将dwExtraInfo设置为IntPtr
端部结构
公共结构键输入
公共wVk为短
公共无线传感器网络
作为整数的公共标志
作为整数的公共时间
公共dwExtraInfo作为IntPtr
端部结构
公共结构硬件输入
作为整数的公共uMsg
公共wParamL简称
公共wParamH简称
端部结构
Const KEYEVENTF_扩展键为UInt32=&H1
常量KEYEVENTF\u KEYUP为UInt32=&H2
Const KEYEVENTF_UNICODE作为UInt32=&H4
Const KEYEVENTF_扫描代码为UInt32=&H8
常量XBUTTON1为UInt32=&H1
常数XBUTTON2为UInt32=&H2
公共结构MOUSEKEYBDHARDWAREINPUT
作为鼠标输入的公共mi
公共ki作为KEYBDINPUT
公共hi作为硬件输入
端部结构
真不敢相信没有人指出简单而明显的解决方案:
#include <windows.h>
void main()
{
while(1){
INPUT input;
input.type = INPUT_MOUSE;
input.mi.dx = 1;
input.mi.dy = 1;
input.mi.mouseData = 0;
input.mi.dwFlags = MOUSEEVENTF_MOVE;
input.mi.time = 0;
input.mi.dwExtraInfo = 0;
SendInput( 1, &input, sizeof(input) );
sleep(60000);
}
}
#包括
void main()
{
而(1){
输入;
input.type=输入\鼠标;
input.mi.dx=1;
input.mi.dy=1;
input.mi.mouseData=0;
input.mi.dwFlags=MOUSEEVENTF_MOVE;
input.mi.time=0;
input.mi.dwExtraInfo=0;
SendInput(1,&input,sizeof(input));
睡眠(60000);
}
}
来自:
如果存在以下任何情况,Windows不会启动屏幕保护程序:
- 活动应用程序不是基于Windows的应用程序
- 存在CBT窗口
- 活动应用程序接收wParam参数设置为SC_SCREENSAVE值的WM_SYSCOMMAND消息,但不会将消息传递给DefWindowProc函数
"FlipSS.exe -h" to see the current state.
"FlipSS.exe /on" to set the screensaver on.
"FlipSS.exe /off" to set the screensaver off.
DllCall("SystemParametersInfo", Int, 17, Int, 0, UInt, NULL, Int, 2)
DllCall("SystemParametersInfo", Int, 17, Int, 1, UInt, NULL, Int, 2)
//To stop/start screen saver and monitor power off event
void SetKeepScreenOn(BOOL isKeepScreenOn)
{
if (isKeepScreenOn == TRUE)
{
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED /*| ES_AWAYMODE_REQUIRED*/);
}
else
{
SetThreadExecutionState(ES_CONTINUOUS);
}
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto,SetLastError = true)]
static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
[FlagsAttribute]
public enum EXECUTION_STATE :uint
{
ES_AWAYMODE_REQUIRED = 0x00000040,
ES_CONTINUOUS = 0x80000000,
ES_DISPLAY_REQUIRED = 0x00000002,
ES_SYSTEM_REQUIRED = 0x00000001
}
void SetKeepScreenOn(bool isKeepScreenOn)
{
if (isKeepScreenOn == true)
{
//You can combine several flags and specify multiple behaviors with a single call
SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS | EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_DISPLAY_REQUIRED /*| EXECUTION_STATE.ES_AWAYMODE_REQUIRED*/);
}
else
{
//To reset or allow those event again you have to call this API with only ES_CONTINUOUS
SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS);
}
}