Автор Тема: Progress Bar без анимации, разноцветный для Windows Vista/7  (Прочитано 7038 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Yashied [?]

  • AutoIt MVP
  • Глобальный модератор
  • *
  • Сообщений: 5379
  • Репутация: 2696
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.x.x
Когда я перешел на Windows 7, то столкнулся с такой проблемой: изменение состояния Progress Bar'а происходит не скачками, как в Windows XP, а плавно, на что, естественно, требуется какое-то время. Выглядит все это конечно красиво, но в некоторых ситуациях очень не кстати. Например при отображении копирования файлов (пример 4). Как я не старался отключить анимацию, у меня так ничего и не получилось. Поэтому пришлось-таки нарисовать собственный Progress Bar, который полностью соответствует выбранной теме. Дополнительно можно задать один из четырех цветов: зеленый (по умолчанию), красный, желтый или голубой. Данный пример корректно будет работать только в Windows Vista/7, и только с включенной темой (не классический вид).


Код: AutoIt [Выделить]
#Include <WinAPI.au3>

GUICreate('MyGUI', 476, 176)
For $i = 0 To 3
    GUICtrlCreatePic('', 20, 20 + 40 * $i, 280, 16)
    _SetProgress(-1, Random(0, 100, 1), $i)
Next
For $i = 0 To 3
    GUICtrlCreatePic('', 320 + 40 * $i, 20, 16, 136)
    _SetProgress(-1, Random(0, 100, 1), $i, 1)
Next
GUISetState()

Do
Until GUIGetMsg() = -3

Func _SetProgress($hWnd, $iPercent, $iState = 0, $fVertical = False)

    Local $hDC, $hMemDC, $hSv, $hObj, $hBitmap, $hTheme, $tRect, $tClip, $W, $H, $Ret, $Rusult = 1

    If Not IsHWnd($hWnd) Then
        $hWnd = GUICtrlGetHandle($hWnd)
        If Not $hWnd Then
            Return 0
        EndIf
    EndIf
    $hTheme = DllCall('uxtheme.dll', 'ptr', 'OpenThemeData', 'hwnd', $hWnd, 'wstr', 'Progress')
    If (@error) Or (Not $hTheme[0]) Then
        Return 0
    EndIf
    $tRect = _WinAPI_GetClientRect($hWnd)
    $W = DllStructGetData($tRect, 3) - DllStructGetData($tRect, 1)
    $H = DllStructGetData($tRect, 4) - DllStructGetData($tRect, 2)
    $hDC = _WinAPI_GetDC($hWnd)
    $hMemDC = _WinAPI_CreateCompatibleDC($hDC)
    $hBitmap = _WinAPI_CreateSolidBitmap(0, _WinAPI_GetSysColor(15), $W, $H, 0)
    $hSv = _WinAPI_SelectObject($hMemDC, $hBitmap)
    DllStructSetData($tRect, 1, 0)
    DllStructSetData($tRect, 2, 0)
    DllStructSetData($tRect, 3, $W)
    DllStructSetData($tRect, 4, $H)
    $Ret = DllCall('uxtheme.dll', 'uint', 'DrawThemeBackground', 'ptr', $hTheme[0], 'hwnd', $hMemDC, 'int', 2 - (Not $fVertical), 'int', 0, 'ptr', DllStructGetPtr($tRect), 'ptr', 0)
    If (@error) Or ($Ret[0]) Then
        $Rusult = 0
    EndIf
    If $fVertical Then
        DllStructSetData($tRect, 2, $H * (1 - $iPercent / 100))
    Else
        DllStructSetData($tRect, 3, $W * $iPercent / 100)
    EndIf
    $tClip = DllStructCreate($tagRECT)
    DllStructSetData($tClip, 1, 1)
    DllStructSetData($tClip, 2, 1)
    DllStructSetData($tClip, 3, $W - 1)
    DllStructSetData($tClip, 4, $H - 1)
    DllCall('uxtheme.dll', 'uint', 'DrawThemeBackground', 'ptr', $hTheme[0], 'hwnd', $hMemDC, 'int', 6 - (Not $fVertical), 'int', 1 + $iState, 'ptr', DllStructGetPtr($tRect), 'ptr', DllStructGetPtr($tClip))
    If (@error) Or ($Ret[0]) Then
        $Rusult = 0
    EndIf
    _WinAPI_ReleaseDC($hWnd, $hDC)
    _WinAPI_SelectObject($hMemDC, $hSv)
    _WinAPI_DeleteDC($hMemDC)
    DllCall('uxtheme.dll', 'uint', 'CloseThemeData', 'ptr', $hTheme[0])
    If $Rusult Then
        _WinAPI_DeleteObject(_SendMessage($hWnd, 0x0172, 0, $hBitmap))
        $hObj = _SendMessage($hWnd, 0x0173)
        If $hObj <> $hBitmap Then
            _WinAPI_DeleteObject($hBitmap)
        EndIf
    EndIf
    Return $Rusult
EndFunc   ;==>_SetProgress



Думай, прежде чем говорить.

Русское сообщество AutoIt

Progress Bar без анимации, разноцветный для Windows Vista/7
« Отправлен: Ноябрь 07, 2010, 17:19:01 »

Оффлайн Afonichev [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 1535
  • Репутация: 408
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
C помощью кнопки тоже не плохо ;D

Код: AutoIt [Выделить]
#Include <WinAPI.au3>

GUICreate('MyGUI', 476, 176)
$hProgress = GUICtrlCreatePic('', 20, 20, 280, 16)
GUISetState()

For $i = 0 To 100 Step 1
    _SetProgress($hProgress, $i, 1, False)
    Sleep(100)
Next

Do
Until GUIGetMsg() = -3

Func _SetProgress($hWnd, $iPercent, $iState = 0, $fVertical = False)

    Local $hDC, $hMemDC, $hSv, $hObj, $hBitmap, $hTheme, $tRect, $tClip, $W, $H, $Ret, $Rusult = 1

    If Not IsHWnd($hWnd) Then
        $hWnd = GUICtrlGetHandle($hWnd)
        If Not $hWnd Then
            Return 0
        EndIf
    EndIf
    $hTheme = DllCall('uxtheme.dll', 'ptr', 'OpenThemeData', 'hwnd', $hWnd, 'wstr', 'Button')
    If (@error) Or (Not $hTheme[0]) Then
        Return 0
    EndIf
    $tRect = _WinAPI_GetClientRect($hWnd)
    $W = DllStructGetData($tRect, 3) - DllStructGetData($tRect, 1)
    $H = DllStructGetData($tRect, 4) - DllStructGetData($tRect, 2)
    $hDC = _WinAPI_GetDC($hWnd)
    $hMemDC = _WinAPI_CreateCompatibleDC($hDC)
    $hBitmap = _WinAPI_CreateSolidBitmap($hWnd, _WinAPI_GetSysColor(14), $W, $H, 1)
    $hSv = _WinAPI_SelectObject($hMemDC, $hBitmap)

    DllStructSetData($tRect, 1, 0)
    DllStructSetData($tRect, 2, 0)
    DllStructSetData($tRect, 3, $W)
    DllStructSetData($tRect, 4, $H)
    $Ret = DllCall('uxtheme.dll', 'uint', 'DrawThemeBackground', 'ptr', $hTheme[0], 'hwnd', $hMemDC, 'int', 2 - (Not $fVertical), 'int', 0, 'ptr', DllStructGetPtr($tRect), 'ptr', 0)
    If (@error) Or ($Ret[0]) Then
        $Rusult = 0
    EndIf
    If $fVertical Then
        DllStructSetData($tRect, 2, $H * (1 - $iPercent / 100))
    Else
        DllStructSetData($tRect, 3, $W * $iPercent / 100)
    EndIf
    $tClip = DllStructCreate($tagRECT)
    DllStructSetData($tClip, 1, 1)
    DllStructSetData($tClip, 2, 1)
    DllStructSetData($tClip, 3, $W - 1)
    DllStructSetData($tClip, 4, $H - 1)
    DllCall('uxtheme.dll', 'uint', 'DrawThemeBackground', 'ptr', $hTheme[0], 'hwnd', $hMemDC, 'int', 2 - (Not $fVertical), 'int', 1 + $iState, 'ptr', DllStructGetPtr($tRect), 'ptr', DllStructGetPtr($tClip))
    If (@error) Or ($Ret[0]) Then
        $Rusult = 0
    EndIf
    _WinAPI_ReleaseDC($hWnd, $hDC)
    _WinAPI_SelectObject($hMemDC, $hSv)
    _WinAPI_DeleteDC($hMemDC)
    DllCall('uxtheme.dll', 'uint', 'CloseThemeData', 'ptr', $hTheme[0])
    If $Rusult Then
        _WinAPI_DeleteObject(_SendMessage($hWnd, 0x0172, 0, $hBitmap))
        $hObj = _SendMessage($hWnd, 0x0173)
        If $hObj <> $hBitmap Then
            _WinAPI_DeleteObject($hBitmap)
        EndIf
    EndIf
    Return $Rusult
EndFunc   ;==>_SetProgress
 


Оффлайн Ilyialat [?]

  • Новичок
  • *
  • Сообщений: 54
  • Репутация: 2
    • Награды
Спасибо)

Русское сообщество AutoIt

Re: Progress Bar без анимации, разноцветный для Windows Vista/7
« Ответ #2 Отправлен: Август 31, 2012, 17:37:52 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
3 Ответов
4752 Просмотров
Последний ответ Октябрь 23, 2010, 11:54:26
от tech-gs
3 Ответов
5392 Просмотров
Последний ответ Май 16, 2011, 04:29:05
от HukpoFuJl
10 Ответов
4986 Просмотров
Последний ответ Январь 10, 2014, 23:20:24
от Siroga00VII
5 Ответов
2887 Просмотров
Последний ответ Июнь 29, 2012, 11:38:53
от Afonichev
1 Ответов
2066 Просмотров
Последний ответ Сентябрь 19, 2012, 18:14:04
от Yashied
2 Ответов
1273 Просмотров
Последний ответ Март 21, 2014, 08:52:55
от Belfigor
10 Ответов
2425 Просмотров
Последний ответ Декабрь 16, 2014, 20:41:52
от inververs
7 Ответов
1889 Просмотров
Последний ответ Июль 07, 2016, 11:42:29
от Maxlinus
1 Ответов
206 Просмотров
Последний ответ Март 18, 2018, 16:15:52
от Tempo
4 Ответов
546 Просмотров
Последний ответ Октябрь 30, 2018, 10:12:15
от ramzesranec