Jump to content

TRANSPARENT PNG BUTTONS W/ ROLLOVER


Recommended Posts

I have been working on this for weeks... lol. I feel I have made good progress with the resources at hand but just can not get a few effects I want.

Posted Image

OK, I hope not ask to many questions at once but...

1. Is it possible to load a PNG and have semi-tranparency?

I would like to be able to have the exit button be red but yet transparent (Vista style), however when I create a PNG with layers not at full opacity

(Transparent) the difference is painted with the color of the image I am using for transparency. I have tried adding more child GUIs and painting with

GDI+ to them yet I am still getting the same result. Set the variable $BAD_EXAMPLE to 1 to see the problem I am talking about.

NOTES: Full opacity of an area in am image works fine.

Using the same color as the image for transparency not only is drawn transparent but work as an eraser for anything drawn with GDI+.

I have not tried this with a "Normal GUI window", it should work except you will need to "erase" a graphic before drawing to the same area

or you will layer the images on top of one another. You may be able to use a label to "erase" the graphic, not sure.

2. So far I have only been able to Draw to the GUI with GDI+ after the GUI is shown. Is it possible draw the graphics and then show the GUI (or a good

work around)? It is not so much a problem until you have many images to be drawn, the delay look terrible. [EDIT] I think that this can be accomplished using

the guictrlcreatepic example #3 in the help file. It is a work around to repaint the image to the GUI before showing by Zedna, however (1) I am not sure how

to use this for multiple images, (yet) and (2) it is not truly a control. It really does not matter its not a control though.

3. I know I am loading the file once and painting it several times on rollovers. Is this a memory leak? Am I using more resources each time the image is

painted or once its loaded thats it?

4. How can I get the current style of the users settings? (Ex. Windows Classic Style / Windows XP Style) See FYI

FYI:

I am posting the code for the script for quick viewing but you need to download the .zip as it includes all the graphics. I have not included any error handling

(Ex. FileExists) so if you remove or rename images you must modified the code to correspond (duh) or you may have unexpected results with no warnings.

If you end up with results like the following image adjust the $LAYERED_GUI_CORRECTION variable.

The problem below has been fixed thanks to MARTIN and his GetVertOffset function. Thanks Martin! Basically layered windows are not at the same vertical location, it is the difference of the title bar. In this case, using Lod3ns PNG GUI there is transparent padding to get the controls to the top of the GUI so I added 25 to the returned value of Martins function. Soooo, no matter what appearance you are using Windows Classic, XP, Media Center, ect. the controls should lay in the correct position.

Posted Image

;THIS IS AN ATTEMPT AT TRANSPARENT PNG BUTTONS
;WITH DIFFERENT LEVELS OF TRANSPARENCY
;BY Justin Meyer

;THE SETBITMAP FUNCTION TO CREATE A PNG GUI IS FROM LOD3N (LAUNCHER) AND CAN BE FOUND HERE \/ \/ \/
;http://www.autoitscript.com/forum/index.php?showtopic=47651&hl=LOD3N+LAUNCHER

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>

;SET TO 1 TO SEE THE BAD EXAMPLE - TRANPARENT PICTURE COLOR
$BAD_EXAMPLE = 1

;VERTICAL OFFSET FIXED BY GetVertOffset FUNCTION, THANKS MARTIN!

Global Const $AC_SRC_ALPHA = 1
;Global Const $ULW_ALPHA = 2

_GDIPLUS_Startup()
$EXIT_NORM = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\EXIT\1.PNG")
$EXIT_OVER = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\EXIT\2.PNG")
$MIN_NORM = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\MIN\1.PNG")
$MIN_OVER = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\MIN\2.PNG")

If $BAD_EXAMPLE = 1 Then
    $BAD_1_PNG = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\BAD(1).PNG")
    $BAD_2_PNG = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\BAD(2).PNG")
    $ERASER = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\ERASER.GIF")
EndIf

$PNG_LOAD = _GDIPLUS_ImageLoadFromFile(@ScriptDir & "\BG.PNG")

$GUI = GUICreate("GREAT GUI", 300, 250, -1, -1, $WS_POPUP, $WS_EX_LAYERED)
SetBitMap($GUI, $PNG_LOAD, 255)
GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")
GUISetState(@SW_SHOW,$GUI)

$LAYERED_GUI_CORRECTION = GetVertOffset($GUI)

$CONTROL_GUI = GUICreate("CONTROL_GUI", 300, 250, 0, $LAYERED_GUI_CORRECTION,$WS_POPUP,BitOR($WS_EX_LAYERED,$WS_EX_MDICHILD),$GUI)

$EXIT_AREA = GUICtrlCreateLabel("", 242, 3, 45, 20)
$MIN_AREA = GUICtrlCreateLabel("", 217, 3, 25, 20)

If $BAD_EXAMPLE = 1 Then
    $BAD_AREA = GUICtrlCreateLabel("", 82, 55, 128, 128)
EndIf

;THE COLOR OF THIS IMAGE SETS THE COLOR FOR TRANSPARENCY - OR ERASER(?)
$TRANS_PIC = GUICtrlCreatePic(@ScriptDir & "\TRANS.GIF",0,0,300,250)
GuiCtrlSetState($TRANS_PIC,$GUI_DISABLE)

$STATUS_LABEL_1 = GUICtrlCreateInput("$STATUS_LABEL_1",8,205,278,15,-1,$WS_EX_WINDOWEDGE)
GUICtrlSetColor(-1,0xFFFFFF)
GUICtrlSetBkColor($STATUS_LABEL_1,000000)
GUICtrlSetFont($STATUS_LABEL_1,8)
GUICtrlSetState($STATUS_LABEL_1,$GUI_DISABLE)

GUISetState(@SW_SHOW,$CONTROL_GUI)

$ZEROGraphic = _GDIPlus_GraphicsCreateFromHWND($CONTROL_GUI)

$EXIT_BUTTON = _GDIPlus_GraphicsDrawImageRectRect ($ZEROGraphic, $EXIT_NORM, 0, 0, 45, 20, 242, 3, 45, 20)
$MIN_BUTTON = _GDIPlus_GraphicsDrawImageRectRect ($ZEROGraphic, $MIN_NORM, 0, 0, 25, 20, 217, 3, 25, 20)

If $BAD_EXAMPLE = 1 Then
    $DRAW_BAD_PNG = _GDIPlus_GraphicsDrawImageRectRect ($ZEROGraphic, $BAD_1_PNG, 0, 0, 128, 128, 82, 55, 128, 128)
EndIf

While 1
    $MSG = GUIGetMsg(1)
    If $MSG = -3 then Exit
    $GCI_DN = GUIGetCursorInfo($CONTROL_GUI)
        Select
            Case $MSG[0] = $GUI_EVENT_CLOSE
                If $MSG[1] = $GUI Then
                    ExitLoop
                EndIf
                If $MSG[1] = $CONTROL_GUI Then
                    ExitLoop
                EndIf
            ;THE GRAPHICS DRAWN HAVE TO BE REPAINTED AFTER MINIMIZING, THERE OTHER ISSUES SUCH AS MsgBox
            Case $GUI_EVENT_RESTORE
                $EXIT_BUTTON = _GDIPlus_GraphicsDrawImageRectRect ($ZEROGraphic, $EXIT_NORM, 0, 0, 45, 20, 242, 3, 45, 20)
                $MIN_BUTTON = _GDIPlus_GraphicsDrawImageRectRect ($ZEROGraphic, $MIN_NORM, 0, 0, 25, 20, 217, 3, 25, 20)
        EndSelect
    If $BAD_EXAMPLE = 1 Then
        If $GCI_DN[4] = $BAD_AREA Then
            $DRAW_BAD_PNG = _GDIPlus_GraphicsDrawImageRectRect ($ZEROGraphic, $ERASER, 0, 0, 50, 50, 82, 55, 128, 128)
            $DRAW_BAD_PNG = _GDIPlus_GraphicsDrawImageRectRect ($ZEROGraphic, $BAD_2_PNG, 0, 0, 128, 128, 82, 55, 128, 128)
            GUICtrlSetData($STATUS_LABEL_1,"BAD TRANSPARENCY EFFECT")
            $GCI_DN = GUIGetCursorInfo($CONTROL_GUI)
            While $GCI_DN[4] = $BAD_AREA
                If GUIGetMsg() = $BAD_AREA Then GUICtrlSetData($STATUS_LABEL_1,"LEFT CLICKED IN AREA")
                $GCI_DN = GUIGetCursorInfo($CONTROL_GUI)
            WEnd
            $DRAW_BAD_PNG = _GDIPlus_GraphicsDrawImageRectRect ($ZEROGraphic, $ERASER, 0, 0, 50, 50, 82, 55, 128, 128)
            $DRAW_BAD_PNG = _GDIPlus_GraphicsDrawImageRectRect ($ZEROGraphic, $BAD_1_PNG, 0, 0, 128, 128, 82, 55, 128, 128)
            GUICtrlSetData($STATUS_LABEL_1,"")
        EndIf
    EndIf
    If $GCI_DN[4] = $EXIT_AREA Then
        $EXIT_BUTTON = _GDIPlus_GraphicsDrawImageRectRect ($ZEROGraphic, $EXIT_OVER, 0, 0, 45, 20, 242, 3, 45, 20)
        GUICtrlSetData($STATUS_LABEL_1,"EXIT GREAT GUI?")
        $GCI_DN = GUIGetCursorInfo($CONTROL_GUI)
            While $GCI_DN[4] = $EXIT_AREA
                If GUIGetMsg() = $EXIT_AREA Then ExitLoop(2)
                $GCI_DN = GUIGetCursorInfo($CONTROL_GUI)
            WEnd
        $EXIT_BUTTON = _GDIPlus_GraphicsDrawImageRectRect ($ZEROGraphic, $EXIT_NORM, 0, 0, 45, 20, 242, 3, 45, 20)
        GUICtrlSetData($STATUS_LABEL_1,"")
    EndIf
    If $GCI_DN[4] = $MIN_AREA Then
        $MIN_BUTTON = _GDIPlus_GraphicsDrawImageRectRect ($ZEROGraphic, $MIN_OVER, 0, 0, 25, 20, 217, 3, 25, 20)
        GUICtrlSetData($STATUS_LABEL_1,"MINIMIZE GREAT GUI?")
        $GCI_DN = GUIGetCursorInfo($CONTROL_GUI)
            While $GCI_DN[4] = $MIN_AREA
                If GUIGetMsg() = $MIN_AREA Then
                    GUISetState(@SW_MINIMIZE,$GUI)
                EndIf
                $GCI_DN = GUIGetCursorInfo($CONTROL_GUI)
            WEnd
        $MIN_BUTTON = _GDIPlus_GraphicsDrawImageRectRect ($ZEROGraphic, $MIN_NORM, 0, 0, 25, 20, 217, 3, 25, 20)
        GUICtrlSetData($STATUS_LABEL_1,"")
    EndIf
WEnd

GUIDelete($CONTROL_GUI)
GUIDelete($GUI)

_GDIPlus_GraphicsDispose($ZEROGraphic)

_GDIPlus_ImageDispose($EXIT_NORM)
_GDIPlus_ImageDispose($EXIT_OVER)
_GDIPlus_ImageDispose($MIN_NORM)
_GDIPlus_ImageDispose($MIN_OVER)
_GDIPlus_ImageDispose($PNG_LOAD)

If $BAD_EXAMPLE = 1 Then
    _GDIPlus_ImageDispose($BAD_1_PNG)
    _GDIPlus_ImageDispose($BAD_2_PNG)
    _GDIPlus_ImageDispose($ERASER)
EndIf

_GDIPLUS_Shutdown()

Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
  if ($hWnd = $GUI) and ($iMsg = $WM_NCHITTEST) then Return $HTCAPTION
EndFunc

Func SetBitmap($hGUI, $hImage, $iOpacity)
    Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend

    $hScrDC = _WinAPI_GetDC(0)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage))
    DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage))
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA)
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hMemDC)
EndFunc   ;==>SetBitmap

Func GetVertOffset($hgui)
;Const $SM_CYCAPTION = 4
    Const $SM_CXFIXEDFRAME = 7
    Local $wtitle, $wclient, $wsize,$wside,$ans
    $wclient = WinGetClientSize($hgui)
    $wsize = WinGetPos($hgui)
    $wtitle = DllCall('user32.dll', 'int', 'GetSystemMetrics', 'int', $SM_CYCAPTION)
    $wside = DllCall('user32.dll', 'int', 'GetSystemMetrics', 'int', $SM_CXFIXEDFRAME)
    $ans = $wsize[3] - $wclient[1] - $wtitle[0] - 2 * $wside[0] +25
    Return $ans
EndFunc  ;==>GetVertOffset

Thanks to Lod3n for inspiring great looking GUIs! LOD3N LAUNCHER

Please take a look and tell me what you think, comments suggestions and solutions, thanks.

Old example was downloaded 32 times, lol.

PNG_BUTTON.zip

Edited by JMeyer
Link to comment
Share on other sites

I am still searching for solutions ... Today I was on MSDN and came across "Using Color Matrix to Set Alpha Value", is this possible in autoit? I have not found anything in the help file, well anything that I understand. I think that this may solve my problem or at least get me closer.

And I came across another issue this afternoon...

On my laptop this is what the GUI looks like after loading (rollovers and buttons work fine)...

Posted Image

but only a second or two after I move the GUI this happens...

Posted Image

I assume it is a hardware issue as I have not had it happen on any other machines... yet.

Just some specs:

Link to comment
Share on other sites

Got the latest Direct X, and I have had many problems getting and update for my video card. My laptop is an Averatec 2300 w/ nVIDIA GeForce Go 6100 graphics. I can not download the driver from nVIDIA because they say I have to download it from Averatec. Unfortunately the last time it was updated was 9/13/06.

But thanks

Link to comment
Share on other sites

Thanks for the link, never seen that before. It seemed like a good idea until it crashed my system 3 times!

fyi, it is an Averatec 2300

The "Nvidia GeForce Go 6100" is listed on the website so it should work. I have never had a laptop with Nvidia so I can't really help further.
Link to comment
Share on other sites

  • 2 weeks later...

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...