Jump to content

Need help adding text atop a GDI+ object


timmy2
 Share

Recommended Posts

The following script, thanks largely to @UEZ, displays the attached PNG image on the Windows Desktop.

Using-Note.png.70ce82c03b4c5773c3dbe7c5858bddc5.png

It perfectly renders the sticky note's shadow over whatever's in the background.

But here's the catch: I would like to add a line of text, fetched from a variable and using a font of my choice, atop the sticky note. It needs to be part of the same GUI because the sticky note can be dragged and placed anywhere on the screen.

Will someone here show me how to add just the additional code needed to accomplish my goal? I have tried sporadically for two years to merge in code from scripts that use GDI+ calls to display text over alpha channels but the challenge has proven beyond me.

#include <ButtonConstants.au3>
#include <MsgBoxConstants.au3>
#include <StructureConstants.au3>
#include <WinAPIConstants.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPISysWin.au3>

_GDIPlus_Startup()
Global Const $SC_DRAGMOVE = 0xF012
Global $iW, $iH, $hImage, $hBitmap, $hGUI
$hImage = _GDIPlus_BitmapCreateFromFile("Using-Note.png")
$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
$iW = _GDIPlus_ImageGetWidth($hImage)
$iH = _GDIPlus_ImageGetHeight($hImage)
$hGUI = GUICreate("", $iW, $iH, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED,$WS_EX_TOPMOST))
GUISetState()
_WinAPI_BitmapDisplayTransparentInGUI($hBitmap, $hGUI)


GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")


Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

_WinAPI_DeleteObject($hBitmap)
_GDIPlus_BitmapDispose($hImage)
_GDIPlus_Shutdown()
GUIDelete()

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)
    _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
EndFunc   ;==>_WM_LBUTTONDOWN

 

Link to comment
Share on other sites

10 hours ago, UEZ said:

Try this:

Wow, what can I say but THANK YOU :thumbsup:.  It works perfectly.  I was trying to accomplish something like this a couple years ago, posed the question, and you responded with a script that I tried to disassemble and merge with the background image script. I finally gave up. Had to move on.

@UEZ, have the functions you used in your code here, and their abilities, been bundled into a published UDF?

Also, please see this comment/"bug report?" I added to your File to Base64 String Code Generator thread.

Edited by timmy2
Link to comment
Share on other sites

3 hours ago, timmy2 said:

@UEZ, have the functions you used in your code here, and their abilities, been bundled into a published UDF?

No, and I never thought about this idea to do. Maybe or maybe not... ;)

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

  • 2 years later...

Hi @UEZ

That is fantastic, not only adding the text to the graphic but embedding the image.   Hopefully a quick question.

How can I change that image after it's added for example I'd like to embed it into a timer but when I tried moving your function down below the GUI declaration, it doesn't display:

;Your Code Above

_GDIPlus_Startup()
Global Const $SC_DRAGMOVE = 0xF012
Global $iW, $iH, $hImage, $hBitmap, $hGUI
$hImage = _GDIPlus_BitmapCreateFromMemory(_Image())
;_AddText2Img($hImage, String($xx))

$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
$iW = _GDIPlus_ImageGetWidth($hImage)
$iH = _GDIPlus_ImageGetHeight($hImage)
$hGUI = GUICreate("", $iW, $iH, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED,$WS_EX_TOPMOST))
GUISetState()
_WinAPI_BitmapDisplayTransparentInGUI($hBitmap, $hGUI)

GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")

For $xx=1 to 5
   _AddText2Img($hImage, String($xx))
   Sleep(1000)
Next

;Your Code Below

Thanks for any tips.

Edited by NassauSky
Link to comment
Share on other sites

Here :

_GDIPlus_Startup()
Global Const $SC_DRAGMOVE = 0xF012
Global $iW, $iH, $hImage, $hBitmap, $hGUI
$hImage = _GDIPlus_BitmapCreateFromMemory(_Image())
$iW = _GDIPlus_ImageGetWidth($hImage)
$iH = _GDIPlus_ImageGetHeight($hImage)
$hGUI = GUICreate("", $iW, $iH, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED,$WS_EX_TOPMOST))
GUISetState()

GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")

For $i = 1 to 5
  _AddText2Img($hImage, String($i))
  $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
  _WinAPI_BitmapDisplayTransparentInGUI($hBitmap, $hGUI)
  _GDIPlus_BitmapDispose($hImage)
  $hImage = _GDIPlus_BitmapCreateFromMemory(_Image())
  Sleep(1000)
  _WinAPI_DeleteObject($hBitmap)
Next


Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

_GDIPlus_BitmapDispose($hImage)
_GDIPlus_Shutdown()

 

Link to comment
Share on other sites

Thanks @Nine,

That worked out perfectly. I tried looping the whole section and it was flashing during refresh. That's interesting how we need to dispose the bitmap image and recreate it from memory then also delete the bitmap which doesn't cause the complete image to flicker.

Thanks again @UEZ for the nice code and @Nine for clearing up 'some' of my confusion

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

×
×
  • Create New...