2010-02-08 1 views
1

ИТАК 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; 
    } 
} 
+2

Не могли бы вы опубликовать код, который вы используете, чтобы создать окно предварительного просмотра в качестве дочернего элемента HWND с передачей? –

+0

@ Не знаю: я нашел это из примера и не очень внимательно изучил его, потому что он работает для меня :-) –

+1

Диалог заставки уничтожает окно предварительного просмотра, когда пользователь переключает заставки - вы послушайте это? –

ответ

1

После APON времени, пытаясь изменить стиль WS_CHILD окна после того, как она была уже создана бы просто тихо терпит неудачу. Я думаю, что они изменили это в текущих версиях окон, но, конечно, вы действительно должны создавать свою форму предварительного просмотра в качестве дочернего окна с самого начала.

У меня есть подозрение, что ваше окно не заканчивается дочерним окном предварительного просмотра. вы могли бы попробовать это.

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

SetParent после изменить свой стиль окна WS_CHILD.

Кроме того, у вас может не быть стиля WS_POPUP в вашей форме, но если вы это сделаете, вы хотите удалить его.

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

То, что здесь происходит, что SetParent устанавливает вышестоящий дочерних окон, но она устанавливает владельца из WS_POPUP и WS_OVERLAPPED окон.

+0

@ Джон: Еще раз спасибо за указание на меня в правильном направлении. –