ИТАК Google не мой друг сегодня ...Как узнать, когда в диалоговом окне свойств экрана была выбрана другая заставка?
У меня есть хранитель экрана, CC.Votd (Full source on Codeplex), и я только начал реализовывать режим предварительного просмотра (/ р аргумент), который работает нормально. Когда он находится в режиме предварительного просмотра, я делаю свою форму ребенком в окне монитора компьютера и рисует там.
Это прекрасно работает, и мое приложение завершается, если диалог свойств дисплея уходит.
Проблема в том, что если я выберу свою экранную заставку из списка, а затем выберем другую заставку, моя шахта продолжит работать и нарисует предварительный просмотр недавно выбранной экранной заставки.
Итак, как я узнаю, когда выбрана другая заставка, и моя должна закрыться?
Edit: Для Анон, вот код, я использую, чтобы моя форма ребенка из окна предварительного просмотра:
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()
и что не работает, так как окно предварительного просмотра остается видимым и имеет ту же ручку, как, когда была выбрана моя экранная заставка.
Edit: Прежде чем я добавил SetParent()
и связанные называет мое приложение будет продолжать работать после того, как диалог высвечивает был закрыт, поэтому я думаю, что часть работает и что-то другое происходит, когда пользователь выбирает другую экранную заставку.
Как Джон К предположил, что я смотрел на свою форму со 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-вызовы API и очищать их декларации, чтобы понять, что я могу понять.
Спасибо за помощь!
Решение: Проблемы закончилась тем, что я устанавливал несколько свойств формы, которые привели к нижележащему управлению .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;
To:
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;
}
}
Не могли бы вы опубликовать код, который вы используете, чтобы создать окно предварительного просмотра в качестве дочернего элемента HWND с передачей? –
@ Не знаю: я нашел это из примера и не очень внимательно изучил его, потому что он работает для меня :-) –
Диалог заставки уничтожает окно предварительного просмотра, когда пользователь переключает заставки - вы послушайте это? –