Jump to content
Sign in to follow this  
DatMCEyeBall

_WinAPI_DrawShadowText

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

Share this post


Link to post
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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

#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


Share this post


Link to post
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

Share this post


Link to post
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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

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  

  • Similar Content

    • By lonardd
      Hi,
      I have a very strange problem concerning MouseClick function.
      I need to start Control Panel, navigate it on the Display Section (Adjust screen resolution link), click on it, and from the next Dialog choose Intel Graphic tool tab and navigate into it when it opens. 
      I wasn't using MouseClick() at first when I tried to use Control IDs, but I was fed up with the Autoit Window Info poor and inaccurate info (It flickers and the moment I click on the control the control ID and class disappear) so I ended up choosing the easiest way.
      The code I'm posting worked OK until two weeks ago, the mouse clicks were accurately performed and the Script reached the end with no errors...and I was happy.
      All of a sudden, between one try and the other, I noticed the cursor not flying exactly where it was supposed to, namely to the Control Panel ->Display->Adjust screen resolution link   but it clicked some 30 pixels below and some 30 pixels to the left, choosing obviously and undesired function and from that point it screwed the whole thing up. And from that moment onward, it seems I can no longer regain the mouse to click on that sequence.
      Could it be because my Control Panel ->Display form moved slightly from one test to another and therefore I got that small offside?
      If you believe this is the reason, I should then re position the Control Panel ->Display window to 0,0 and recalculate all the clicks. 
      do you have a suggestion?
       
      Thanks a lot
      Dave
       
       
       
      RotateDisplays.au3
    • By lonardd
      I need to open an INTEL Graphic Tool clicking on a Win7 Tray Icon. This icon is not shown on the Win7 Tray but it is shown once you click on a button that shows a little  arrow-up. This button opens up an extension of the tray and there is my INTEL Graphic Tool Icon. 
      The first ControlClick('[Class:Shell_TrayWnd]', '', 1502 ) at line 26 of my source code (Rotatedisplays.au3) works fine as it clicks on the up-arrow shown on the uparrowfirst Menu.jpg  picture and opens up an extension of the tray. Then I'm trying to click on the INTEL Graphic Tool Icon which is the first blue icon (up-left) of the tray extension but I failed all my attempts. Can somebody help me out?
      Thanks 
      Dave


      RotateDisplays.au3
    • By argumentum
      in 
       so, here they are.
    • By drapdv
      I have a GUI with a parent window that has a menu and shortcut buttons at the top, and a child window which displays a list which is scrolled vertically.
      When the list is relatively small, like no more than 100 or so lines then it scrolls fine.  As the list gets larger, scrolling begins to slow, and if you start mixing up the scroll method (mousewheel, left-clicking the scrollbar box, etc) then it begins to hang.  When it hangs, dwm.exe CPU usage maxes out, and I can't even switch to another window.  Each line in the list is 1000px wide X 30px tall, and the lines alternate between a gray background and a white background, in case that matters.
      When a non-Aero theme is active, everything works fine.  So, I could disable DWM every time someone fires it up, but changing a client's color scheme is not ideal.
      I tried to utilize _WinAPI_DwmSetWindowAttribute($oGui_Parent,  $DWMWA_NCRENDERING_POLICY, $DWMNCRP_DISABLED), and although it succeeds in disabling DWM for that window, it doesn't seem to make any difference as far as the scrolling lag is concerned.
      The code is several thousand lines long and contains proprietary information, so I'm trying to avoid posting that, but these are the lines which are creating the GUIs.  Is there anything that anyone can think of off the top of their heads, or is there anything jumping out at you from this snippet of code?  Any help is appreciated!
      $oGui_Parent = GUICreate("Data Viewer", 700, 500, Default, Default, BitOR($WS_CAPTION, $WS_MINIMIZEBOX, $WS_POPUPWINDOW)) WinSetTrans($oGui_Parent, "", 255) _WinAPI_DwmSetWindowAttribute($oGui_Parent, $DWMWA_NCRENDERING_POLICY, $DWMNCRP_DISABLED) GUISetFont(9, 500, 0, "Calibri") GUISetBkColor(0xFFFFFF) $oGui_Child = GUICreate("", 700, 400, 0, 100, $WS_POPUP, $WS_EX_MDICHILD, $oGui_Parent) WinSetTrans($oGui_Child, "", 255) _WinAPI_DwmSetWindowAttribute($oGui_Child, $DWMWA_NCRENDERING_POLICY, $DWMNCRP_DISABLED) GUISetFont(9, 500, 0, "Calibri") GUISetBkColor(0xFFFFFF)  
    • By AutoitMike
      I saw a post dated 2013 about WinSetTitle not working in Win7 64bit. No answer there for me.
      I am trying to set the title of a window, the function returns success and the title is changed for about 50 ms and then reverts back to its original value.
      #RequireAdmin makes no difference in operation.
      I have tried using the handle, the title and the class to define the window. Operation is the same for all three ways.
      EG:
      WinSetTitle("Old Title", "", "New Title")
      WinSetTitle("[Class:Class name]","","New Title")
      WinSetTitle(handle,"","New Title")
      ;=======================================================================================
      All functions report success.
      WinActivate("PxxCXpbHG", "Text")
      WinSetTitle("PxxCXpbHG ", "Text","New title")
      $M1=WinGetTitle("[ACTIVE]","")
      sleep (100)
      $M2=WinGetTitle("[ACTIVE]","")
      MsgBox(0,"", $M1 & "  " & $M2) ;------------------> "New Title"  "PxxCXpbHG"
      If I change Sleep to 50 , then it is "New Title", "New Title" so somewhere between 50 and 100 ms it gets changed back,but by what??
      Thanks for any help in this matter.
       
       
       
       
×
×
  • Create New...