timmy2

Is it possible to have a transparent BG when employing GDIPlus ?

7 posts in this topic

The following script lets me display text against a transparent background.

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

Global $hGui = GUICreate("", 400, 300, -1, -1, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED))
GUISetBkColor(0xF1F1F1)

Global $sString = "Testing 123" & @CRLF & "I've got info for you." & @CRLF & @CRLF & "Last line of text."

GUICtrlCreateLabel($sString, 50, 50, 400, 300, -1, $GUI_WS_EX_PARENTDRAG)

_WinAPI_SetLayeredWindowAttributes($hGui, 0xF1F1F1, 255)
GUISetState(@SW_SHOW, $hGui)

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
Exit 0 * GUIDelete($hGui)

 

Forum_Example_of_transparent_popup.png

 

I'm hoping to apply what I learned from it to creating a transparent background in the following script, which allows me to choose the font, size, and color of the text (and sequence seamlessly through a series of text messages).

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <GUIConstants.au3>

HotKeySet("{Esc}", Close)

Local $hGUI, $hGraphic, $hBrush, $hFormat, $hFamily, $hFont, $tLayout
Local $iString = 0
Local $aStrings[3] = ["Testing 123" & @CRLF & "I've got info for you" & @CRLF & @CRLF & "And that is not all!", _
        "Another page" & @CRLF & "this is more text." & @CRLF & "More to come.", _
        "The last page" & @CRLF & @CRLF & "this is more text." & @CRLF & "And that IS all."]

; Create GUI
$hGUI = GUICreate("", 400, 300, -1, -1, $WS_POPUP)
GUISetBkColor(0xFF000000) ; will change background color
GUISetState(@SW_SHOW)

; Draw a string
_GDIPlus_Startup()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics(400, 300, $hGraphic)
Local $hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
$hBrush = _GDIPlus_BrushCreateSolid(0xFF99ff33)
$hFormat = _GDIPlus_StringFormatCreate()
$hFamily = _GDIPlus_FontFamilyCreate("Arial")
$hFont = _GDIPlus_FontCreate($hFamily, 20, 0)
$tLayout = _GDIPlus_RectFCreate(50, 50, 0, 0)

While (True)
    Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $aStrings[$iString], $hFont, $tLayout, $hFormat)
    _GDIPlus_GraphicsClear($hBuffer)
    _GDIPlus_GraphicsDrawStringEx($hBuffer, $aStrings[$iString], $hFont, $aInfo[0], $hFormat, $hBrush)
    _GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap, 0, 0)
    Sleep(1000)
    $iString += 1
    If ($iString > 2) Then $iString = 0
WEnd


; Clean up resources

Func Close()
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
EndFunc   ;==>Close

 

Is a transparent background possible when employing GDIPlus to display text?

 

Share this post


Link to post
Share on other sites



It most certainly is....but I'm not a GDI+ expert.  I know it possible though because the Clock example included with AutoIt (.\Examples\GUI\Advanced\Clock.su3) does just that.  I think the magic happens in the ResourceInit function (detached/GUI-less GDI+ Init)..but I'm not positive.  Also, the AlphaBlend example shows how to use PNG images with a transparent background which are also move-able.  Might be worth a look.

Share this post


Link to post
Share on other sites

Sure.

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

Global Const $SC_DRAGMOVE = 0xF012
Global $iW = 300, $iH = 100, $hHBitmap
Global $hGUI = GUICreate("Parent", $iW, $iH, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST))
GUISetState(@SW_SHOW, $hGUI)

_GDIPlus_Startup()

Global $hBrush = _GDIPlus_BrushCreateSolid(0xD80000A0)
Global $hFormat = _GDIPlus_StringFormatCreate()
Global $hFamily = _GDIPlus_FontFamilyCreate("Impact")
Global $hFont = _GDIPlus_FontCreate($hFamily, 60)
Global $tLayout = _GDIPlus_RectFCreate(0, 0, $iW, $iH)
_GDIPlus_StringFormatSetAlign($hFormat, 0)
Global $hImage = _GDIPlus_BitmapCreateFromScan0($iW, $iH)
Global $hGfx = _GDIPlus_ImageGetGraphicsContext($hImage)
_GDIPlus_GraphicsSetTextRenderingHint($hGfx, 4)
_GDIPlus_GraphicsSetSmoothingMode($hGfx, 4)

GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")

_ShowTime()
AdlibRegister("_ShowTime", 1000)

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

AdlibUnRegister("_ShowTime")
_WinAPI_DeleteObject($hHBitmap)
_GDIPlus_FontDispose($hFont)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_StringFormatDispose($hFormat)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hGfx)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()
GUIDelete()


Func _ShowTime()
    _GDIPlus_GraphicsClear($hGfx, 0x00000000)
    _GDIPlus_GraphicsDrawStringEx($hGfx, @HOUR & ":" & @MIN & ":" & @SEC, $hFont, $tLayout, $hFormat, $hBrush)
    $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    _WinAPI_BitmapDisplayTransparentInGUI($hHBitmap, $hGUI)
    _WinAPI_DeleteObject($hHBitmap)
EndFunc

Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True)
    If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0)
    Local $tDim = DllStructCreate($tagBITMAP)
    If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0)
    Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION)
    Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    $tSize.X = $tDim.bmWidth
    $tSize.Y = $tDim.bmHeight
    $tBlend.Alpha = $iOpacity
    $tBlend.Format = 1
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteDC($hMemDC)
    If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap)
    Return True
EndFunc

Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
    Switch $hWnd
        Case $hGUI
            _SendMessage($hWnd, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
    EndSwitch
EndFunc   ;==>_WM_LBUTTONDOWN

Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
    If ($iMsg = $WM_NCHITTEST) Then Return $HTCAPTION
EndFunc

 

1 person likes this

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!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

@UEZ: thanks for the fine example.

For anyone not accustomed to working with ARGB values, here's an example of what's possible:

Brush.PNG

 

 

Edited by qwert

Share this post


Link to post
Share on other sites

Thank you very much, @UEZ , for your example but I am having trouble figuring out which parts of your example are applicable to my script and goals.  I think what's tripping me up (besides understanding very little about GDIPlus) is your example contains a view commands that are not in my script (which surely came from some other post of yours), and vice versa.

Also, I decided I want to load the display text from a file (so I can easily change it) AND I want the text to "stream" onto the screen. There's also a graphic element involved. 

aniGif of tester (half-size).gif

Because I could not figure out how to superimpose my text over the screen in the graphic, I went with including the black background in my script, and removed the display area from the graphic (it's a PNG with an alpha channel). Even at that level of simplicity I'm having trouble, but that's for another post.

If you see this post and are willing to reply I would love to know how you would have made the script below generate text over a transparent background instead of the black background that's in it. 

#cs
Display a message one character at a time
with the goal of adding a PNG graphic overlay

#ce

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6


#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <GUIConstants.au3>

Global $sMessage
Global $iString = 0
Global $aInfo

HotKeySet("{Esc}","Close")

; in my actual script I read in a file containing all the text to be displayed

Global $sText = _
"Lorem ipsum dolor sit amet, consectetur" & @CRLF & _
"elit, sed do eiusmod tempor incididunt ut" & @CRLF & _
@CRLF & _
"Et dolore magna aliqua. Ut enim ad minim," & @CRLF & _
"quis nostrud exercitation ullamco laboris nisi" & @CRLF & _
"aliquip ex ea commodo consequat." & @CRLF & _
@CRLF & _
"Duis aute irure dolor in reprehenderit in" & @CRLF & _
"voluptate velit esse cillum dolore eu fugiat" & @CRLF & _
"nulla pariatur." & @CRLF

;MsgBox (1,"test", $sText)

; Create GUI

Global $hGUI = GUICreate("", 450, 340, -1, -1, $WS_POPUP)
; UEZ's example uses the following instead:
; Global $hGUI = GUICreate("Parent", $iW, $iH, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST)

GUISetBkColor(0xFF000000) ; will change background color, which UEZ doesn't use in his example, but then he doesn't want a BG

GUISetState(@SW_SHOW)

; Draw a string
_GDIPlus_Startup()
Global $hBrush = _GDIPlus_BrushCreateSolid(0xFF99ff33)
Global $hFormat = _GDIPlus_StringFormatCreate()
Global $hFamily = _GDIPlus_FontFamilyCreate("ARIAL")
Global $hFont = _GDIPlus_FontCreate($hFamily, 14, 0)
Global $tLayout = _GDIPlus_RectFCreate(20, 20, 0, 0)

Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)  ; not in UEZ's example
Global $hBitmap = _GDIPlus_BitmapCreateFromGraphics(420, 300, $hGraphic) ; UEZ used ..CreateFromScan0 (?)

Global $hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

; UEZ's Example used the following commands that are not in my script, and I cannot figure out which ones are
; applicable to my goal vs the goal of his example, which was to display a live digital clock

;  _GDIPlus_StringFormatSetAlign($hFormat, 0)
;  Global $hImage = _GDIPlus_BitmapCreateFromScan0($iW, $iH) ; must achieve something other than CreateFromHWND
;  _GDIPlus_GraphicsSetTextRenderingHint($hGfx, 4)
;  _GDIPlus_GraphicsSetSmoothingMode($hGfx, 4)


For $iString = 1 to StringLen($sText)
    $sMessage = StringLeft($sText,$iString)
    $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sMessage, $hFont, $tLayout, $hFormat)
    _GDIPlus_GraphicsClear($hBuffer)
    _GDIPlus_GraphicsDrawStringEx($hBuffer, $sMessage, $hFont, $aInfo[0], $hFormat, $hBrush)
    _GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap, 0, 0)
Next

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Close()

; Clean up resources (my best guess at what needs closing/shutting down)

Func Close()
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>Close

 

 

 

Share this post


Link to post
Share on other sites

Thank you also to @qwert and @spudw2k for their replies. I did try your suggestions.

Share this post


Link to post
Share on other sites

For this example without the bg image:

#cs
Display a message one character at a time
with the goal of adding a PNG graphic overlay

#ce

;~ #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6


#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <GUIConstants.au3>

Global $sMessage
Global $iString = 0
Global $aInfo

HotKeySet("{Esc}","Close")

; in my actual script I read in a file containing all the text to be displayed

Global $sText = _
"Lorem ipsum dolor sit amet, consectetur" & @CRLF & _
"elit, sed do eiusmod tempor incididunt ut" & @CRLF & _
@CRLF & _
"Et dolore magna aliqua. Ut enim ad minim," & @CRLF & _
"quis nostrud exercitation ullamco laboris nisi" & @CRLF & _
"aliquip ex ea commodo consequat." & @CRLF & _
@CRLF & _
"Duis aute irure dolor in reprehenderit in" & @CRLF & _
"voluptate velit esse cillum dolore eu fugiat" & @CRLF & _
"nulla pariatur." & @CRLF

;MsgBox (1,"test", $sText)

; Create GUI

Global $hGUI = GUICreate("", 450, 340, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST))
; UEZ's example uses the following instead:
; Global $hGUI = GUICreate("Parent", $iW, $iH, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST)

GUISetBkColor(0xFF000000) ; will change background color, which UEZ doesn't use in his example, but then he doesn't want a BG

GUISetState(@SW_SHOW)

; Draw a string
_GDIPlus_Startup()
Global $hBrush = _GDIPlus_BrushCreateSolid(0xFFA05033)
Global $hFormat = _GDIPlus_StringFormatCreate()
Global $hFamily = _GDIPlus_FontFamilyCreate("ARIAL")
Global $hFont = _GDIPlus_FontCreate($hFamily, 14, 0)
Global $tLayout = _GDIPlus_RectFCreate(20, 20, 0, 0)
Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
Global $hBitmap = _GDIPlus_BitmapCreateFromScan0(420, 300) ; UEZ used ..CreateFromScan0 (?)
Global $hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

; UEZ's Example used the following commands that are not in my script, and I cannot figure out which ones are
; applicable to my goal vs the goal of his example, which was to display a live digital clock

;  _GDIPlus_StringFormatSetAlign($hFormat, 0)
;  Global $hImage = _GDIPlus_BitmapCreateFromScan0($iW, $iH) ; must achieve something other than CreateFromHWND
  _GDIPlus_GraphicsSetTextRenderingHint($hBuffer, 4)
  _GDIPlus_GraphicsSetSmoothingMode($hBuffer, 4)


For $iString = 1 to StringLen($sText)
    $sMessage = StringLeft($sText,$iString)
    $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sMessage, $hFont, $tLayout, $hFormat)
    _GDIPlus_GraphicsClear($hBuffer, 0x000000)
    _GDIPlus_GraphicsDrawStringEx($hBuffer, $sMessage, $hFont, $aInfo[0], $hFormat, $hBrush)
    $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    _WinAPI_BitmapDisplayTransparentInGUI($hHBitmap, $hGUI)
    _WinAPI_DeleteObject($hHBitmap)
Next

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Close()

; Clean up resources (my best guess at what needs closing/shutting down)

Func Close()
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_ImageDispose($hBitmap)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>Close

Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True)
    If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0)
    Local $tDim = DllStructCreate($tagBITMAP)
    If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0)
    Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION)
    Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    $tSize.X = $tDim.bmWidth
    $tSize.Y = $tDim.bmHeight
    $tBlend.Alpha = $iOpacity
    $tBlend.Format = 1
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteDC($hMemDC)
    If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap)
    Return True
EndFunc

 

1 person likes this

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!
¯\_(ツ)_/¯

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