- Сообщения
- 5,379
- Репутация
- 2,724
Когда я перешел на Windows 7, то столкнулся с такой проблемой: изменение состояния Progress Bar'а происходит не скачками, как в Windows XP, а плавно, на что, естественно, требуется какое-то время. Выглядит все это конечно красиво, но в некоторых ситуациях очень не кстати. Например при отображении копирования файлов (пример 4). Как я не старался отключить анимацию, у меня так ничего и не получилось. Поэтому пришлось-таки нарисовать собственный Progress Bar, который полностью соответствует выбранной теме. Дополнительно можно задать один из четырех цветов: зеленый (по умолчанию), красный, желтый или голубой. Данный пример корректно будет работать только в Windows Vista/7, и только с включенной темой (не классический вид).
Код:
#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