2017-05-04 39 views
0

我刚刚开始学习C#并试图编写屏幕保护程序。我App.xaml.cs包含在使用/ P参数为下面的代码:在C#中使用WPF在预览模式下崩溃的Windows屏幕保护程序

else if (arg1 == "/p") 
      { 
       if (e.Args[1] == null) 
       { 
        System.Windows.Forms.MessageBox.Show("Invalid or missing window handle."); 
        System.Windows.Application.Current.Shutdown(); 
       } 
       IntPtr previewHandle = new IntPtr(long.Parse(e.Args[1])); 
       System.Windows.Application.Current.Run(new MainWindow(previewHandle)); 
      } 
我MainWindow.xaml.cs

然后,这个构造处理预览呼叫:

public MainWindow(IntPtr previewHandle) 
    { 
     App.Current.Properties["isPreviewMode"] = true; 
     App.Current.Properties["previewHandle"] = previewHandle; 
     InitializeComponent(); 
    } 

后这,它崩溃。在我的MainWindow.xaml中,我有Loaded =“MainWindow_Loaded”。

在MainWindows.xaml.cs这MainWindow_Loaded:

private void MainWindow_Loaded(object sender, RoutedEventArgs e) 
{ 
     if ((bool)App.Current.Properties["isPreviewMode"]) 
     { 
      IntPtr myHandle = new WindowInteropHelper(this).Handle; 
      SetParent(myHandle, (IntPtr)App.Current.Properties["previewHandle"]); 
      SetWindowLong(myHandle, -16, new IntPtr(GetWindowLong(myHandle, -16) | 0x40000000)); 
      Rectangle ParentRect; 
      GetClientRect((IntPtr)App.Current.Properties["previewHandle"], out ParentRect); 
      this.Top = ParentRect.X; 
      this.Left = ParentRect.Y; 
      this.Height = ParentRect.Height; 
      this.Width = ParentRect.Width; 
     } 
     ssimage.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/EmbeddedImage.PNG")); 
} 
[DllImport("user32.dll")] 
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); 

[DllImport("user32.dll")] 
static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong); 

[DllImport("user32.dll", SetLastError = true)] 
static extern int GetWindowLong(IntPtr hWnd, int nIndex); 

[DllImport("user32.dll")] 
static extern bool GetClientRect(IntPtr hWnd, out Rectangle lpRect); 

我在App.xaml.cs其它代码来处理改变在计时器和其他代码图像中MainWindow.xaml.cs到处理鼠标移动,点击和按键。正常运行屏幕保护程序时一切正常。这只是预览失败。我究竟做错了什么?

+0

你能用像GIF动画一样预览吗? –

+0

我可能可以,但它显示的图像是动态的。它从计算机上的文件夹中读取它们,因此如果我有GIF,那么屏幕保护程序运行时将不会显示实际使用的图像。 –

回答

0

我最终做的是使用WPF窗口来显示何时屏幕保护程序在/ s全屏幕下正常运行。我用一个picturebox创建了一个新的常规窗体previewForm.cs用于预览。这工作正常,没有性能问题。我假设picturebox正在使用GDI。

这是我修改App.xaml.cs用于处理/ P参数:

else if (arg1 == "/p") 
      { 
       if (e.Args[1] == null) 
       { 
        System.Windows.Forms.MessageBox.Show("Invalid or missing window handle."); 
        System.Windows.Application.Current.Shutdown(); 
       } 
       IntPtr previewHandle = new IntPtr(long.Parse(e.Args[1])); 
       pw = new previewForm(previewHandle); 
       GetImages(); 
       pw.Show(); 
      } 

和我previewForm.cs构造处理预览:

public previewForm(IntPtr previewHandle) 
    { 
     InitializeComponent(); 
     IntPtr myHandle = this.Handle; 
     SetParent(myHandle, previewHandle); 
     SetWindowLong(myHandle, -16, new IntPtr(GetWindowLong(myHandle, -16) | 0x40000000)); 
     Rectangle ParentRect; 
     GetClientRect(previewHandle, out ParentRect); 
     this.Size = ParentRect.Size; 
     this.pictureBox1.Size = ParentRect.Size; 
     this.Location = new Point(0, 0); 
    } 

所以我用的混合一个WPF窗体和一个常规窗体来完成这个任务。性能很好。只使用像14-18MB的RAM和几乎没有CPU。

0

据我所知,WPF不允许你重定位窗口句柄,所以使用你的技术在WPF中执行屏保预览是不可能的。但是,有一种解决方法:如果将WPF配置为渲染到位图目标(请参阅RenderTargetBitmap),则可以将该位图粘贴到所需的目标窗口句柄上 - 但这会涉及到GDI和WPF的混淆组合并可能具有糟糕的运行时性能;我怀疑这是值得的努力。

相关问题