Фон Windows Aero Glass нарушается после перехода в спящий режим. Как я могу это решить?

Я разрабатываю программу на C # .net 3.5 wpf. Он должен работать в Windows XP, Windows Vista и Windows 7. В более новых операционных системах я хотел создать фон в Aero Glass. Так что это только особый дизайн. После спящего режима, после приостановки или изменения окон Desings на базовый дизайн и обратно в аэро все добавленные стекла отображаются полностью черными.

Я отображаю Glass через класс GlassHelper (его можно найти в Google).

Собственно я вижу 3 способа решения этой проблемы. Первый - это решить. Но я где-то читал, что это ошибка в управляемом коде Windows, поэтому у меня нет возможности исправить ее. Поправьте меня, если я ошибаюсь.

Так что у меня возникла идея каждый раз закрывать окно, оно сворачивается и полностью перестраивать, когда оно будет использоваться в следующий раз.

Это неплохо работает. После спящего режима окно по-прежнему отображается черным, но мне не нужно выходить из приложения, я все еще могу минимизировать его и снова развернуть.

Теперь я вижу пути:

1) Я закрываю окно каждый раз, когда компьютер переходит в спящий режим или меняет дизайн. И я снова открываю окно, когда оно сохраняется. Но как мне с этим справиться?

2) Я согласен с тем, что окно будет отображаться черным, пока кто-нибудь его не свернет. (Не мой любимый) Но затем у меня появляется новая проблема: кнопка на панели задач. (Не значок в трее). Мне нужно, чтобы он отображался постоянно. На winxp мне нужно, чтобы окно открывалось, когда оно свернуто. И особенно на win7 мне это нужно, потому что я хочу использовать некоторые из новых преимуществ Superbar! (предварительный просмотр при наведении указателя мыши не будет окном, это будет статичное изображение.)

Спасибо всем, что помогли мне!


person Legy    schedule 13.02.2011    source источник
comment
Это проблема с другими программами в вашей системе разработки или просто с программой, которую вы создаете?   -  person tomfanning    schedule 13.02.2011
comment
Это просто программа, которую я строю.   -  person Legy    schedule 13.02.2011


Ответы (3)


Попробуйте обработать сообщение WM_NCCALCSIZE и уменьшить клиентскую область (NCCALCSIZE_PARAMS.rgrc0) на один пиксель. Я серьезно. Я обнаружил, что это решение используется в Google Chrome, и оно мне тоже подходит.

person Marat Khasanov    schedule 13.02.2011
comment
Хорошо, я хотя бы попробую это решение ... Спасибо, немного, так как сейчас половина первого ночи, сделаю это завтра! - person Legy; 14.02.2011
comment
Взгляните на этот src.chromium.org/svn/branches / 329 / src / views / window / и найдите gfx :: Insets WindowWin :: GetClientAreaInsets - person Marat Khasanov; 14.02.2011
comment
Привет, я пока пробовал ваш, потому что он немного умнее, но я не смог решить свою проблему. Моя программа больше не имеет черного фона, но зависает в не-аэродинамической теме, а в новой теме она снова полностью прозрачна, я вижу только границу. - person Legy; 15.02.2011

Хорошо, всем спасибо! Но я думаю, что нашел свое решение!

Я обрабатываю сообщения: WM_DWMCOMPOSITIONCHANGED (0x031E) и WM_THEMECHANGED (0x031A)

и, поймав одно из этих сообщений, я просто снова назначаю стакан или новый фон в зависимости от DwmIsCompositionEnabled ().

Собственно у меня есть что-то похожее на следующее:

const int WM_THEMECHANGED = 0x031A;
const int WM_DWMCOMPOSITIONCHANGED = 0x031E;

private static void ApplyTheme(IntPtr hwnd)
{
    if (DwmIsCompositionEnabled())
    {
        HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;
        MARGINS margins = new MARGINS(new Thickness(-1));
        DwmExtendFrameIntoClientArea(hwnd, ref margins);
    }
    else
    {
        HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = SystemColors.ActiveCaptionBrush.Color;
    }
}

private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    if (msg == WM_THEMECHANGED)
    {
        ApplyTheme(hwnd);
    }
    if (msg == WM_DWMCOMPOSITIONCHANGED)
    {
        ApplyTheme(hwnd);
    }
    return IntPtr.Zero;
}

Я понимаю.

Подцепил.

HwndSource.FromHwnd(hwnd).AddHook(new HwndSourceHook(WndProc));

Я делаю фон окна WPF прозрачным, потому что позже в функции WndProc я смогу получить доступ только к моему фону hwnd (Win32).

window.Background = Brushes.Transparent;

А теперь мне нужно только первый раз назначить стиль:

ApplyTheme(hwnd);

Вот и все! У меня отлично работает (Win 64 Home Premium) после того, как я отключил или включил аэро, переключился между разными стилями аэро или без аэро или в спящий режим, так что это именно то, что я искал. Спасибо за прекрасные идеи!

person Legy    schedule 16.02.2011

Вы можете ознакомиться с библиотекой интеграции оболочки WPF. Я помню, что с этой библиотекой были похожие проблемы из-за ошибки в диспетчере окон рабочего стола в Windows 7. Библиотека имеет доступный исходный код, так что вы можете посмотреть, как они с этим справляются.

person JLaanstra    schedule 13.02.2011
comment
Спасибо, посмотрю! - person Legy; 13.02.2011
comment
В порядке. Тестовое приложение с оболочкой становится черным из-за более старой темы Windows. Но разница в том, что он полностью восстанавливает свой прежний вид, когда вы снова переключаетесь на аэро. Думаю, это было бы неплохо. Я постараюсь использовать это в своем собственном приложении. Спасибо! - person Legy; 13.02.2011