我刚刚开始学习C#并且正在尝试编写屏幕保护程序。我的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]));
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 :(得分:0)
据我所知,WPF不允许您重新定位窗口句柄,因此使用您的技术在WPF中执行屏幕保护程序预览是不可能的。
但是,有一种解决方法:如果您将WPF配置为渲染到位图目标(请参阅RenderTargetBitmap
),则可以将该位图blit到所需的目标窗口句柄上 - 但这将涉及到unholy混合GDI和WPF可能具有糟糕的运行时性能;我怀疑这是值得的。
答案 1 :(得分:0)
我最终做的是使用WPF窗口显示屏幕保护程序在全屏运行时使用/ s。我创建了一个新的常规Windows窗体previewForm.cs,其中包含一个用于预览的图片框。这很好,并没有性能问题。我认为图片框正在使用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。