Что нового

[Элементы GUI] дополнение функции GUICtrlSetImage

ynbIpb

Скриптер
Сообщения
399
Репутация
110
Прошу поддержать мой тикет по дополнению функции GUICtrlSetImage.
Прозьба заключается в том, чтобы была возможность использовать не только файл картинки, но и бинарные данные этой картинки, которые заранее откуда-то считаны.
Например:
Сейчас функция использует файл картинки:
Код:
GUICtrlSetImage ($controlID, @ScriptDir & "\image.jpg")

А хотелось бы ещё и так:
Код:
$hImageFile = FileOpen (@ScriptDir & "\image.jpg", 16);binary mode
$bImageData = FileRead ($hImageFile) ; binary data
GUICtrlSetImage ( $controlID, $bImageData)

Я там конечно коряво изложил идею, может ктонибудь дополнит и лучше сформулирует запрос?
з.ы.
Я знаю, что существует самодельная функция, которая реализует эту идею, но хочется максимально упростить код. Так будет намного приятнее и удобнее.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,716
Существует определенная концепция GUI в AutoIt. Реализованы только базовые функции, все остальное - UDF. В противном случае нужно переписывать большинство функций GUI. На уровне API во все контролы "вставляются" bitmap'ы, а не двоичные данные. Если бы ты попросил реализацию HBITMAP и HICON, то я бы еще понял, а так, это вряд ли когда-нибудь будет сделано. Чем больше будет реализовано функций, тем сложнее и больше будет "компилятор", и следовательно, исполняемый файл. Оно надо? Только из-за спорной полезности данной возможности.

AutoIt issue tracker сказал(а):
Think about your feature request. If you can do it via UDFs, then don't ask for it to be built in. There's a reason you can create your own functions.

В любом случае, для реализации твоей просьбы, нужно подключать GDI+, на что, естественно разработчики вряд ли пойдут. Если тебе нужна подобная функция, то дай знать, я напишу ее и выложу здесь...
 
Автор
ynbIpb

ynbIpb

Скриптер
Сообщения
399
Репутация
110
Ситуация ясна.
Вобщем есть одна UDF с англ. форума. Скажи своё мнение, если можно ещё оптимизировать, то буду благодарен.

Код:
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

#include <WinAPI.au3>
#include <GDIPlus.au3>
#include <Memory.au3>

#include <BinaryImage.au3>

$Form1 = GUICreate("Form1", 134, 128)
$Pic1 = GUICtrlCreatePic("", 4, 4, 128, 102, BitOR($SS_NOTIFY,$WS_GROUP,$WS_CLIPSIBLINGS))
;GUICtrlSetImage ($Pic1, $sCarImage1)
$sCarImage1 = _CarImageBin()
_SetImageBinaryToCtrl($Pic1, $sCarImage1)
GUISetState(@SW_SHOW)

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

Func _CarImageBin ()
Dim $CarImage = '0xFFD8... тут бинарник'
Return $CarImage
EndFunc


UDF BinaryImage.au3
Код:
;Authors: [email protected], based on code by Zedna
Func _SetImageBinaryToCtrl($CtrlId, ByRef $Binary)
    Local $picdata = Binary($Binary) ; Fetch the Data
    Local $piclength = BinaryLen($picdata) ; Get Length

    Local $picstruct = DllStructCreate("byte[" & $piclength & "]")
        DllStructSetData($picstruct,1,$picdata)
        Local $picmemory = DllStructGetPtr($picstruct)
        _SetMemoryImageToCtrl($CtrlId, $picmemory, $piclength)
        DllStructSetData($picstruct,1,0)
    $picstruct = ""
EndFunc

; Authors: Zedna, based on code by [email protected]
Func _SetMemoryImageToCtrl($CtrlId, $Pointer, $nSize)
    Local $hData, $pData, $pStream, $pBitmap, $hBitmap
        ; use GDI+ for converting to bitmap first
    $hData = _MemGlobalAlloc($nSize,2)
    $pData = _MemGlobalLock($hData)
    _MemMoveMemory($Pointer,$pData,$nSize)
    _MemGlobalUnlock($hData)
    $pStream = DllCall( "ole32.dll","int","CreateStreamOnHGlobal", "int",$hData, "long",1, "Int*",0)
    $pStream = $pStream[3]
    _GDIPlus_Startup()
    $pBitmap = DllCall($ghGDIPDll,"int","GdipCreateBitmapFromStream", "ptr",$pStream, "int*",0)
    $pBitmap = $pBitmap[2]
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($pBitmap)
    _SetBitmapToCtrl($CtrlId, $hBitmap)
    If @error Then SetError(3, 0, 0)
    _GDIPlus_BitmapDispose($pBitmap)
    _GDIPlus_Shutdown()
    _WinAPI_DeleteObject($pStream)
    _MemGlobalFree($hData)
EndFunc

; internal helper function
; Out of resources.au3 :) 
Func _SetBitmapToCtrl($CtrlId, $hBitmap)
    Local Const $STM_SETIMAGE = 0x0172
    Local Const $IMAGE_BITMAP = 0
    Local Const $SS_BITMAP = 0xE
    Local Const $GWL_STYLE = -16

    Local $hWnd = GUICtrlGetHandle($CtrlId)
    If $hWnd = 0 Then Return SetError(1, 0, 0)
        ; set SS_BITMAP style to control
    Local $oldStyle = DllCall("user32.dll", "long", "GetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE)
    If @error Then Return SetError(2, 0, 0)
    DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE, "long", BitOR($oldStyle[0], $SS_BITMAP))
    If @error Then Return SetError(3, 0, 0)
        Local $oldBmp = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hWnd, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hBitmap)
    If @error Then Return SetError(4, 0, 0)
    If $oldBmp[0] <> 0 Then _WinAPI_DeleteObject($oldBmp[0])
    Return 1
EndFunc
 
Верх