I maintained a system which used the WPF Framework to wrote, which appeared a so weird scene, when screen-saver is running and a window used the ShowDialog to popup a window by timer object, this was popup window will not be appeared the any text, button and another control, its whole view is blank. but the popup window will be works if screen-saver doesn't run.
I means that the popup window will have view issue when screen-saver is running. The popup will be works normally if screen-saver doesn't run.
This issue which can't reproduce in my development environment locally. it is run for a specific PC(windows 8.1 embedded version)
I figured out a pathway directly to resolve, which is to interrupt screen-saver before ShowDialog window. These are ways included as below,
- a. Move mouse(used the user32's mouse_event api)
- b. Send keys(also used the user32's api)
- c. Kill screen-saver process.
- d. upgraded to Framework to 4.6.2
Above ways refer to above links, All of these ways can be work well in my locally(Windows 10) , but didn't work on that specific PC(windows 8.1 embedded version) indeed. https://www.codeproject.com/Articles/17067/Controlling-The-Screen-Saver-With-C
How to interrupt Screen-saver under windows 8
I have given up this interrupt screen-saver way, I hope look at another key point to resolve this issue, but I didn't know should to focus on which part of code. Have any suggestion for me? thanks in advance. I according to logic of this part of original project to wrote a demo as below,
Main window code
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();
}
}
}
There was pop-up window code as below
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();
}
}
}
Actually, it's very simple code for below, please give me some suggestions. thanks in advance.