【发布时间】:2017-06-19 07:16:18
【问题描述】:
我维护了一个使用WPF框架编写的系统,出现了一个很奇怪的场景,当屏幕保护程序运行时,一个窗口使用ShowDialog通过定时器对象弹出一个窗口,这个弹出窗口不会出现任何文本、按钮和另一个控件,它的整个视图都是空白的。但如果屏幕保护程序不运行,弹出窗口将起作用。
我的意思是当屏幕保护程序运行时弹出窗口会有视图问题。如果屏幕保护程序没有运行,弹出窗口将正常工作。
这个问题在我的本地开发环境中无法重现。它针对特定的 PC(Windows 8.1 嵌入式版本)运行
我想出了一个直接解决的途径,就是在ShowDialog窗口之前中断屏保。这些方法包括如下,
- 一个。移动鼠标(使用 user32 的 mouse_event api)
- 乙。发送密钥(也使用了user32的api)
- c。终止屏幕保护程序。
- d.升级到 Framework 到 4.6.2
以上方式参考以上链接,所有这些方式都可以在我的本地(Windows 10)上运行良好,但确实不适用于该特定PC(Windows 8.1嵌入式版本)。 https://www.codeproject.com/Articles/17067/Controlling-The-Screen-Saver-With-C
How to interrupt Screen-saver under windows 8
我已经放弃了这种中断屏保的方式,希望再看一个关键点来解决这个问题,但是不知道应该把重点放在代码的哪一部分。对我有什么建议吗?提前致谢。我按照原项目这部分的逻辑写了一个demo如下,
主窗口代码
using OutdoorCentral.WPF.UI;
using System;
using System.Configuration;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Input;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private static object inactivityLockObject = "InactivityLockObject";
protected delegate void func();
private static Timer checkActivityTimer;
public MessageDialog msg = new MessageDialog();
public enum MessageWindowType
{
OK,
OKCancel,
YesNo,
YesNoCancel
}
public MainWindow()
{
InitializeComponent();
this.Title = "test";
AutoResetEvent autoResetEvent = new AutoResetEvent(false);
checkActivityTimer = new Timer(CheckActivityCallback, autoResetEvent, new TimeSpan(0, 2, 0), new TimeSpan(0, 2, 0));
}
private void CheckActivityCallback(object stateInfo)
{
CheckActivity();
}
private void CheckActivity()
{
lock (inactivityLockObject)
{
InvokeOnUiThread(ForceLogout);
}
}
protected void InvokeOnUiThread(func method)
{
Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, method);
}
private void ForceLogout()
{
checkActivityTimer.Dispose();
msg.TitleLabel.Content = Title;
msg.Topmost = true;
msg.Message = "test focus on message missed";
msg.MessageWindowType = MessageWindowType.OK;
msg.ShowDialog();
}
}
}
弹窗代码如下
using System.Diagnostics;
using Microsoft.Win32;
using System.Windows;
using System;
using System.Threading;
using System.Runtime.InteropServices;
using WpfApplication1;
using static WpfApplication1.MainWindow;
namespace OutdoorCentral.WPF.UI
{
/// <summary>
/// Interaction logic for MessageDialog.xaml
/// </summary>
public partial class MessageDialog : Window
{
public MessageDialog()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MessageDialog_Loaded);
}
public bool? MessageResult { get; set; }
void MessageDialog_Loaded(object sender, RoutedEventArgs e)
{
SetWindowType();
}
new string Title
{
get { return TitleLabel.Content.ToString(); }
set { TitleLabel.Content = value; }
}
public string Message
{
get { return MessageText.Text; }
set { MessageText.Text = value; }
}
private MessageWindowType messageWindowType;
public MessageWindowType MessageWindowType
{
get { return messageWindowType; }
set
{
messageWindowType = value;
SetWindowType();
}
}
private void SetWindowType()
{
switch (MessageWindowType)
{
case MessageWindowType.OKCancel:
CancelButton.Visibility = Visibility.Visible;
break;
case MessageWindowType.YesNo:
OKButton.Content = "Yes";
NoButton.Visibility = Visibility.Visible;
break;
case MessageWindowType.YesNoCancel:
OKButton.Content = "Yes";
CancelButton.Visibility = Visibility.Visible;
NoButton.Visibility = Visibility.Visible;
break;
}
}
private void Done(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
MessageResult = true;
}
private void NoSelection(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
MessageResult = false;
}
public void Canceled(object sender, RoutedEventArgs e)
{
MessageResult = null;
this.Close();
}
private void Window_LostFocus(object sender, RoutedEventArgs e)
{
this.Focus();
}
}
}
实际上,下面的代码很简单,请给我一些建议。提前致谢。
【问题讨论】:
-
你用过谷歌翻译吗?我发现您的问题几乎无法阅读。
-
谢谢你的回复,我又修改了描述,你能再看看吗?
-
看到这个,可能是相关的:codeproject.com/Answers/187206/…
-
我看过这个链接,它主要关注 PowerModeChanged 事件,但不适用于我的问题