我想禁用屏幕保护程序并关闭电源.在这个阶段,没有窗户形式,我可以.因此,我不想使用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);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,没有使用WM_SYSCOMMAND调用WndProc.实际上,WndProc被称为4次.在最后一次调用时,有msg.Msg == WM_CREATE.
我想我错过了一些创建参数.有人有建议吗?
关心迈克尔
UPDATE
我在非STA线程中运行代码.因此,窗口没有显示任何消息,而不是初始消息.现在我收到了WM_SYSCOMMAND消息.但是当屏幕保护程序激活时,没有消息.
我也尝试用相同的结果覆盖Form的WndProc.但这曾经在Windows XP中运行.Windows 7有变化吗?
操作系统:Windows 7 64位.
解
正如本问题中的评论所述,只有前景窗口可以取消屏幕保护程序.因此上面的代码无法工作.NativeWindow非常适合接收消息,但不适用于取消屏幕保护程序.对于后者,我推荐这个问题的答案.
执行此操作的正确方法是告诉Windows您的线程需要激活显示.常用于视频播放器.P /调用SetThreadExecutionState()API函数,传递ES_DISPLAY_REQUIRED.并且ES_SYSTEM_REQUIRED可防止机器自动关闭.访问pinvoke.net获取所需的声明.