Остановка исчезновения полосы прокрутки в Vista (.NET или WinAPI) - PullRequest
0 голосов
/ 18 февраля 2009

Кто-нибудь знает какой-либо способ подавления анимации исчезновения Vista на полосах прокрутки?

Я хочу сделать это только временно, и я не думаю, что подклассы - это вариант, потому что полосы прокрутки являются «автоматическими», генерируемыми функцией автопрокрутки (это приложение .NET, но я предполагаю, что взаимодействие требуется) .

Причина, по которой я хочу это сделать, заключается в том, что содержимое элемента управления может (и будет) изменяться и вызывать автоматическое скрытие вертикальной полосы прокрутки. Однако - и это та часть, которая сводит меня с ума - если пользователь завис над полосой прокрутки в течение последних 1-2 секунд, и анимация все еще продолжается, полоса прокрутки скрывается, но анимация все равно продолжается и оставляет Призрачное изображение, поэтому SB, кажется, все еще там, хотя его на самом деле нет (не может щелкнуть по нему, а сворачивание / восстановление формы приводит к ее полному исчезновению).

Я полагаю, что Vista использует какой-то таймер для этой анимации и надеюсь, что, возможно, есть какой-то новый API, чтобы остановить таймер (Google, к сожалению, в этом не поможет). Или, если кто-то еще сталкивался с этой проблемой и знает другой способ ее решения, это тоже было бы здорово.

Заранее спасибо,
Aaron

Ответы [ 4 ]

1 голос
/ 30 августа 2011

У меня есть обходной путь в этом посте:

http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/88abdb31-651b-4b47-ae24-8b923344c349

В примере в посте используется C ++, но вот код C #, иллюстрирующий, как я использую его в .NET через pinvoke (работая в подклассе Control ...)

protected override void OnSizeChanged(EventArgs e)
{
    if (_vScrollVisible != VerticalScroll.Visible)
    {
        _vScrollVisible = VerticalScroll.Visible;

        if (!_vScrollVisible)
        {

            if (NativeMethods.IsThemeActive())
            {
                // Fix scrollbar fade issue                
                NativeMethods.SetWindowTheme(Handle, null, null);
            }
        }
    }
}

internal static class NativeMethods
{      
    [DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
    public static extern bool IsThemeActive();

    [DllImport("uxtheme.dll", ExactSpelling = true, CharSet = CharSet.Unicode)]
    public static extern int SetWindowTheme(IntPtr hWnd, String pszSubAppName, String pszSubIdList);
}
0 голосов
/ 25 февраля 2009

об этом мне тоже интересно.

Я написал элемент управления, полученный из ContainerControl, где дочерние элементы управления могут увеличиваться или уменьшаться в результате взаимодействия с пользователем. Поэтому я потратил некоторое время, чтобы настроить свой собственный LayoutEngine, чтобы получить необходимый макет для дочерних элементов управления. Но даже этот анимированный безостановочный SB грязен. У меня есть обходной путь - пожалуйста, не принимайте это как решение - в методе Layout я установил фокус на элементе управления контейнером перед созданием макета. Это работает для меня ...

гр

Еще один обходной путь ...

is to inherit from the ScrollableControl (Panel, ...) and to

переопределить метод WndProc и использовать метод PreventScrollAnimation. Это сожжет все сообщения WM_NCMOUSEMOVE, имеющие тест попадания в полосе прокрутки. Так что это не позволит внутренним элементам начать исчезать полосы прокрутки. Кстати, замирание реализовано в интерфейсе VISTA-UI с использованием обратного вызова таймера, поэтому нет возможности остановить это.

const int WM_NCMOUSEMOVE = 160;
const int HTHSCROLL = 6;
const int HTVSCROLL = 7;

bool PreventScrollAnimation(ref Message m)
{
    if (m.Msg == WM_NCMOUSEMOVE)
    {
        if ((m.WParam.ToInt32() == HTHSCROLL) ||
            (m.WParam.ToInt32() == HTVSCROLL))
        {
            m.Result = IntPtr.Zero;
            return true;
        }
    }
    return false;
}

protected override void WndProc(ref Message m)
{
    if (PreventScrollAnimation(ref m))
        return;

    base.WndProc(ref m);
}
0 голосов
/ 18 марта 2009

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

Если у вас есть Expression Blend, это довольно легко сделать, потому что он может создать копию полосы прокрутки по умолчанию, которую вы можете изменить в соответствии со своими вкусами (например, в этом случае изменение времени затухания до нуля). Эта ссылка не совсем то, что вы ищете, но она должна дать вам представление о том, что это может включать.

Если у вас нет Expression Blend, все равно можно кодировать одно и то же вручную, поскольку это всего лишь текст XAML (даже когда Blend его создает), но потребуется больше усилий, чтобы научиться делать это так, чтобы способ.

Глава 15 из Windows Presentation Foundation Unleashed (отличная книга по многим причинам) объясняет, как использовать WPF внутри и в качестве хоста приложений Win32 и Windows Forms, что удобно, если вы не можете портировать все ваше приложение в WPF, но все еще хотите использовать некоторые функции WPF выборочно.

0 голосов
/ 21 февраля 2009

Есть ли причина вообще иметь полосы прокрутки? Вы можете отключить их, не используя какие-либо приемы Win32 API, а также установить размер вашего окна для соответствующей обработки анимации (или масштабирования анимации).

Я думаю, что ваш единственный вариант - бросить свой собственный объект Window, что было бы ужасно.

...