我想禁用屏幕保护程序并关闭电源。在这个阶段,没有窗户形式,我可以。因此,我不想使用NativeWindow。
这是我的代码
sealed class ObserverWindow : NativeWindow, IDisposable
{
internal ObserverWindow()
{
this.CreateHandle(new CreateParams()
{
Parent= IntPtr.Zero
});
}
public void Dispose()
{
DestroyHandle();
}
protected override void WndProc(ref Message msg)
{
if (msg.Msg == WM_SYSCOMMAND &&
((((long)msg.WParam & 0xFFF0) == SC_SCREENSAVE) ||
((long)msg.WParam & 0xFFF0) == SC_MONITORPOWER))
{
msg.Msg = 0;
msg.HWnd = IntPtr.Zero;
}
base.WndProc(ref msg);
}
}
问题是,没有使用WM_SYSCOMMAND调用WndProc。实际上,WndProc被称为4次。在最后一次调用时,有msg.Msg == WM_CREATE。
我想我缺少一些创建参数。有人有建议吗?
问候迈克尔
更新
我在非STA线程中运行代码。因此,窗口没有显示任何消息,而不是初始消息。现在我收到了WM_SYSCOMMAND消息。但是当屏幕保护程序激活时,没有消息。
我还尝试用相同的结果覆盖Form的WndProc。但这曾经在Windows XP中运行。 Windows 7中是否有变化?
操作系统:Windows 7 64位。
解
作为此Question个州的评论,只有前景窗口可以取消屏幕保护程序。因此上面的代码无法工作。 NativeWindow非常适合接收消息,但不适用于取消屏幕保护程序。对于后者,我建议回答这个问题。
答案 0 :(得分:6)
执行此操作的正确方法是告诉Windows您的线程需要激活显示。常用于视频播放器。 P /调用SetThreadExecutionState()API函数,传递ES_DISPLAY_REQUIRED。并且ES_SYSTEM_REQUIRED可防止机器自动关闭。访问pinvoke.net获取所需的声明。
答案 1 :(得分:0)
这可以通过以下方式轻松完成:
SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, FALSE, 0, SPIF_SENDWININICHANGE );
[...]
如果您需要再次启动屏幕保护程序,则需要重新初始化超时期限。通过[c] alling
SystemParametersInfo (SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_SENDWININICHANGE)
执行此操作。
答案 2 :(得分:0)
您可以尝试覆盖DefWndProc
。
public override void DefWndProc(ref Message msg)
{
if (msg.Msg == WM_SYSCOMMAND &&
((((long)msg.WParam & 0xFFF0) == SC_SCREENSAVE) ||
((long)msg.WParam & 0xFFF0) == SC_MONITORPOWER))
{
msg.Msg = 0;
msg.HWnd = IntPtr.Zero;
}
base.DefWndProc(ref msg);
}
我现在不在Windows机器上,所以我无法测试。如果有效,请告诉我。