Что нового

Поддержка иконок и изображений, содержащих прозрачность (Alpha канал)

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
AutoIt: 3.3.0.0
Версия: 1.8

Категория: Управление элементами GUI

Описание: Как известно, AutoIt не поддерживает никаких форматов графических файлов кроме BMP, JPG и GIF (без анимации), что ни есть хорошо. Поэтому я написал библиотеку, которая исправляет это. UDF содержит всего 3 (но очень ползные) основные функции, которыми очень легко пользоваться. Все возможности этой библиотеки хорошо отображает приведенные ниже примеры. От себя лишь хочу сказать, что функция _SetImage() поддерживает все форматы графических файлов, которые, собственно, поддерживает Windows. Так же в UDF присутствуют несколько дополнительных функций для работы непосредственно с хендлами (HICON и HBITMAP).

Пример(ы): (составлен для AutoIt 3.3.0.0)
Код:
#Include <GUIConstantsEx.au3>
#Include <Icons.au3>

Global Const $sPng = RegRead('HKLM\SOFTWARE\AutoIt v3\AutoIt', 'InstallDir') & '\Examples\GUI\Advanced\Images\Torus.png'
Global Const $sJpg = @TempDir & '\~wallpaper.jpg'
Global Const $sGreen = @TempDir & '\~green.png'
Global Const $sRed = @TempDir & '\~red.png'
Global Const $sLogo = @TempDir & '\~logo.png'

Example1()
Example2()
Example3()
Example4()
Example5()
Example6()
Example7()

Func Example1()

    GUICreate('Example1', 204, 108)
    $Icon1 = GUICtrlCreateIcon('', 0, 30, 38, 32, 32)
    $Icon2 = GUICtrlCreateIcon('', 0, 88, 38, 32, 32)
    $Icon3 = GUICtrlCreateIcon('', 0, 146, 38, 32, 32)
    GUISetState()

    _SetCombineBkIcon($Icon1, -1, @SystemDir & '\shell32.dll', 70, 32, 32, @SystemDir & '\shell32.dll', 22, 24, 24, 0, 8)
    _SetCombineBkIcon($Icon2, -1, @SystemDir & '\shell32.dll', 3, 32, 32, @SystemDir & '\shell32.dll', 28, 32, 32)
    _SetCombineBkIcon($Icon3, -1, @SystemDir & '\shell32.dll', 220, 32, 32, @SystemDir & '\shell32.dll', 29, 32, 32)

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    GUIDelete()

EndFunc   ;==>Example1

Func Example2()

    GUICreate('Example2', 216, 128)
    $Icon = GUICtrlCreateIcon('', 0, 40, 40, 48, 48)
    GUICtrlCreateIcon(@WindowsDir & '\explorer.exe', 0, 128, 40, 48, 48)
    GUISetState()

    _SetIcon($Icon, @WindowsDir & '\explorer.exe', 0, 48, 48)

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    GUIDelete()

EndFunc   ;==>Example2

Func Example3()

    GUICreate('Example3', 715, 388)
    $Pic1 = GUICtrlCreatePic('', 10, 10, 386, 368)
    $Pic2 = GUICtrlCreatePic('', 406, 10, 193, 184)
    $Pic3 = GUICtrlCreatePic('', 609, 10, 96, 92)
    GUISetState()

    _SetImage($Pic1, $sPng)
    _SetImage($Pic2, $sPng)
    _SetImage($Pic3, $sPng)

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    GUIDelete()

EndFunc   ;==>Example3

Func Example4()

    GUICreate('Example4', 253, 244)
    $Pic1 = GUICtrlCreatePic('', 10, 10, 193, 184)
    $Pic2 = GUICtrlCreatePic('', 60, 60, 193, 184)
    GUISetState()

    _SetImage($Pic2, $sPng)
    _SetImage($Pic1, $sPng)

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    GUIDelete()

EndFunc   ;==>Example4

Func Example5()

    Local $aIndex[10] = [4, 13, 23, 31, 86, 104, 130, 150, 168, 170]

    GUICreate('Example5', 600, 400)
    $Pic = GUICtrlCreatePic('', 0, 0, 600, 400)
    For $i = 1 To UBound($aIndex)
        GUICtrlCreatePic('', Random(0, 600 - 48, 1), Random(0, 400 - 48, 1), 48, 48)
        $hIcon = _Icons_Icon_Extract(@SystemDir & '\shell32.dll', $aIndex[$i - 1], 48, 48)
        $hBitmap = _Icons_Bitmap_CreateFromIcon($hIcon)
        _SetHImage($Pic + $i, $hBitmap)
        _WinAPI_DeleteObject($hBitmap)
        _WinAPI_DestroyIcon($hIcon)
    Next
    GUISetState()

    InetGet('http://dota.ru/3d/big/p324_42.jpg', $sJpg)
    $hBitmap = _Icons_Bitmap_Load($sJpg)
    $hArea = _Icons_Bitmap_Crop($hBitmap, 420, 320, 600, 400)
    _SetHImage($Pic, $hArea)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteObject($hArea)
    FileDelete($sJpg)

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    GUIDelete()

EndFunc   ;==>Example5

Func Example6()

    GUICreate('Example6', 800, 500)
    $Background = GUICtrlCreatePic('', 0, 0, 800, 500)
    GUICtrlSetState(-1, $GUI_DISABLE)
    $Button = GUICtrlCreateButton('Test', 355, 460, 90, 23)
    $Pic1 = GUICtrlCreatePic('', 102, 122, 256, 256)
    $Pic2 = GUICtrlCreatePic('', 442, 122, 256, 256)
    GUISetState()

    InetGet('http://autoit-script.ru/autoit_rv_ua/files/Pictures/icons_ex_back.jpg', $sJpg)
    InetGet('http://autoit-script.ru/autoit_rv_ua/files/Pictures/icons_ex_green.png', $sGreen)
    InetGet('http://autoit-script.ru/autoit_rv_ua/files/Pictures/icons_ex_red.png', $sRed)
    _SetImage($Background, $sJpg)
    $hGreen = _Icons_Bitmap_Load($sGreen)
    $hRed = _Icons_Bitmap_Load($sRed)
    _SetHImage($Pic1, $hRed)
    _SetHImage($Pic2, $hRed)
    FileDelete($sJpg)
    FileDelete($sGreen)
    FileDelete($sRed)

    $pCtrlID = 0

    While 1
        $Cursor = GUIGetCursorInfo()
        If @error Then
            ContinueLoop
        EndIf
        $nCtrlID = $Cursor[4]
        If $nCtrlID <> $pCtrlID Then
            Switch $pCtrlID
                Case $Pic1
                    _SetHImage($Pic1, $hRed)
                Case $Pic2
                    _SetHImage($Pic2, $hRed, -1)
            EndSwitch
            Switch $nCtrlID
                Case $Pic1
                    _SetHImage($Pic1, $hGreen)
                Case $Pic2
                    _SetHImage($Pic2, $hGreen, -1)
            EndSwitch
            $pCtrlID = $nCtrlID
        EndIf
        $Msg = GUIGetMsg()
        Switch $Msg
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $Button
                GUICtrlSetState($Button, $GUI_DISABLE)
                For $i = 1 To 50
                    GUIGetMsg()
                    _SetHImage($Pic1, $hGreen)
                    _SetHImage($Pic2, $hGreen, -1)
                    Sleep(50)
                    _SetHImage($Pic1, $hRed)
                    _SetHImage($Pic2, $hRed, -1)
                    Sleep(50)
                Next
                GUICtrlSetState($Button, $GUI_ENABLE)
        EndSwitch
    WEnd

    GUIDelete()

EndFunc   ;==>Example6

Func Example7()

    GUICreate('Example7', 400, 93)
    $Pic = GUICtrlCreatePic('', 0, 0, 400, 93)
    $hIcon = _Icons_Icon_Extract(@SystemDir & '\shell32.dll', 86, 24, 24)
    $hBitmap = _Icons_Bitmap_CreateFromIcon($hIcon)
    For $i = 1 To 5
        GUICtrlCreatePic('', 258 + ($i - 1) * 28, 12, 24, 24)
        _SetHImage($Pic + $i, $hBitmap)
    Next
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DestroyIcon($hIcon)
    GUISetState()

    InetGet('http://www.autoitscript.com/forum/public/style_images/autoit/logo.png', $sLogo)
    $hBitmap = _Icons_Bitmap_Load($sLogo)
    $hArea = _Icons_Bitmap_Crop($hBitmap, 0, 7, 400, 93)
    _SetHImage($Pic, $hArea)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteObject($hArea)
    FileDelete($sLogo)

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    GUIDelete()

EndFunc   ;==>Example7

Файлы: AU3
Версия с поддержкой 3.3.14.5

Скриншот:

Icons.png

Источник: Icons UDF (оффициальный форум)
Автор: Yashied
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Обновил библиотеку до версии 1.8.

Список изменений (с 1.5 до 1.8):

  • Добавлен режим для снижения мерцаний при смене изображений/иконок, особенно заметно в Windows XP (см. пример 6).
  • Добавлено много недокументированных (внутренних) функций (см. примеры 5, 6, 7), так же переименованы все предыдущие внутренние функции.
  • Добавлена возможность удаления изображения/ионки из контрола, причем размеры контрола сохраняются (если возможно).
  • Добавлено несколько новых примеров.
  • Обеспечена совместимость с библиотекой GUICtrlSetOnHover от CreatoR'а.
  • Улучшена производительность всех функций.
  • Изменены заголовки для основных функций (см. описания внутри библиотеки).
  • Полностью переписан код библиотеки.
  • Исправлена ошибка в функции _SetCombineBkIcon(), связанная с определением цвета окна, если оно является невидимым.
  • Исправлено несколько внутренних ошибок.
 

ynbIpb

Скриптер
Сообщения
399
Репутация
110
Отличная UDF!
Хочу приспособить её использование для создания собственного скина окна из PNG файлов (так как в PNG можно варьировать уровень прозрачности)
В итоге не могу добиться чтобы бэкграунд окна был абсолютно прозрачным.
Получается вот что:
94146378.png

Игрался со стилями, не помогает.
Код:
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Icons.au3>

$sPngLeft = @ScriptDir & "\Left.png"
$sPngCenter = @ScriptDir & "\Center.png"
$sPngRight = @ScriptDir & "\Right.png"
$sPngTitle = @ScriptDir & "\Title.png"
$Form1 = GUICreate("Form1", 500, 400, -1, -1, $WS_POPUP, $WS_EX_LAYERED)
$Pic1 = GUICtrlCreatePic("", 0, 0, 32, 38)
$Pic2 = GUICtrlCreatePic("", 186, 0, 128, 38)
$Pic3 = GUICtrlCreatePic("", 468, 0, 32, 38)
$Pic4 = GUICtrlCreatePic("", 32, 0, 154, 38)
$Pic5 = GUICtrlCreatePic("", 314, 0, 154, 38)

_SetImage($Pic1, $sPngLeft)
_SetImage($Pic2, $sPngCenter)
_SetImage($Pic3, $sPngRight)
_SetImage($Pic4, $sPngTitle)
_SetImage($Pic5, $sPngTitle)
GUISetState(@SW_SHOW)

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit

	EndSwitch
WEnd

Вычитал, что нужно добавить в код следущее:
GUISetBkColor (0xFF00FF, $Form1)
_WinAPI_SetLayeredWindowAttributes($Form1, 0xFF00FF, 255)

Тоесть задать уникальный цвет бэкгроунду и сделать его прозрачным.
В результате фон стал прозрачным, но проявился другой баг: там где в PNG файле прозрачность плавно переходит от менее прозрачного к абсолютному проявляется тот самый уникальный цвет.
Как быть?
87510215.png
 

ynbIpb

Скриптер
Сообщения
399
Репутация
110
Спасибо за примеры, но это всётаки немного не то.
Мне необходимо составить свой скин именно из кусочков контролов Pic
Так как мне необходимо менять размер окна и скин будет растягиваться в некоторых местах.
В частности элемент $Pic4 и $Pic5
 

ynbIpb

Скриптер
Сообщения
399
Репутация
110
UP!
Хочу использовать функцию _SetHImage, для установки картинок на контролы.
Там есть такой параметр : $hBitmap - The handle to a bitmap (HBitmap).
Как мне создать такой $hBitmap, если моё изображение формата *.BMP хранится в бинароном виде, типа: Binary ("0x00...") в самом коде скрипта.
Спасибо.
 

StepanSkvortsov

Новичок
Сообщения
9
Репутация
0
А можно как то скачать удфку не с оф.форума? А то что как то не могу никак пройти антироботную проверку, что бы зарегистрироваться на буржуйском форуме автоита... :(
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
StepanSkvortsov,
Предупреждение За нарушение общих правил (пункт В.8):
Так как эта конференция называется "Русское сообщество AutoIt", язык общения на ней - Русский. Названия фирм или программных продуктов, аббревиатуры и т.д. должны быть написаны так, как они пишутся в оригинале, например не следует писать УСБ вместо USB. На форуме крайне не рекомендуется намеренно искажать русский язык и использовать "сетевой жаргон" на подобии "Аффтар выпей йадау!".


С уважением, ваш Глобальный модератор.
 

mmsgeorge

Новичок
Сообщения
96
Репутация
0
Yashied
а как сделать, чтобы меньше мигала картинка при перемещении , добавлял $WS_CLIPCHILDREN + $WS_CLIPSIBLINGS, но тогда частично пропадает прозрачность, за то все плавно)
 

Stalevar

Новичок
Сообщения
31
Репутация
0
Выдает ошибку
"C:\Program Files (x86)\AutoIt3\Include\Icons.au3"(625,28) : warning: $ghGDIPDll: possibly used before declaration.

$Ret = DllCall($ghGDIPDll, 'int', 'GdipCreateBitmapFromHICON', 'ptr', $hIcon, 'ptr*', 0)

Код:
#Region
#AutoIt3Wrapper_Res_File_Add=CrashXP.bmp, 2, 200
#EndRegion

#Include <Icons.au3>
#Include <WinAPIEx.au3>

GUICreate("MyProg", 640, 480)
$Pic = GUICtrlCreatePic("", 0, 0, 640, 480)
$hInstance = _WinAPI_GetModuleHandle(0)
$hBitmap = _WinAPI_LoadBitmap($hInstance, 200)
_SetHImage($Pic, $hBitmap)
_WinAPI_DeleteObject($hBitmap)
GUISetState()

Do
Until GUIGetMsg() = -3
 
Верх