2017-05-04 4 views
0

私はC#を学び始めたばかりで、スクリーンセーバーを作成しようとしています。私App.xaml.csは、/ p個の引数を使用する場合のために、次のコードが含まれています。WindowsのスクリーンセーバーをC#で使用すると、プレビューモードでWPFがクラッシュする

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); 

私はにMainWindow.xaml.csにタイマーや他のコード上の画像を変更する処理するApp.xaml.cs内の他のコードを持っていますマウスの動き、クリック、キー入力を処理します。スクリーンセーバーを正常に実行するとすべて正常に動作します。それは失敗するプレビューです。私は間違って何をしていますか?

+0

アニメーションGIFのようなものでプレビューできますか? –

+0

私はおそらく可能ですが、それが表示する画像は動的です。それはコンピュータ上のフォルダからそれらを読み取るので、GIFがあれば、スクリーンセーバーが実行されるときに使用される実際のイメージは表示されません。 –

答えて

0

私がやったことは、スクリーンセーバーが/ sでフルスクリーンで正常に動作するときに、WPFウィンドウを使って表示することでした。プレビューに使用するピクチャボックスを持つpreviewForm.csという新しいレギュラーウィンドウフォームを作成しました。それは正常に動作し、パフォーマンスの問題はありません。私は、ピクチャボックスがGDIを使用していると仮定します。

これは、/ p個の引数を処理するために、私の修正App.xaml.csです:

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フォームと通常のWindowsフォームを使用します。そしてパフォーマンスは良いです。 14-18MBのRAMと実際にはCPUは使用しないでください。

0

私の知る限り、WPFではウィンドウハンドルのターゲットを変更することはできないため、WPFでのテクニックを使ったスクリーンセーバープレビューの実行は不可能です。

ビットマップターゲット(RenderTargetBitmapを参照)にレンダリングするようにWPFを設定すると、そのビットマップを目的のウィンドウハンドルに合わせることができますが、これはGDIとWPFの混乱を招きます恐らくひどいランタイムパフォーマンスを持つでしょう。私はそれが努力の価値があるとは思わない。

関連する問題