Jump to content

Recommended Posts

Posted

Hey, I don't know what is happening but It doesn't displays the PNG inside the button ctrl

#include <GDIPlus.au3>
#include <Memory.au3>
#include <WindowsConstants.au3>
#NoTrayIcon
Global Const $STM_SETIMAGE = 0x0172, $BM_SETIMAGE = 0xF7, $BS_BITMAP = 0x0080
Global $bico = "0x89504E470D0A1A0A0000000D49484452000000100000001008060000001FF3FF61000000017352474200AECE1CE" & _
        "90000000467414D410000B18F0BFC6105000000E249444154384F9D93B11183300C45198559E8E92929188B9E31684241E58" & _
        "CC0064E1A5AC74F67F9841B82B9D321E4AF6759C84D533CE7798ED1D668A1306263A9CFDF71B18DE634E9388ED0759D18BE81" & _
        "A1692FA094EC976509FBBE8B185F01F33C4B8C35E2D1F717083BDB84699A42DFF719804F4C8109E2A48A7466A1ABE0EEAD554" & _
        "A4F6CC3741776DC5E5BF8F8AF18BE5684C6F46305204DE29C2AD264E7DE01530895A141AB8D1540593209246A5C21A58EDC47" & _
        "8061182E9B6500E5D0D97F8F80D61E214F5D6D1319DDFADF9866A17E9012807B503FCA06527799ECCD7A7A9D7F919E81F9F48" & _
        "210970000000049454E44AE426082"

_GDIPlus_Startup()
$Form1 = GUICreate("Example", 300, 200, -1, -1, BitOR($WS_THICKFRAME,$WS_SYSMENU))

$btn = GUICtrlCreateButton("",130,70,32,32,$BS_BITMAP)
$hButton = GUICtrlGetHandle($btn)
$hHBITMAP = Load_BMP_From_Mem($bico, True)
_WinAPI_DeleteObject(_SendMessage($hButton, $BM_SETIMAGE, 0, $hHBITMAP))
_WinAPI_UpdateWindow($hButton)
_GDIPlus_Shutdown()
GUISetState()
    
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case -3
            GUIDelete()
            _WinAPI_DeleteObject($hHBITMAP)
            Exit
    EndSwitch
WEnd

;======================================================================================
; Function Name:        Load_BMP_From_Mem
; Description:          Loads a image which is saved as a binary string and converts it to a bitmap or hbitmap
;
; Parameters:           $mem_image:     the binary string which contains any valid image which is supported by GDI+
; Optional:                 $hHBITMAP:      if false a bitmap will be created, if true a hbitmap will be created
;
; Remark:                   hbitmap format is used generally for GUI internal images
;
; Requirement(s):       GDIPlus.au3, Memory.au3
; Return Value(s):  Success: handle to bitmap or hbitmap, Error: 0
; Error codes:          1: $mem_image is not a binary string
;
; Author(s):                UEZ
; Additional Code:  thanks to progandy for the MemGlobalAlloc and tVARIANT lines
; Version:                  v0.95 Build 2011-06-11 Beta
;=======================================================================================
Func Load_BMP_From_Mem($mem_image, $hHBITMAP = False)
    If Not IsBinary($mem_image) Then Return SetError(1, 0, 0)
    Local $declared = True
    If Not $__g_hGDIPDll Then
        _GDIPlus_Startup()
        $declared = False
    EndIf
    Local Const $memBitmap = Binary($mem_image) ;load image  saved in variable (memory) and convert it to binary
    Local Const $len = BinaryLen($memBitmap) ;get length of image
    Local Const $hData = _MemGlobalAlloc($len, $GMEM_MOVEABLE) ;allocates movable memory  ($GMEM_MOVEABLE = 0x0002)
    Local Const $pData = _MemGlobalLock($hData) ;translate the handle into a pointer
    Local $tMem = DllStructCreate("byte[" & $len & "]", $pData) ;create struct
    DllStructSetData($tMem, 1, $memBitmap) ;fill struct with image data
    _MemGlobalUnlock($hData) ;decrements the lock count  associated with a memory object that was allocated with GMEM_MOVEABLE
    Local $hStream = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "handle", $pData, "int", True, "ptr*", 0)
    $hStream = $hStream[3]
    Local $hBitmap = DllCall($__g_hGDIPDll, "uint", "GdipCreateBitmapFromStream", "ptr", $hStream, "int*", 0) ;Creates a Bitmap object based on an IStream COM interface
    $hBitmap = $hBitmap[2]
    Local Const $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
    DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "dword", 8 + 8 * @AutoItX64, _
            "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT)) ;release memory from $hStream to avoid memory leak
    $tMem = 0
    If $hHBITMAP Then
        Local Const $hHBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        _GDIPlus_BitmapDispose($hBitmap)
        If Not $declared Then _GDIPlus_Shutdown()
        Return $hHBmp
    EndIf
    If Not $declared Then _GDIPlus_Shutdown()
    Return $hBitmap
EndFunc   ;==>Load_BMP_From_Mem
I guess this worked before :s

Heroes, there is no such thing

One day I'll discover what IE.au3 has of special for so many users using it.
C'mon there's InetRead and WinHTTP, way better
happy.png

  • Solution
Posted

Try this:

#include <GDIPlus.au3>
#include <Memory.au3>
#include <WindowsConstants.au3>
#NoTrayIcon

Global Const $STM_SETIMAGE = 0x0172, $BM_SETIMAGE = 0xF7, $BS_BITMAP = 0x0080

Global $bico = "0x89504E470D0A1A0A0000000D49484452000000100000001008060000001FF3FF61000000017352474200AECE1CE" & _
        "90000000467414D410000B18F0BFC6105000000E249444154384F9D93B11183300C45198559E8E92929188B9E31684241E58" & _
        "CC0064E1A5AC74F67F9841B82B9D321E4AF6759C84D533CE7798ED1D668A1306263A9CFDF71B18DE634E9388ED0759D18BE81" & _
        "A1692FA094EC976509FBBE8B185F01F33C4B8C35E2D1F717083BDB84699A42DFF719804F4C8109E2A48A7466A1ABE0EEAD554" & _
        "A4F6CC3741776DC5E5BF8F8AF18BE5684C6F46305204DE29C2AD264E7DE01530895A141AB8D1540593209246A5C21A58EDC47" & _
        "8061182E9B6500E5D0D97F8F80D61E214F5D6D1319DDFADF9866A17E9012807B503FCA06527799ECCD7A7A9D7F919E81F9F48" & _
        "210970000000049454E44AE426082"

_GDIPlus_Startup()
$Form1 = GUICreate("Example", 300, 200, -1, -1, BitOR($WS_THICKFRAME,$WS_SYSMENU))
$btn = GUICtrlCreateButton("",130,70,32,32,$BS_BITMAP)
$hButton = GUICtrlGetHandle($btn)
$hHBITMAP = _GDIPlus_BitmapCreateFromMemory(Binary($bico), True)
_WinAPI_DeleteObject(_SendMessage($hButton, $BM_SETIMAGE, 0, $hHBITMAP))
_GDIPlus_Shutdown()
GUISetState()

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case -3
            GUIDelete()
            _WinAPI_DeleteObject($hHBITMAP)
            Exit
    EndSwitch
WEnd

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted

This is very useful and clear.  But how can that same bitmap graphic be placed directly on the GUI (i.e., not on a button)?

I've tried this without success:

$hHBITMAP = _GDIPlus_BitmapCreateFromMemory(Binary($bico), True)
;
$pic = GUICtrlCreatePic("", 130, 130, 32, 32, $BS_BITMAP)
$hPic = GUICtrlGetHandle($pic)
_SendMessage($hPic, $BM_SETIMAGE, 0, $hHBITMAP)
;
_WinAPI_DeleteObject(_SendMessage($hButton, $BM_SETIMAGE, 0, $hHBITMAP))
Posted (edited)

Thank you UEZ :D

Didn't knew about the _GDIPlus_BitmapCreateFromMemory :sweating: 

 

It is the same function as Load_BMP_From_Mem but integrated as _GDIPlus_BitmapCreateFromMemory now n GDIPlus.au3.

 

 

This is very useful and clear.  But how can that same bitmap graphic be placed directly on the GUI (i.e., not on a button)?

I've tried this without success:

$hHBITMAP = _GDIPlus_BitmapCreateFromMemory(Binary($bico), True)
;
$pic = GUICtrlCreatePic("", 130, 130, 32, 32, $BS_BITMAP)
$hPic = GUICtrlGetHandle($pic)
_SendMessage($hPic, $BM_SETIMAGE, 0, $hHBITMAP)
;
_WinAPI_DeleteObject(_SendMessage($hButton, $BM_SETIMAGE, 0, $hHBITMAP))

 

For picture control you have to use this:

Global Const $STM_SETIMAGE = 0x0172
$hHBITMAP = _GDIPlus_BitmapCreateFromMemory(Binary($bico), True)
;
$pic = GUICtrlCreatePic("", 130, 130, 32, 32, $BS_BITMAP)

_WinAPI_DeleteObject(GUICtrlSendMsg($pic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBITMAP))
Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted

Yes, thanks, UEZ!   GUICtrlSendMessage works.

But, is there any short explanation as to why _SendMessage can't send to a Pic, but can to a Button?  What is the basis for having different send messages functions?

I'm only looking for a general understanding to help me navigate this sort of thing.

Posted (edited)

Well, you can use also _SendMessage() but I'm using mostly GUICtrlSendMsg to send a GDI bitmap to the control.

 

#include <GDIPlus.au3>
#include <Memory.au3>
#include <WindowsConstants.au3>
#NoTrayIcon

Global Const $STM_SETIMAGE = 0x0172, $BM_SETIMAGE = 0xF7, $BS_BITMAP = 0x0080

Global $bico = "0x89504E470D0A1A0A0000000D49484452000000100000001008060000001FF3FF61000000017352474200AECE1CE" & _
        "90000000467414D410000B18F0BFC6105000000E249444154384F9D93B11183300C45198559E8E92929188B9E31684241E58" & _
        "CC0064E1A5AC74F67F9841B82B9D321E4AF6759C84D533CE7798ED1D668A1306263A9CFDF71B18DE634E9388ED0759D18BE81" & _
        "A1692FA094EC976509FBBE8B185F01F33C4B8C35E2D1F717083BDB84699A42DFF719804F4C8109E2A48A7466A1ABE0EEAD554" & _
        "A4F6CC3741776DC5E5BF8F8AF18BE5684C6F46305204DE29C2AD264E7DE01530895A141AB8D1540593209246A5C21A58EDC47" & _
        "8061182E9B6500E5D0D97F8F80D61E214F5D6D1319DDFADF9866A17E9012807B503FCA06527799ECCD7A7A9D7F919E81F9F48" & _
        "210970000000049454E44AE426082"

_GDIPlus_Startup()
$Form1 = GUICreate("Example", 300, 200, -1, -1, BitOR($WS_THICKFRAME,$WS_SYSMENU))
$btn = GUICtrlCreateButton("",130,70,32,32,$BS_BITMAP)
$hButton = GUICtrlGetHandle($btn)
$hHBITMAP = _GDIPlus_BitmapCreateFromMemory(Binary($bico), True)
_WinAPI_DeleteObject(_SendMessage($hButton, $BM_SETIMAGE, 0, $hHBITMAP))

$pic = GUICtrlCreatePic("",90,78,16,16,$BS_BITMAP)
$hPic = GUICtrlGetHandle($pic)
_WinAPI_DeleteObject(_SendMessage($hPic, 0x0172, 0, $hHBITMAP))

_GDIPlus_Shutdown()
GUISetState()

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case -3
            GUIDelete()
            _WinAPI_DeleteObject($hHBITMAP)
            Exit
    EndSwitch
WEnd

#cs
GUICtrlSendMsg ( controlID, msg , wParam, lParam )

Func _SendMessage($hWnd, $iMsg, $wParam = 0, $lParam = 0, $iReturn = 0, $wParamType = "wparam", $lParamType = "lparam", $sReturnType = "lresult")
    Local $aResult = DllCall("user32.dll", $sReturnType, "SendMessageW", "hwnd", $hWnd, "uint", $iMsg, $wParamType, $wParam, $lParamType, $lParam)
    If @error Then Return SetError(@error, @extended, "")
    If $iReturn >= 0 And $iReturn <= 4 Then Return $aResult[$iReturn]
    Return $aResult
EndFunc   ;==>_SendMessage
#ce
 

But I cannot tell you the difference between _SendMessage and GUICtrlSendMsg because GUICtrlSendMsg is "hidden". Maybe a dev can answer this.

 

I assume it is more or less the same but _SendMessage has some more parameters which can be provided.

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted

Thanks for your reply.

That works equally well.  I looked up 0x0172 and saw that it's the code for $__STM_SETIMAGE.  Then I looked up SETIMAGE on msdn and found that the _SendMessage can set either an icon or a bitmap, depending on whether you provide a BITMAP or ICON image as the parameter.

 

That's about as far as I can afford to look into this right now.  I glad to have another way to use PNGs on GUIs.  But you may be onto something regarding GUICtrlSendMessage as a native function.  It would be nice to know if it's the better choice if the extended params aren't needed.   Or is _SendMessage ("Wrapper for commonly used DLL Call") more efficient if you have the control handle?

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...