Jump to content

_WinAPI_DrawShadowText


Go to solution Solved by Yashied,

Recommended Posts

I'm trying to make a "sheet of glass" with shadow text drawn on it, the problem is that the shadow isn't transparent at all.
I have absolutely no idea what I am doing wrong -  being a noob with the WinAPI stuff.
 
Screen-shot:
post-79729-0-60356500-1379304340_thumb.p
 
Here's the script:
; Requires AutoIT beta 3.3.9.21 or newer
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Version=Beta
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <Misc.au3>
#include <WinAPIGdi.au3>

If Not _WinAPI_DwmIsCompositionEnabled() Then
    MsgBox(BitOR(16, 4096), 'Error', 'Script requires Windows Vista or later with enabled Aero theme.')
    Exit
EndIf

Global Const $STM_SETIMAGE = 0x0172
Global Const $STM_GETIMAGE = 0x0173

Global $hDarkBK = GUICreate("Dark background", 400, 40, -1, -1, -1, BitOR($WS_EX_TOOLWINDOW, $WS_EX_WINDOWEDGE))
GUISetBkColor(0)
GUISetState(@SW_SHOW)

Global $hGUI = GUICreate("DWM Test", 300, 20, -1, -1, -1, BitOR($WS_EX_TOOLWINDOW, $WS_EX_WINDOWEDGE, $WS_EX_TOPMOST))
GUISetBkColor(0)
_WinAPI_DwmExtendFrameIntoClientArea($hGUI)

Global $Pic = GUICtrlCreatePic('', 0, 0, 300, 20)
Global $hPic = GUICtrlGetHandle($Pic)

Global $tRECT = _WinAPI_GetClientRect($hPic)
Global $Width = DllStructGetData($tRECT, 3) - DllStructGetData($tRECT, 1)
Global $Height = DllStructGetData($tRECT, 4) - DllStructGetData($tRECT, 2)
Global $hDC = _WinAPI_GetDC($hPic)
Global $hDestDC = _WinAPI_CreateCompatibleDC($hDC)
Global $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $Width, $Height)
Global $hDestSv = _WinAPI_SelectObject($hDestDC, $hBitmap)
Global $hSrcDC = _WinAPI_CreateCompatibleDC($hDC)
Global $hSource = _WinAPI_CreateCompatibleBitmapEx($hDC, $Width, $Height, _WinAPI_SwitchColor(_WinAPI_GetSysColor($COLOR_3DFACE)))
Global $hSrcSv = _WinAPI_SelectObject($hSrcDC, $hSource)
Global $hFont = _WinAPI_CreateFont(20, 0, 0, 0, $FW_NORMAL, 0, 0, 0, $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $ANTIALIASED_QUALITY, $DEFAULT_PITCH, 'Arial')
_WinAPI_SelectObject($hSrcDC, $hFont)
_WinAPI_DrawShadowText($hSrcDC, "Why is the shadow not transparent?", 0xFFFFFF, 0x000000, 3, 3, $tRECT)

_WinAPI_BitBlt($hDestDC, 0, 0, $Width, $Height, $hSrcDC, 0, 0, $MERGECOPY)

_WinAPI_ReleaseDC($hPic, $hDC)
_WinAPI_SelectObject($hDestDC, $hDestSv)
_WinAPI_DeleteDC($hDestDC)
_WinAPI_SelectObject($hSrcDC, $hSrcSv)
_WinAPI_DeleteDC($hSrcDC)
_WinAPI_DeleteObject($hSource)
_WinAPI_DeleteObject($hFont)

; Set bitmap to control
_SendMessage($hPic, $STM_SETIMAGE, 0, $hBitmap)
Global $hObj = _SendMessage($hPic, $STM_GETIMAGE)
If $hObj <> $hBitmap Then
    _WinAPI_DeleteObject($hBitmap)
EndIf

GUISetState(@SW_SHOW)

Global $nMsg
While 1
    $nMsg = GUIGetMsg()
    If $nMsg = $GUI_EVENT_CLOSE Then Exit
WEnd

 

"Just be fred, all we gotta do, just be fred."  -Vocaliod

"That is a Hadouken. A KAMEHAMEHA would have taken him 13 days and 54 episodes to form." - Roden Hoxha

@tabhooked

Clock made of cursors ♣ Desktop Widgets ♣ Water Simulation

Link to comment
Share on other sites

This method doesn't support alpha channel. You have to switch probably to GDI+ to draw shadow text with alpha channel.

As far as I can remember there are several examples creating shadow text using GDI+.

Br,

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

  • Solution

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

If Not _WinAPI_DwmIsCompositionEnabled() Then
    MsgBox(BitOR(16, 4096), 'Error', 'Script requires Windows Vista or later with enabled Aero theme.')
    Exit
EndIf

OnAutoItExitRegister('OnAutoItExit')

Global $hDarkBK = GUICreate("Dark background", 400, 40, -1, -1, -1, BitOR($WS_EX_TOOLWINDOW, $WS_EX_WINDOWEDGE))
GUISetBkColor(0)
GUISetState(@SW_SHOW)

Global $hGUI = GUICreate("DWM Test", 300, 20, -1, -1, -1, BitOR($WS_EX_TOOLWINDOW, $WS_EX_WINDOWEDGE, $WS_EX_TOPMOST))
GUICtrlCreateLabel('Why is the shadow not transparent?', 0, 0, 300, 20)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlSetState(-1, $GUI_DISABLE)
Global $hLabel = GUICtrlGetHandle(-1)
GUISetBkColor(0)

Global $hDll = DllCallbackRegister('_SubclassProc', 'lresult', 'hwnd;uint;wparam;lparam;uint_ptr;dword_ptr')
Global $pDll = DllCallbackGetPtr($hDll)
_WinAPI_SetWindowSubclass($hLabel, $pDll, 1000, 0)

_WinAPI_DwmExtendFrameIntoClientArea($hGUI)

GUISetState(@SW_SHOW)

Global $nMsg

While 1
    $nMsg = GUIGetMsg()
    If $nMsg = $GUI_EVENT_CLOSE Then Exit
WEnd

Func _SubclassProc($hWnd, $iMsg, $wParam, $lParam, $ID, $pData)
    Switch $iMsg
        Case $WM_PAINT

            Local $tPAINTSTRUCT
            Local $hDC = _WinAPI_BeginPaint($hWnd, $tPAINTSTRUCT)

            Local $tRECT = _WinAPI_GetClientRect($hWnd)
            Local $W = DllStructGetData($tRECT, 3) - DllStructGetData($tRECT, 1)
            Local $H = DllStructGetData($tRECT, 4) - DllStructGetData($tRECT, 2)
            Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC)
            Local $hBitmap = _WinAPI_CreateDIB($W, -$H)
            Local $hSv1 = _WinAPI_SelectObject($hMemDC, $hBitmap)
            Local $hFont = _WinAPI_CreateFont(20, 0, 0, 0, $FW_NORMAL, 0, 0, 0, $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $ANTIALIASED_QUALITY, $DEFAULT_PITCH, 'Arial')
            Local $hSv2 = _WinAPI_SelectObject($hMemDC, $hFont)

            _WinAPI_DrawShadowText($hMemDC, 'Why is the shadow not transparent?', 0xFFFFFF, 0x000000, 3, 3, $tRECT)
            _WinAPI_BitBlt($hDC, 0, 0, $W, $H, $hMemDC, 0, 0, $SRCCOPY)

            _WinAPI_SelectObject($hMemDC, $hSv1)
            _WinAPI_DeleteObject($hBitmap)
            _WinAPI_SelectObject($hMemDC, $hSv2)
            _WinAPI_DeleteObject($hFont)
            _WinAPI_DeleteDC($hMemDC)

            _WinAPI_EndPaint($hWnd, $tPAINTSTRUCT)

            Return 0
    EndSwitch
    Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam)
EndFunc   ;==>_SubclassProc

Func OnAutoItExit()
    _WinAPI_RemoveWindowSubclass($hLabel, $pDll, 1000)
    DllCallbackFree($hDll)
EndFunc   ;==>OnAutoItExit

Link to comment
Share on other sites

Thanks UEZ and Yashied, now I'm going to create a P2P chat using this method!

"Just be fred, all we gotta do, just be fred."  -Vocaliod

"That is a Hadouken. A KAMEHAMEHA would have taken him 13 days and 54 episodes to form." - Roden Hoxha

@tabhooked

Clock made of cursors ♣ Desktop Widgets ♣ Water Simulation

Link to comment
Share on other sites

Here the GDI+ variant:

;Coded by UEZ 2013 -> This program requires AutoIt version 3.3.9.21 or higher!

#AutoIt3Wrapper_Autoit3Dir=c:\Program Files (x86)\AutoIt3\Beta
#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>

If Not _WinAPI_DwmIsCompositionEnabled() Then
    MsgBox(BitOR(16, 4096), 'Error', 'Script requires Windows Vista or later with enabled Aero theme.')
    Exit
EndIf

_GDIPlus11_Startup()
Global Const $GDIP_BLUREFFECT = "{633C80A4-1843-482b-9EF2-BE2834C5FDD4}"

Global Const $hGUI = GUICreate("Shadow Text Beta by UEZ 2013", 640, 130, -1, -1, -1, BitOR($WS_EX_TOOLWINDOW, $WS_EX_WINDOWEDGE))
GUISetBkColor(0x000000)
Global Const $iPic = GUICtrlCreatePic("", 0, 0, 640, 130)
_WinAPI_DwmExtendFrameIntoClientArea($hGUI)
Global $hBmp = _GDIPlus_BitmapCreateFromScan0(640, 130)
Global $hCtxt = _GDIPlus_ImageGetGraphicsContext($hBmp)
_GDIPlus_DrawShadowText($hCtxt, "AutoIt rulez!", 80, 0, 0, 0xE00000C0, "Arial", 8, 6, 0xA0000000)
Global $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmp)
_WinAPI_DeleteObject(GUICtrlSendMsg($iPic, 0x0172, 0x0000, $hHBitmap))
GUISetState()


Do
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            _GDIPlus_GraphicsDispose($hCtxt)
            _GDIPlus_BitmapDispose($hBmp)
            _WinAPI_DeleteObject($hHBitmap)
            _GDIPlus_Shutdown()
            GUIDelete()
            Exit
    EndSwitch
Until False

Func _GDIPlus_DrawShadowText($hGraphic, $sText, $iFontSize, $iX, $iY, $iColorText = 0xFF000080, $sFont = "Arial", $iShadowX = 3, $iShadowY = 3, $iColorShadow = 0xF0000000, $iFontStyle = 0, $iBlurLevel = 10)
    Local Const $hFormat = _GDIPlus_StringFormatCreate()
    Local Const $hFamily = _GDIPlus_FontFamilyCreate($sFont)
    Local Const $hFont = _GDIPlus_FontCreate($hFamily, $iFontSize, $iFontStyle)
    Local Const $tLayout = _GDIPlus_RectFCreate()
    Local Const $hBrush = _GDIPlus_BrushCreateSolid($iColorShadow)
    Local Const $aBounds = _GDIPlus_GraphicsMeasureString($hGraphic, $sText, $hFont, $tLayout, $hFormat)
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0(Floor(DllStructGetData($aBounds[0], "width") + Abs($iShadowX)), Floor(DllStructGetData($aBounds[0], "height") + Abs($iShadowX)))
    Local $hCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetSmoothingMode($hCtxt, $GDIP_SMOOTHINGMODE_HIGHQUALITY)
    _GDIPlus_GraphicsSetTextRenderingHint($hCtxt, $GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT)
    DllStructSetData($tLayout, "x", $iShadowX)
    DllStructSetData($tLayout, "y", $iShadowY)
    _GDIPlus_GraphicsDrawStringEx($hCtxt, $sText, $hFont, $tLayout, $hFormat, $hBrush)
    Local Const $tagBLURPARAMS = "float radius;bool expandEdge"
    Local Const $tBlur = DllStructCreate($tagBLURPARAMS)
    Local Const $hEffect = _GDIPlus_Blur($tBlur, $iBlurLevel)
    Local Const $hBitmap_Blur = _GDIPlus_BitmapCreateApplyEffect($hBitmap, $hEffect)
    _GDIPlus_GraphicsDispose($hCtxt)
    _GDIPlus_BitmapDispose($hBitmap)
    $hCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap_Blur)
    _GDIPlus_GraphicsSetSmoothingMode($hCtxt, $GDIP_SMOOTHINGMODE_HIGHQUALITY)
    _GDIPlus_GraphicsSetTextRenderingHint($hCtxt, $GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT)
    _GDIPlus_BrushSetSolidColor($hBrush, $iColorText)
    DllStructSetData($tLayout, "x", 0)
    DllStructSetData($tLayout, "y", 0)
    _GDIPlus_GraphicsDrawStringEx($hCtxt, $sText, $hFont, $tLayout, $hFormat, $hBrush)
    _GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap_Blur, 0, 0)
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_EffectDispose($hEffect)
    _GDIPlus_GraphicsDispose($hCtxt)
    _GDIPlus_BitmapDispose($hBitmap_Blur)
EndFunc   ;==>_GDIPlus_DrawShadowText

Func _GDIPlus_Blur($tBlur, $fRadius, $bExpandEdge = False)
    If Not IsDllStruct($tBlur) Then Return SetError(1, @error, 0)
    DllStructSetData($tBlur, "radius", $fRadius)
    DllStructSetData($tBlur, "expandEdge", $bExpandEdge)
    Local $pEffect = _GDIPlus_EffectCreate($GDIP_BLUREFFECT)
    If @error Then Return SetError(2, @error, 0)
    _GDIPlus_EffectsSetParameters($pEffect, $tBlur)
    If @error Then Return SetError(3, @error, 0)
    Return $pEffect
EndFunc   ;==>_GDIPlus_Blur

Func _GDIPlus_EffectCreate($sEffectGUID, $pEffect = 0)
    Local $iI, $tGUID, $pGUID, $tElem, $aElem[4], $aResult
    $tGUID = _WinAPI_GUIDFromString($sEffectGUID)
    $pGUID = DllStructGetPtr($tGUID)
    $tElem = DllStructCreate("uint[4]", $pGUID)
    For $iI = 1 To 4
        $aElem[$iI - 1] = DllStructGetData($tElem, 1, $iI)
    Next
    $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateEffect", "uint", $aElem[0], "uint", $aElem[1], "uint", $aElem[2], "uint", $aElem[3], "uint*", $pEffect)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aResult[0], 0, $aResult[5])
EndFunc   ;==>_GDIPlus_EffectCreate

Func _GDIPlus_EffectsSetParameters($pEffectObject, $tEffectParameters, $iSizeAdj = 1)
    Local $aSize = DllCall($ghGDIPDll, "uint", "GdipGetEffectParameterSize", "ptr", $pEffectObject, "uint*", 0)
    Local $iSize = $aSize[2] * $iSizeAdj
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipSetEffectParameters", "ptr", $pEffectObject, "struct*", $tEffectParameters, "uint", $iSize)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aResult[0], 0, $aResult[3])
EndFunc   ;==>_GDIPlus_EffectsSetParameters

Func _GDIPlus_BitmapCreateApplyEffect($hBitmap, $pEffect, $pROI = 0, $tOutRect = 0, $hBmpOutput = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipBitmapCreateApplyEffect", _
            "ptr*", $hBitmap, _
            "int", 1, _
            "ptr", $pEffect, _
            "ptr", $pROI, _
            "struct*", $tOutRect, _
            "int*", $hBmpOutput, _
            "int", 0, "ptr*", 0, "int*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aResult[0], 0, $aResult[6])
EndFunc   ;==>_GDIPlus_BitmapCreateApplyEffect

Func _GDIPlus_EffectDispose($pEffect)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipDeleteEffect", "ptr", $pEffect)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc   ;==>_GDIPlus_EffectDispose

Requires AutoIt version 3.3.9.21 or higher and Windows Vista or later with enabled Aero theme!

 

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

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