Спиране на избледняването на лентата за превъртане във Vista (.NET или WinAPI)

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

Искам да направя това само временно и не мисля, че подкласирането е опция, защото лентите за превъртане са "автоматични", генерирани от функцията за автоматично превъртане (това е .NET приложение, но предполагам, че е необходимо взаимодействие).

Причината, поради която искам да направя това, е, че съдържанието на контролата може (и ще) се променя и води до автоматично скриване на вертикалната лента за превъртане. Въпреки това - и това е частта, която ме подлудява - ако потребителят е задържал курсора на мишката върху лентата за превъртане през последните 1-2 секунди и анимацията все още е в ход, тогава лентата за превъртане се скрива, но анимацията продължава въпреки това и оставя призрачно изображение, така че SB изглежда все още там, въпреки че всъщност не е (не мога да щракна върху него и минимизирането/възстановяването на формуляра го кара да изчезне напълно).

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

Благодаря предварително,
Арън


person Aaronaught    schedule 18.02.2009    source източник
comment
Най-доброто ми предложение е да регистрирате грешка с MS.   -  person Jonathan C Dickinson    schedule 25.02.2009


Отговори (4)


това е ефект, за който също се чудя.

Написах контрола, получена от ContainerControl, където дъщерните контроли могат да растат или да се свиват от взаимодействието на потребителя. Така че отделих известно време, за да настроя моя собствен LayoutEngine, за да получа необходимото оформление за дъщерните контроли. Но дори и този анимиран нон-стоп SB е мръсен. Имам заобиколно решение - моля, не го приемайте като решение - в метода Layout поставям фокуса върху контролата на контейнера, преди да направя оформлението. Това работи за мен...

rp

Друго решение...

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);
}
person Community    schedule 25.02.2009

Заобиколното решение в тази публикация работи за мен:

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);
}
person sger6218    schedule 30.08.2011

Има ли някаква причина изобщо да има ленти за превъртане? Можете да ги изключите, без да използвате никакви трикове за API на Win32, като същевременно зададете размера на вашия прозорец, за да се справите по подходящ начин с анимацията (или да мащабирате вашата анимация).

Мисля, че единствената ви друга възможност е да търкаляте свой собствен обект Window, което би било кралска болка.

person Beep beep    schedule 21.02.2009
comment
Твърде много съдържание, за да се побере във формуляра без превъртане. Не е добре да ограничавате голямото съдържание до собственото поле за превъртане, защото в крайна сметка ще се окаже много малка използваема площ. Помислете за отчет с дълъг горен/долен колонтитул – обикновено искате да превъртите целия отчет, а не само основната част. - person Aaronaught; 24.02.2009

Въпросът не прави напълно ясно дали имате предвид ленти за превъртане във вашето приложение или цялата система. Ако имате предвид цялата система, тогава не съм сигурен какво можете да направите, освен изцяло нова тема за целия си компютър. Ако обаче имате предвид промяна само на собственото си приложение, можете да промените поведението на лентата за превъртане, като използвате шаблони за управление на WPF, за да направите това, което описвате.

Ако имате Expression Blend, това е доста лесно да се направи, защото може да създаде копие на лентата за превъртане по подразбиране, която можете да промените, за да отговаря на вашите вкусове (като промяна на времето на избледняване до нула в този случай). Тази връзка не е точно това, което търсите, но трябва да ви даде представа какво може да включва.

Ако нямате Expression Blend, все още е възможно да кодирате същото нещо на ръка, тъй като всичко е само XAML текст (дори когато Blend го произвежда), но ще са необходими още малко усилия, за да се научите как да го правите по този начин.

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

person Eric Cosky    schedule 18.03.2009
comment
Това е само в рамките на приложението и по-специално в рамките на един контрол; той се оразмерява автоматично в друга контрола, но родителската лента за превъртане не изчезва, когато трябва, ако е по средата на анимация. Това също е приложение Winforms 2.0 - няма WPF - може да проучи вграждането. - person Aaronaught; 19.03.2009