好吧,谷歌今晚不是我的朋友。。。
我有一个屏幕保护程序,
CC.Votd (Full source on Codeplex)
,我刚刚开始实现预览模式(/p参数),它工作正常。当它处于预览模式时,我将我的表单作为小计算机监视器窗口的子窗口,并在其中绘制。
如果“显示属性”对话框消失,这将正常工作,并且我的应用程序将退出。
问题是,如果我从列表中选择我的屏幕保护程序,然后选择一个不同的屏幕保护程序,我的屏幕保护程序将继续运行,并绘制新选择的屏幕保护程序的预览。
那么,我如何知道什么时候选择了不同的屏幕保护程序,我的屏幕保护程序应该关闭?
对于Anon,下面是我用来使表单成为预览窗口子窗口的代码:
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()
在显示对话框关闭后,我的应用程序将继续运行相关调用,因此我认为该部分正在工作,当用户选择不同的屏幕保护程序时,会发生一些不同的情况。
正如John K所说,我一直在用Spy++查看我的表单。我从未见过应用WS_CHILD样式。然而,我所有的调试建议它应该是。我将代码修改为:
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调用并清理它们的声明,看看我能找出什么。
谢谢你到目前为止的帮助!
解决方案:
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;
}
}