Хорошо, сегодня Google не мой друг ...
У меня есть заставка, CC.Votd (Полный исходный код в Codeplex) , и я только начал реализовывать режим предварительного просмотра (аргумент / p), который работает нормально. Когда он находится в режиме предварительного просмотра, я превращаю свою форму ребенка в маленькое окно монитора компьютера, и оно рисует там.
Это работает нормально, и мое приложение закрывается, если диалоговое окно свойств экрана исчезает.
Проблема заключается в том, что если я выберу заставку из списка, а затем выберу другую заставку, шахта продолжит работу и будет отображать предварительный просмотр только что выбранной заставки.
Итак, как мне узнать, когда выбрана другая заставка, и моя должна закрыться?
Редактировать: Для Анона, вот код, который я использую, чтобы сделать мою форму дочерней по отношению к окну предварительного просмотра:
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()
и связанные вызовы, мое приложение продолжало бы работать после закрытия диалогового окна, поэтому я думаю, что часть работает, и что-то другое происходит, когда пользователь выбирает другой заставка.
Как предположил Джон К, я просматривал свою форму в 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 и очистить их объявления, чтобы увидеть, что я могу выяснить.
Спасибо за всю помощь!
Решение: Проблема закончилась тем, что я установил несколько свойств формы, в результате чего базовый элемент управления .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;
}
}