首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >以编程方式禁用ScreenSaver

以编程方式禁用ScreenSaver
EN

Stack Overflow用户
提问于 2021-02-14 12:55:06
回答 1查看 360关注 0票数 1

我有一个ACEPC T6,一个7英寸液晶显示屏连接通过HDMI,和一个USB触摸屏。

该系统通过USB串口连接到处理器板上,读取各种传感器,并将数据反馈给PC机。

PC上的程序是用VB.NET 2019年编写的。除了一个例外,一切都很好。

我使用ScreenSaver在10分钟的活动后空白屏幕,触摸屏幕可以让事情恢复正常。

我的问题是,我有一个PIR传感器连接到处理器,它发送一个命令回PC。我的目标是模拟被触摸的屏幕,并恢复显示,即当有人走进房间时,显示器就会返回。

我尝试过各种各样的选项,模拟鼠标效果,发送按键笔触,但都没有效果。

任何帮助都将不胜感激。

我应该说我正在运行Windows 10 Pro。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-15 17:20:02

您可能无法使用SendInput()或其他函数获得积极的结果,因为ScreenSaver在特殊桌面上运行,名为(猜猜什么) Screen-saver

您需要获得此桌面的句柄,以便与其或其Windows进行积极的交互。

您可以使用SPI_GETSCREENSAVERRUNNING函数,传递SystemParametersInfo来确定ScreenSaver当前是否处于活动状态,然后调用OpenDesktop()获取桌面的句柄(使用名称),查找ScreenSaver窗口( ScreenSaver是标准的可执行文件),并发送WM_CLOSE消息来关闭它。

在这里,我使用EnumDesktopWindows查找ScreenSaver。

(无论如何,ScreenSaver窗口应该是前台窗口)。

如果失败,我们可以尝试关闭桌面,调用CloseDesktop()

这里有一些可能与ScreenSaver相关的更有趣的信息:

操作屏幕保护程序

如果有一个通过串口或类似程序接收命令的过程,请验证此过程是否在UI线程以外的线程中运行,以防在此情况下需要访问UI。

将此代码添加到过程中:它检查ScreenSaver是否处于活动状态,并试图关闭它。

它已经在Windows10 (19H2)和Windows7 SP1中进行了测试。

.Net框架4.8 - VB.Net v.15

注意到:您的应用程序是作为64位进程运行的。如果在项目的构建选项中设置了Prefer 32-bit,则需要取消选择它。

►假设此过程在UI线程中运行。Me.Activate()并不是严格要求的,只能从UI胎面使用。如果您的代码运行在不同的线程上,请删除它。

代码语言:javascript
复制
Protected Sub SomeProcedure()
    If NativeMethods.GetScreenSaverActiveState() Then
        NativeMethods.TerminateScreenSaver()
        Me.Activate()
    End If
End Sub

NativeMethods类和助手方法:

代码语言:javascript
复制
Imports System.Runtime.InteropServices
Imports System.Security.Permissions

Friend Class NativeMethods
    Public Shared Sub TerminateScreenSaver()
        Try
            TerminateScreenSaverCore()
        Catch wex As Win32Exception
            MessageBox.Show(wex.Message)
        End Try
    End Sub

    Public Shared Function GetScreenSaverActiveState() As Boolean
        Dim scState As IntPtr = IntPtr.Zero
        SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0UI, scState, 0UI)
        Return scState <> IntPtr.Zero
    End Function

    <UIPermission(SecurityAction.Demand, Action:=SecurityAction.Demand, Window:=UIPermissionWindow.AllWindows)>
    Private Shared Sub TerminateScreenSaverCore()
        Call New SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand()

        Dim hDesktop As IntPtr = OpenDesktop("Screen-saver", 0, False,
            DesktopAccessRights.DESKTOP_READOBJECTS Or DesktopAccessRights.DESKTOP_WRITEOBJECTS)

        If hDesktop <> IntPtr.Zero Then
            If Not EnumDesktopWindows(hDesktop,
            Function(hWnd, lp)
                If IsWindowVisible(hWnd) Then CloseWindow(hWnd)
                Return True
            End Function, IntPtr.Zero) Then
                If Not CloseDesktop(hDesktop) Then
                    CloseWindow(GetForegroundWindow())
                End If
            End If
        End If
    End Sub

    Private Shared Sub CloseWindow(hWnd As IntPtr)
        PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero)
    End Sub

    Private Const WM_CLOSE As Integer = &H10
    Private Const SPI_GETSCREENSAVERRUNNING As UInteger = &H72

    Public Enum DesktopAccessRights As Long
        DESKTOP_CREATEMENU = &H4L
        DESKTOP_CREATEWINDOW = &H2L
        DESKTOP_ENUMERATE = &H40L
        DESKTOP_HOOKCONTROL = &H8L
        DESKTOP_JOURNALPLAYBACK = &H20L
        DESKTOP_JOURNALRECORD = &H10L
        DESKTOP_READOBJECTS = &H1L
        DESKTOP_SWITCHDESKTOP = &H100L
        DESKTOP_WRITEOBJECTS = &H80L
    End Enum

    Private Delegate Function EnumWindowsProc(hDesktop As IntPtr, lParam As IntPtr) As Boolean

    <DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
    Private Shared Function OpenDesktop(
        lpszDesktop As String,
        dwFlags As UInteger,
        <[In], MarshalAs(UnmanagedType.Bool)> fInherit As Boolean,
        dwDesiredAccess As DesktopAccessRights) As IntPtr
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
    Private Shared Function CloseDesktop(hDesktop As IntPtr) As Boolean
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
    Private Shared Function EnumDesktopWindows(
        hDesktop As IntPtr,
        callback As EnumWindowsProc,
        lParam As IntPtr) As Boolean
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
    Public Shared Function GetForegroundWindow() As IntPtr
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
    Private Shared Function IsWindowVisible(hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
    Private Shared Function PostMessage(hWnd As IntPtr, msg As UInteger, wParam As IntPtr, lParam As IntPtr) As Boolean
    End Function

    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
    Private Shared Function SystemParametersInfo(uiAction As UInteger, uiParam As UInteger, ByRef pvParam As IntPtr, fWinIni As UInteger) As Boolean
    End Function
End Class

C#版本,以防万一:

代码语言:javascript
复制
using System.Runtime.InteropServices;
using System.Security.Permissions;

internal static class NativeMethods
{
    public static void TerminateScreenSaver()
    {
        try {
            TerminateScreenSaverCore();
        }
        catch(Win32Exception wex){
            MessageBox.Show(wex.Message);
        }
    }

    public static bool GetScreenSaverActiveState()
    {
        var scState = IntPtr.Zero;
        SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0U, ref scState, 0U);
        return scState != IntPtr.Zero;
    }

    [UIPermission(SecurityAction.Demand, Action = SecurityAction.Demand, Window = UIPermissionWindow.AllWindows)]
    private static void TerminateScreenSaverCore()
    {
        new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();

        IntPtr hDesktop = OpenDesktop("Screen-saver", 0, false, 
            DesktopAccessRights.DESKTOP_READOBJECTS | DesktopAccessRights.DESKTOP_WRITEOBJECTS);
        if (hDesktop != IntPtr.Zero) {
            if (!EnumDesktopWindows(hDesktop, (hWnd, lp)=> {
                if (IsWindowVisible(hWnd)) CloseWindow(hWnd);
                return true;
            }, IntPtr.Zero) || !CloseDesktop(hDesktop)) {
                CloseWindow(GetForegroundWindow());
            }
        }
    }

    private static void CloseWindow(IntPtr hWnd)
    {
        PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
    }

    private const uint SPI_GETSCREENSAVERRUNNING = 0x0072;
    private const int WM_CLOSE = 0x0010;

    public enum DesktopAccessRights : long
    {
        DESKTOP_CREATEMENU = 0x0004L,        // Required to create a menu on the desktop.
        DESKTOP_CREATEWINDOW = 0x0002L,      // Required to create a window on the desktop.
        DESKTOP_ENUMERATE = 0x0040L,         // Required for the desktop to be enumerated.
        DESKTOP_HOOKCONTROL = 0x0008L,       // Required to establish any of the window hooks.
        DESKTOP_JOURNALPLAYBACK = 0x0020L,   // Required to perform journal playback on a desktop.
        DESKTOP_JOURNALRECORD = 0x0010L,     // Required to perform journal recording on a desktop.
        DESKTOP_READOBJECTS = 0x0001L,       // Required to read objects on the desktop.
        DESKTOP_SWITCHDESKTOP = 0x0100L,     // Required to activate the desktop using the SwitchDesktop function.
        DESKTOP_WRITEOBJECTS = 0x0080L       // Required to write objects on the desktop.
    }

    private delegate bool EnumWindowsProc(IntPtr hDesktop, IntPtr lParam);

    [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern IntPtr OpenDesktop(
        string lpszDesktop, 
        uint dwFlags, 
        [In, MarshalAs(UnmanagedType.Bool)]bool fInherit, 
        DesktopAccessRights dwDesiredAccess);

    [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool CloseDesktop(IntPtr hDesktop);

    [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumWindowsProc callback, IntPtr lParam);

    [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool IsWindowVisible(IntPtr hWnd);

    [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]

    [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref IntPtr pvParam, uint fWinIni);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66195624

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档