Sign in to follow this  
Followers 0
qwert

How to put text label on floating PNG?

3 posts in this topic

I need to be able to place a label on top of a PNG graphic that is faded into view. The label doesn't necessarily have to fade in with the graphic, but it needs to have a transparent background so that it lays cleanly on the graphic.

The example below is derived from the launcher example on this forum. I've tried a dozen different variations of defining the label control and nothing has worked. I've trimmed this example down to the minimum elements.

Any suggestions will be appreciated. Thanks.

#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#Include <GDIPlus.au3>

$pngSrc = @WorkingDir & "\Splash.png"
_GDIPlus_Startup()
$hSplashImage = _GDIPlus_ImageLoadFromFile($pngSrc)

; Extract image width and height from PNG
$width = _GDIPlus_ImageGetWidth($hSplashImage)
$height = _GDIPlus_ImageGetHeight($hSplashImage)

; Create layered window
$SplashGUI = GUICreate("", $width, $height, -1, -1, $WS_POPUP, $WS_EX_LAYERED, $DS_MODALFRAME)
GUISetState()

; Add text on top of the graphic           <<<<<<<<<<<<<<<<<<<<<<<<<  THIS IS THE PROBLEM
GUICtrlCreateLabel("This is an overlaid label", 100, 200, 250, 50)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlSetColor(-1, 0xffffff)
GUISetState()
WinSetOnTop($SplashGUI, "", 1)

;fade in png image
For $i = 0 To 255 Step 10
      SetBitmap($SplashGUI, $hSplashImage, $i)
Next

While 1
    $msg = GUIGetMsg()
    Switch $msg
    Case $GUI_EVENT_CLOSE, $GUI_EVENT_PRIMARYDOWN, $GUI_EVENT_PRIMARYUP
    ExitLoop
  EndSwitch
Wend

; Release resources
_GDIPlus_ImageDispose($hSplashImage)
_GDIPlus_Shutdown()
GUIDelete($SplashGUI)
Exit

Func SetBitmap($hGUI, $hImage, $iOpacity)
Const $AC_SRC_ALPHA = 1
;Const $ULW_ALPHA = 2
Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend
local $hBrush, $hFormat, $hFamily, $hFont, $tLayout,$hGraphic
    $hScrDC = _WinAPI_GetDC(0)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
    $hGraphic = _GDIPlus_GraphicsCreateFromHDC ($hMemDC)

    $hBrush  = _GDIPlus_BrushCreateSolid (0xffFA0C0A)
    $hFormat = _GDIPlus_StringFormatCreate ()
    $hFamily = _GDIPlus_FontFamilyCreate ("Arial")
    $hFont   = _GDIPlus_FontCreate ($hFamily, 32, 1)
    $tLayout = _GDIPlus_RectFCreate ( 100, 200, 350, 50 )

    $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)
    _GDIPlus_FontDispose ($hFont)
    _GDIPlus_FontFamilyDispose ($hFamily)
   _GDIPlus_StringFormatDispose ($hFormat)
   _GDIPlus_BrushDispose ($hBrush)
EndFunc ;==>SetBitmap

post-29172-12492254693169_thumb.png

Share this post


Link to post
Share on other sites



Hi,

You can use the update layered window attributes to be able to add controls to it, but once you do the nice smooth fade effect your using will flicker slightly..

You'd also need to change the way the image is displayed once the window is at full trans.

ProgAndy wrote the function to set the layered window attributes and using the function makes it so you can have a fully transparent window with controls normally displayed.

Is the label needed as control to catch clicks?

If the label is just to put some text on only, then use the gdi draw font

(I notice your SetBitmap() function already had some of the gdi font code)..

#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#Include <GDIPlus.au3>
#include <WinAPI.au3>

Global $sFile = @ScriptDir & "\Splash.png"
Global $hGui, $iW, $iH, $hBmp

_GDIPlus_Startup()

$hImage1 = _GDIPlus_ImageLoadFromFile($sFile)
$iW = _GDIPlus_ImageGetWidth($hImage1)
$iH = _GDIPlus_ImageGetHeight($hImage1)

$hGUI = GUICreate("", $iW, $iH, -1, -1, $WS_POPUP, BitOr($WS_EX_LAYERED, $WS_EX_TOPMOST))
GUISetState()

;Add the text to a new image
$hBmp = _ImageDrawText($hImage1, "Text drawn on image", 100, 200, 0xFFFFFF)

;fade in png image
For $i = 0 To 255 Step 1
    SetBitmap($hGUI, $hBmp, $i)
Next
;Finished with the new text written image delete it
_WinAPI_DeleteObject($hBmp)
Sleep(2000)

;Since the original png is still open lets dribble some more text..
$hBmp = _ImageDrawText($hImage1, "Once upon a time....", 0, 0, 0xFF0000, 16, 2, "Impact")
SetBitmap($hGUI, $hBmp, 255)
_WinAPI_DeleteObject($hBmp)
Sleep(2000)

$hBmp = _ImageDrawText($hImage1, "Long long ago....", 0, 60, 0x00FF00, 16, 1, "Tahoma")
SetBitmap($hGUI, $hBmp, 255)
_WinAPI_DeleteObject($hBmp)
Sleep(2000)

$hBmp = _ImageDrawText($hImage1, "When I was young and in my prime....", 0, 80, 0x0000FF, 9, 3, "Arial")
SetBitmap($hGUI, $hBmp, 255)
_WinAPI_DeleteObject($hBmp)
Sleep(2000)

$hBmp = _ImageDrawText($hImage1, "Wait....", 60, 120, 0x00FFFF, 20, 0, "Arial")
SetBitmap($hGUI, $hBmp, 255)
_WinAPI_DeleteObject($hBmp)
Sleep(2000)

$hBmp = _ImageDrawText($hImage1, "Scratch that part....", 20, 130, 0x00FF00, 12, 8, "Comic Sans MS")
SetBitmap($hGUI, $hBmp, 255)
_WinAPI_DeleteObject($hBmp)
Sleep(2000)

$hBmp = _ImageDrawText($hImage1, "To Be Continued...." & @LF & "NOT!", 50, 160, 0xFFFF00, 12, 4, "Impact")
SetBitmap($hGUI, $hBmp, 255)
_WinAPI_DeleteObject($hBmp)
Sleep(2000)

;set the original non texted png image back to the window
SetBitmap($hGUI, $hImage1, 255)

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE, $GUI_EVENT_PRIMARYDOWN, $GUI_EVENT_PRIMARYUP
            _GDIPlus_ImageDispose($hImage1)
            _GDIPlus_Shutdown()
            Exit
    EndSwitch
Wend

; $hImage = The handle to your open image file
; $sText = Sting of text to draw on the picture
; $iX = X postion the text will be drawn at
; $iY = Y position the text will be drawn at
; $iRGB = the RGB color to draw the text (0x000000 to 0xffffff)
; $iSize = The size of the font
; $iStyle = 0 None (Default)
;           1 Bold
;           2 Italic
;           4 Underline
;           8 Strikethrough
;           (Add together for combination, eg: 3 = Bold + Italic)
; $sFont = Name of font to use
Func _ImageDrawText($hImage, $sText, $iX = 0, $iY = 0, $iRGB = 0x000000, $iSize = 9, $iStyle = 0, $sFont = "Arial") 
    Local $w, $h, $hGraphic1, $hBitmap, $hGraphic2, $hBrush, $hFormat, $hFamily, $hFont, $tLayout, $aInfo
    $w = _GDIPlus_ImageGetWidth($hImage)
    $h = _GDIPlus_ImageGetHeight($hImage)
    
    ;Create a new bitmap, this way the original opened png is left unchanged
    $hGraphic1 = _GDIPlus_GraphicsCreateFromHWND(_WinAPI_GetDesktopWindow())
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($w, $h, $hGraphic1)
    $hGraphic2 = _GDIPlus_ImageGetGraphicsContext($hBitmap) 
    
    ; Draw the original opened png into my newly created bitmap
    _GDIPlus_GraphicsDrawImageRect($hGraphic2, $hImage, 0, 0, $w, $h)

    ;Create the font
    $hBrush = _GDIPlus_BrushCreateSolid ("0xFF" & Hex($iRGB, 6))
    $hFormat = _GDIPlus_StringFormatCreate()
    $hFamily = _GDIPlus_FontFamilyCreate ($sFont)
    $hFont = _GDIPlus_FontCreate ($hFamily, $iSize, $iStyle)
    $tLayout = _GDIPlus_RectFCreate ($iX, $iY, 0, 0)
    $aInfo = _GDIPlus_GraphicsMeasureString ($hGraphic2, $sText, $hFont, $tLayout, $hFormat)
    
    ;Draw the font onto the new bitmap
    _GDIPlus_GraphicsDrawStringEx ($hGraphic2, $sText, $hFont, $aInfo[0], $hFormat, $hBrush)
    
    ;Cleanup the no longer needed resources
    _GDIPlus_FontDispose ($hFont)
    _GDIPlus_FontFamilyDispose ($hFamily)
    _GDIPlus_StringFormatDispose ($hFormat)
    _GDIPlus_BrushDispose ($hBrush)
    _GDIPlus_GraphicsDispose ($hGraphic2)
    _GDIPlus_GraphicsDispose ($hGraphic1)

    ;Return the new bitmap
    Return $hBitmap
EndFunc 
    
Func SetBitmap($hGUI, $hImage, $iOpacity)
    Local Const $AC_SRC_ALPHA = 1
    Local Const $ULW_ALPHA = 2
    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

Share this post


Link to post
Share on other sites

Smashly, that is an excellent solution:

$hBmp = _ImageDrawText($hImage1, "Text drawn on image", 100, 200, 0xFFFFFF)

It's a function I had never found. The capability to update the text is very cool and opens up some new possibilities for my application. (BTW, I don't need the text field to catch controls.)

Thanks very much for your assistance. Anyone looking to work with popup graphics will do well to explore your excellent example of what can be done.

Share this post


Link to post
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
Sign in to follow this  
Followers 0