2017-05-04 41 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的混淆組合並可能具有糟糕的運行時性能;我懷疑這是值得的努力。

相關問題