Jump to content

Transparent PNG issue?


Proph
 Share

Recommended Posts

I have been trying to use a transparent PNG in my gui.

It seemed that I had it working fine. But I notice that if another windows gains focus over my gui that my PNG will dissapear. I did find a support thread on the forum that seemed like it would help here:

But it does not work correctly either. When the PNG is first loaded with that code it loads the png in... but it is not at the desired location on the gui. Then if I right click and show my desktop... then bring my gui back into focus the png is then resized and placed into a different location.

My question is... does anyone have some code that allows you to use a transparent png file in your gui and it does not dissapear or any other unintended effects?

Thanks to anyone who can help me!

Edited by Proph
Link to comment
Share on other sites

Does anyone else get this problem when they test this code?

#include <GuiConstantsEX.au3>
#include <GDIPlus.au3>
#include "resources.au3"

_GDIPlus_Startup()

$hGui = GUICreate("show png", 350, 300)
$hPic = GUICtrlCreatePic("", 25, 25, 300, 200)
$Button = GUICtrlCreateButton("view", 130, 250, 75, 21)
GUISetState()


While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
ExitLoop
Case $Button
$OpenFile = FileOpenDialog("Select image file", "", "image(*.png)")
_GUICtrlStatic_SetPicture($OpenFile, $hPic)
EndSwitch
WEnd

FUnc _GUICtrlStatic_SetPicture($File, $CtrlId)
$hImage = _GDIPlus_ImageLoadFromFile($File)
$hScrDC = _WinAPI_GetDC(0)
$hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
GUICtrlSetImage($CtrlId, "")
_SetBitmapToCtrl($CtrlId, $hBitmap)
EndFUnc

 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

Just launch the code and grab a transparent png. It will look normal at first. But then if you show desktop then go back to this window you will notice your png is mesed up.

Edited by Proph
Link to comment
Share on other sites

Try this:

#include <GuiConstantsEX.au3>
#include <GDIPlus.au3>
;~ #include "resources.au3"

_GDIPlus_Startup()

$hGui = GUICreate("show png", 350, 300)
$hPic = GUICtrlCreatePic("", 25, 25)
$Button = GUICtrlCreateButton("view", 130, 250, 75, 21)
GUISetState()


While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
ExitLoop
Case $Button
$OpenFile = FileOpenDialog("Select image file", "", "image(*.png)")
_GUICtrlStatic_SetPicture($OpenFile, $hPic, $hGui)
EndSwitch
WEnd

Func _GUICtrlStatic_SetPicture($File, $CtrlId, $hGui)
$hImage = _GDIPlus_ImageLoadFromFile($File)
$hScrDC = _WinAPI_GetDC(0)
$hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
$aPos = ControlGetPos($hGui, "", $CtrlId)
GUICtrlSetPos($CtrlId, $aPos[0], $aPos[1], _GDIPlus_ImageGetWidth($hImage), _GDIPlus_ImageGetHeight($hImage))
GUICtrlSetImage($CtrlId, "")
_SetBitmapToCtrl($CtrlId, $hBitmap)
EndFUnc

 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

Br,

UEZ

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

It seems that this is working great when I am running Windows. But if I try to launch it from withing a Preinstallation Environment like BartPE or LiveXP none of the graphics show. Do you have any ideas as to why this may happen?

Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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