如何知道何时在显示属性对话框中select了不同的屏幕保护程序?

好,所以Google今晚不是我的朋友…

我有一个屏幕保护程序, CC.Votd(在Codeplex上的完整源代码) ,并且我刚刚开始实现预览模式(/ p参数),它工作正常。 当它处于预览模式时,我将窗体变成小电脑监视器窗口的一个小孩,并在那里画图。

这工作正常,我的应用程序退出,如果显示属性对话框消失。

问题是,如果我从列表中select我的屏幕保护程序,然后select一个不同的屏幕保护程序我继续运行,并绘制新select的屏幕保护程序的预览。

那么我怎么知道什么时候select了不同的屏幕保护程序,我应该closures?


编辑:对于匿名,这里是我用来使我的窗体预览窗口的孩子的代码:

P /调用:

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

代码:

 SetParent(Handle, _PreviewHandle); SetWindowLong(Handle, -16, new IntPtr(GetWindowLong(Handle, -16) | 0x40000000)); Rectangle parentRectangle; GetClientRect(_PreviewHandle, out parentRectangle); Size = parentRectangle.Size; Location = new Point(0, 0); 

完整的表单代码: http : //ccvotd.codeplex.com/SourceControl/changeset/view/40085#862458


忘了提及,我尝试使用IsWindowVisible() ,并没有工作,因为预览窗口仍然可见,并具有相同的处理,当我的屏幕保护程序被选中。

编辑:在我添加SetParent()和相关的调用之前,我的应用程序将继续在closures显示对话框后运行,所以我认为该部分正在工作,当用户select不同的屏幕保护程序时会发生不同的事情。


正如John Kbuild议我一直在用Spy ++来查看我的表格。 我从来没有看到应用WS_CHILD样式。 不过,我所有的debugging都表明它应该是。 我修改了代码:

 long style = GetWindowLong(Handle, -16); System.Diagnostics.Trace.WriteLine("Original Style: " + style); style &= ~0x800000000; style |= 0x40000000; System.Diagnostics.Trace.WriteLine("Adjusted Style: " + style); SetWindowLong(Handle, -16, new IntPtr(style)); System.Diagnostics.Trace.WriteLine("After Set Style: " + GetWindowLong(Handle, -16)); SetParent(Handle, _PreviewHandle); System.Diagnostics.Trace.WriteLine("After Set Parent: " + GetWindowLong(Handle, -16)); 

最后三条曲线的样式是相同的,其中两条应该从表单本身获得值。 去研究我的本地API调用,并清理他们的声明,看看我能弄清楚。

感谢所有的帮助!


解决scheme:问题最终导致我设置了几个导致底层.NET控件覆盖我的新样式的属性。 所以改变:

 SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); Capture = true; if (!_IsPreview) { // Removed ... } else { SetWindowLong(Handle, -16, new IntPtr(GetWindowLong(Handle, -16) | 0x40000000)); SetParent(Handle, _PreviewHandle); Rectangle parentRectangle; GetClientRect(_PreviewHandle, out parentRectangle); Size = parentRectangle.Size; Location = new Point(0, 0); } ShowInTaskbar = false; DoubleBuffered = true; BackgroundImageLayout = ImageLayout.Stretch; 

至:

 SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); BackgroundImageLayout = ImageLayout.Stretch; Capture = true; DoubleBuffered = true; ShowInTaskbar = false; if (!_IsPreview) { // Removed ... } else { SetWindowLong(Handle, -16, new IntPtr(GetWindowLong(Handle, -16) | 0x40000000)); SetParent(Handle, _PreviewHandle); Rectangle parentRectangle; GetClientRect(_PreviewHandle, out parentRectangle); Size = parentRectangle.Size; Location = new Point(0, 0); } 

解决了这个问题。 简单的错误:-)


正确的方法来解决它…重写CreateParams:

 protected override CreateParams CreateParams { get { CreateParams createParams = base.CreateParams; if (!DesignMode && _IsPreview) { createParams.Style |= 0x40000000; } return createParams; } } 

一旦尝试改变已经创建的窗口的WS_CHILD样式,就会悄然失败。 我认为他们改变了当前版本的Windows,但可以肯定的是,你应该真的从一开始就创建你的预览窗口作为子窗口。

我有一个预感你的窗口没有结束预览的子窗口。 你可以试试这个。

 SetParent(Handle, _PreviewHandle); SetWindowLong(Handle, -16, new IntPtr(GetWindowLong(Handle, -16) | 0x40000000)); SetParent(Handle, _PreviewHandle); 

将窗口样式更改为WS_CHILD 之后,再设置SetParent。

此外,您的表单上可能没有WS_POPUP样式,但是如果这样做,则需要将其删除。

 int style = GetWindowLong(Handle, -16); style &= ~0x800000000; style |= 0x40000000; SetWindowLong(Handle, -16, new IntPtr(style)); 

这里发生的是SetParent设置了子窗口的父项,但它设置了WS_POPUP和WS_OVERLAPPED窗口的所有者