#include <GuiToolbar.au3>
#include <GuiImageList.au3>
#include <WinAPI.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>

$Debug_TB = False ; Проверяет ClassName передаваемый в функции. Установите True и используйте дескриптор от другого элемента, чтобы увидеть как это работает
Global $iMemo, $hToolbar, $iItem
Global Enum $idBtn1 = 1000, $idBtn2, $idBtn3, $idBtn4

_Main()

Func _Main()
	Local $hGUI, $hNormal, $hDisabled, $hHot
	Local $hBmpCloseNorm, $hBmpCloseHot, $hBmpCloseDis

	; Создаёт GUI
	$hGUI = GUICreate(StringTrimRight(@ScriptName, 4), 400, 300)
	$hToolbar = _GUICtrlToolbar_Create($hGUI)
	$iMemo = GUICtrlCreateEdit("", 2, 36, 396, 262, $WS_VSCROLL)
	GUICtrlSetFont($iMemo, 10, 400, 0, "Courier New")
	GUISetState()

	; PNG - Чёрный
	$hBmpCloseNorm = _ImgProcess(Binary("0x89504E470D0A1A0A0000000D49484452000000100000001008060000001FF3FF610000004D4944415478DA63646060F807C48C0C640290C6FF1418F09FEA061063188A7A6C2EC06708865A5C5E205A0C5F1810E3358281F81F4AE394A7A901147981A240A4281AA992904801D433806C000084BB3001A54004A20000000049454E44AE426082"))

	; PNG - Красный
	$hBmpCloseHot = _ImgProcess(Binary("0x89504E470D0A1A0A0000000D49484452000000100000001008060000001FF3FF610000004E4944415478DA63FCCFC00044E4034690018C409A1CCD60BD54358018C330D4A36BC2670856B5D834902486CB4662BC46301061518CD74B343380222F50148814452355121229807A0690A319060072C55FF1268547030000000049454E44AE426082"))

	; PNG - Серый
	$hBmpCloseDis = _ImgProcess(Binary("0x89504E470D0A1A0A0000000D49484452000000100000001008060000001FF3FF610000004F4944415478DA636C6868F8CF400160041900C48CE46806E9A5AE01C41886AE1EC305F80CC1A616AB174811C31906C4788D6020C2A2189F3CED0CA0C80B14052245D1489584440AA09E01E4688601009F29A8019406DA6A0000000049454E44AE426082"))

	; Создаёт нормальный список изображений
	$hNormal = _GUIImageList_Create(16, 16, 5)
	_GUIImageList_AddIcon($hNormal, 'shell32.dll', 19)
	_GUIImageList_AddIcon($hNormal, 'regedit.exe', 0)
	_GUIImageList_AddIcon($hNormal, 'notepad.exe', 0)
	_GUIImageList_Add($hNormal, $hBmpCloseNorm)
	_GUICtrlToolbar_SetImageList($hToolbar, $hNormal)

	; Создаёт список изображений для состояния недоступный
	$hDisabled = _GUIImageList_Create(16, 16, 5)
	_GUIImageList_AddIcon($hDisabled, 'shell32.dll', 10)
	_GUIImageList_AddIcon($hDisabled, 'shell32.dll', 8)
	_GUIImageList_AddIcon($hDisabled, 'shell32.dll', 12)
	_GUIImageList_Add($hDisabled, $hBmpCloseDis)
	_GUICtrlToolbar_SetDisabledImageList($hToolbar, $hDisabled)

	; Создаёт список изображений для состояния при наведении на элемент
	$hHot = _GUIImageList_Create(16, 16, 5)
	_GUIImageList_AddIcon($hHot, 'shell32.dll', 4)
	_GUIImageList_AddIcon($hHot, 'shell32.dll', 137)
	_GUIImageList_AddIcon($hHot, 'shell32.dll', 132)
	_GUIImageList_Add($hHot, $hBmpCloseHot)
	_GUICtrlToolbar_SetHotImageList($hToolbar, $hHot)

	; Добавляет кнопки
	_GUICtrlToolbar_AddButton($hToolbar, $idBtn1, 0)
	_GUICtrlToolbar_AddButton($hToolbar, $idBtn2, 1)
	_GUICtrlToolbar_AddButton($hToolbar, $idBtn3, 2)
	_GUICtrlToolbar_AddButton($hToolbar, $idBtn4, 3)

	; Показывает дескрипторы списка изображений
	MemoWrite("Дескриптор списка недоступных .: 0x" & Hex(_GUICtrlToolbar_GetDisabledImageList($hToolbar)))
	MemoWrite("Дескриптор списка при наведении: 0x" & Hex(_GUICtrlToolbar_GetHotImageList($hToolbar)))
	MemoWrite("Дескриптор списка нормального .: 0x" & Hex(_GUICtrlToolbar_GetImageList($hToolbar)))

	GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")

	; Цикл выполняется, пока окно не будет закрыто
	Do
	Until GUIGetMsg() = $GUI_EVENT_CLOSE

EndFunc   ;==>_Main

; Записывает строку в элемент для заметок
Func MemoWrite($sMessage = "")
	GUICtrlSetData($iMemo, $sMessage & @CRLF, 1)
EndFunc   ;==>MemoWrite

Func _WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID, $wParam
    Local $tNMHDR, $event, $hwndFrom, $code, $i_idNew, $dwFlags, $lResult, $idFrom, $i_idOld
    Local $tNMTOOLBAR, $tNMTBHOTITEM
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hwndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    ; $idFrom = DllStructGetData($tNMHDR, "IDFrom")
    $code = DllStructGetData($tNMHDR, "Code")
    Switch $hwndFrom
        Case $hToolbar
            Switch $code
                Case $NM_LDOWN
                    ; $a = _GUICtrlToolbar_CommandToIndex ($hToolbar, $iItem)
                    Switch $iItem
                        Case $idBtn1
                            Run('Explorer.exe')
                        Case $idBtn2
                            Run('regedit.exe')
                        Case $idBtn3
                            Run('notepad.exe')
                        Case $idBtn4
                            Exit
                    EndSwitch
                Case $TBN_HOTITEMCHANGE
                    $tNMTBHOTITEM = DllStructCreate($tagNMTBHOTITEM, $lParam)
                    ; $i_idOld = DllStructGetData($tNMTBHOTITEM, "idOld")
                    $i_idNew = DllStructGetData($tNMTBHOTITEM, "idNew")
                    $iItem = $i_idNew
                    $dwFlags = DllStructGetData($tNMTBHOTITEM, "dwFlags")
                    If BitAND($dwFlags, $HICF_LEAVING) = $HICF_LEAVING Then ; Если оставляет кнопку
                                ; SoundPlay(@WindowsDir & "\media\start.wav")
                    Else ; иначе наведение на кнопку
                        Switch $i_idNew
                            Case $idBtn1, $idBtn2, $idBtn3, $idBtn4
                                SoundPlay(@WindowsDir & "\media\start.wav")
                        EndSwitch
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_NOTIFY

; Преобразует бинарный представление в дескриптор
Func _ImgProcess(Const $bBinary) ; Объединение кода Progandy и Zedna
    Local $iLen = BinaryLen($bBinary)
    If $iLen = 0 Then Return SetError(2, 0, 0)
    Local $hMem = _MemGlobalAlloc($iLen, $GMEM_MOVEABLE)
    If @error Or Not $hMem Then Return SetError(3, 0, 0)
    DllStructSetData(DllStructCreate("byte[" & $iLen & "]", _MemGlobalLock($hMem)), 1, $bBinary)
    If @error Then
        _MemGlobalUnlock($hMem)
        _MemGlobalFree($hMem)
        Return SetError(4, 0, 0)
    EndIf
    _MemGlobalUnlock($hMem)
    _GDIPlus_Startup()
    Local $aResult = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "handle", $hMem, "bool", True, "ptr*", 0)
    If @error Or $aResult[0] <> 0 Or $aResult[3] = 0 Then
        _MemGlobalFree($hMem)
        Return SetError(5, @error, 0)
    EndIf
    Local $hImage = DllCall($ghGDIPDll, "uint", "GdipLoadImageFromStream", "ptr", $aResult[3], "int*", 0)
    Local $error = @error
	_MemGlobalFree($hMem) ; освобождение памяти, чтобы не вызывать в каждом последующем Return
    Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
    DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $aResult[3], "dword", 8 + 8 * @AutoItX64, "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT))
    If @error Then Return SetError(6, $error, 0)
    If $hImage[2] = 0 Then Return SetError(7, 0, $hImage[2])
    Local $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage[2])
    _GDIPlus_ImageDispose($hImage[2])
    _GDIPlus_Shutdown()
    Return SetError(0, 0, $hBitmap)
EndFunc   ;==>_ImgProcess