Jump to content

GDI+ On External Window


Demonic
 Share

Recommended Posts

I'm attempting to draw on a external window, but the window is constantly refreshing because of the nature of the program, so upon each refresh, the drawn GDIPlus graphic vanishes. Trying to draw it in a loop creates a flicker effect, which as many have noticed is annoying.

Any way around this, besides creating a seperate GUI that layers over the program?

Link to comment
Share on other sites

Maybe this will help you?

Link: Rotating Letters using GDI+

For transparent window have a look below:

;coded by UEZ 2009
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <String.au3>
Opt('MustDeclareVars', 1)
Opt("GUIOnEventMode", 1)

Global Const $width = 640
Global Const $height = 480
Global Const $pi_div_180 = 4 * ATan(1) / 180
Global $hwnd, $graphics, $backbuffer, $bitmap, $Pen, $arrTxt1, $arrTxt2, $fontsize_txt1, $fontsize_txt2
Global $brush_color, $hFamily1, $hFamily2, $hFont1, $hFont2, $hFormat, $tLayout
Global $ScreenDc, $dc, $tSize, $pSize, $tSource, $pSource, $tBlend, $pBlend, $tPoint, $pPoint, $gdibitmap
Global $x1, $x2, $y1, $y2, $a, $b, $c, $r, $g, $b, $y
Global $width_mul_045, $height_mul_045, $radius_x1, $radius_x2, $radius_y1, $radius_y2, $radius_x, $radius_y
Global $text1, $text2
Global $i = 0, $j = 360, $m = 0, $n = 0
Global $title = "GDI+: Rotating Letters by UEZ 2009!"


$hwnd = GUICreate($title, $width, $height, -1, -1, 0, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST))
GUISetOnEvent($GUI_EVENT_CLOSE, "Close")

_GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd)
$bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
;~ _GDIPlus_GraphicsSetSmoothingMode($backbuffer, 4)

$ScreenDc = _WinAPI_GetDC($hWnd)
$dc = _WinAPI_CreateCompatibleDC($ScreenDc)

; _WinAPI_UpdateLayeredWindow parameters
$tSize = DllStructCreate($tagSIZE)
$pSize = DllStructGetPtr($tSize)
DllStructSetData($tSize, "X", $width)
DllStructSetData($tSize, "Y", $height)
$tSource = DllStructCreate($tagPOINT)
$pSource = DllStructGetPtr($tSource)
$tBlend = DllStructCreate($tagBLENDFUNCTION)
$pBlend = DllStructGetPtr($tBlend)
DllStructSetData($tBlend, "Alpha", 255)
DllStructSetData($tBlend, "Format", 1)
$tPoint = DllStructCreate($tagPOINT)
$pPoint = DllStructGetPtr($tPoint)
DllStructSetData($tPoint, "X", 0)
DllStructSetData($tPoint, "Y", 0)

GUISetState()

$fontsize_txt1 = 48
$fontsize_txt2 = 24

$width_mul_045 = $width * 0.45
$height_mul_045 = $height * 0.45
$radius_x1 = ($width_mul_045) * 0.95
$radius_y1 = ($height_mul_045) * 0.95
$radius_x2 = ($width_mul_045) * 0.45
$radius_y2 = ($height_mul_045) * 0.45
$text1 = _StringReverse(" Rotating Letters using GDI+")
$text2 = " By UEZ '09 ;-)"
$arrTxt1 = StringSplit($text1, "")
$arrTxt2 = StringSplit($text2, "")
Dim $arrX1[UBound($arrTxt1)]
Dim $arrY1[UBound($arrTxt1)]
Dim $arrX2[UBound($arrTxt2)]
Dim $arrY2[UBound($arrTxt2)]
Dim $brush1[UBound($arrTxt1)]
Dim $brush2[UBound($arrTxt2)]

$r = 1
$c = (255 / UBound($arrTxt1) - 1) * 2 - 1
$r = 0x80
$g = 0xA0
$b = $c
For $k = 0 To UBound($arrTxt1) - 1
    $brush_color = "0xFF" & Hex($r, 2) & Hex($g, 2) & Hex($b, 2)
    $brush1[$k] = _GDIPlus_BrushCreateSolid($brush_color)
    If $r = 1 Then
        $b += $c
    Else
        $b -= $c
    EndIf
    If $b >= 255 Then $r = 0
    If $b <= $c Then $r = 1
Next

For $k = 0 To (UBound($arrTxt2) - 1)
    $brush_color = 0xFF808080
    $brush2[$k] = _GDIPlus_BrushCreateSolid($brush_color)
Next
_GDIPlus_BrushSetSolidColor($brush2[0], 0xFFD08020)
_GDIPlus_BrushSetSolidColor($brush2[1], 0xFFFFA060)
_GDIPlus_BrushSetSolidColor($brush2[2], 0xFFD08020)

$hFormat = _GDIPlus_StringFormatCreate()
$hFamily1 = _GDIPlus_FontFamilyCreate("Arial")
$hFamily2 = _GDIPlus_FontFamilyCreate("Comic Sans MS")
$hFont1 = _GDIPlus_FontCreate($hFamily1, $fontsize_txt1, 2)
$hFont2 = _GDIPlus_FontCreate($hFamily2, $fontsize_txt2, 2)
$tLayout = _GDIPlus_RectFCreate(0, 0)
$a = 360 / (UBound($arrTxt1) - 1)
$b = 360 / (UBound($arrTxt2) - 1)
$y = 0

Do
    _GDIPlus_GraphicsClear($backbuffer, 0x00000000)
    For $x = 1 To UBound($arrTxt1) - 1
        $x1 = $width_mul_045 + Cos(($i + $m) * $pi_div_180) * $radius_x1
        $y1 = $height_mul_045 + Sin(($i + $m) * $pi_div_180) * $radius_y1 - $fontsize_txt1 / 4
        $arrX1[$x] = $x1
        $arrY1[$x] = $y1
        DllStructSetData($tLayout, "x", $arrX1[$x])
        DllStructSetData($tLayout, "y", $arrY1[$x])
        _GDIPlus_GraphicsDrawStringEx($backbuffer, $arrTxt1[$x], $hFont1, $tLayout, $hFormat, $brush1[$x])
        $m += $a
    Next
    For $x = 1 To UBound($arrTxt2) - 1
        $x2 = $width_mul_045 + Cos(($j + $n) * $pi_div_180) * $radius_x2 * Cos($y * $pi_div_180)
        $y2 = $height_mul_045 + Sin(($j + $n) * $pi_div_180) * $radius_y2 - $fontsize_txt2 / 4
        $arrX2[$x] = $x2
        $arrY2[$x] = $y2
        DllStructSetData($tLayout, "x", $arrX2[$x])
        DllStructSetData($tLayout, "y", $arrY2[$x])
        _GDIPlus_GraphicsDrawStringEx($backbuffer, $arrTxt2[$x], $hFont2, $tLayout, $hFormat, $brush2[$x])
        $n += $b
    Next
    If Mod($y, 2) = 1 Then Array_Rot($brush2, 1)
    $y += 1

    $gdibitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($bitmap)
    _WinAPI_SelectObject($dc, $gdibitmap)
    _WinAPI_UpdateLayeredWindow($hWnd, $ScreenDc, 0, $pSize, $dc, $pSource, 0, $pBlend, 2)

    $i += 1
;~  If $i >= 360 Then
;~      $i = 0
;~      $m = 0
;~  EndIf
    $j -= 2
;~  If $j <= 0 Then
;~      $j = 360
;~      $n = 0
;~  EndIf
Until False * Not Sleep(30)


Func Array_Rot(ByRef $arr, $dir = 0) ;0 for left, 1 for right
    Local $tmp, $p,$q
    If $dir = 0 Then ;left rotation
        $tmp = $arr[0]
        $q = 0
        For $p = 1 To UBound($arr) - 1
            $arr[$q] = $arr[$p]
            $q += 1
        Next
        $arr[UBound($arr) - 1] = $tmp
    ElseIf $dir = 1 Then ;right rotation
        $tmp = $arr[UBound($arr) - 1]
        $q = UBound($arr) - 1
        For $p = UBound($arr) - 2 To 0 Step - 1
            $arr[$q] = $arr[$p]
            $q -= 1
        Next
        $arr[0] = $tmp
    EndIf
EndFunc

Func _GDIPlus_BrushSetSolidColor($hBrush, $iARGB = 0xFF000000)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetSolidFillColor", "hwnd", $hBrush, "int", $iARGB)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc ;==>_GDIPlus_BrushSetSolidColor

Func Close()
    For $x = 0 To UBound($arrTxt1) - 1
        _GDIPlus_BrushDispose($brush1[$x])
    Next
    For $x = 0 To UBound($arrTxt2) - 1
        _GDIPlus_BrushDispose($brush2[$x])
    Next
    _WinAPI_DeleteDC($dc)
    _WinAPI_ReleaseDC($hWnd, $ScreenDc)
    _GDIPlus_FontDispose($hFont1)
    _GDIPlus_FontDispose($hFont2)
    _GDIPlus_FontFamilyDispose($hFamily1)
    _GDIPlus_FontFamilyDispose($hFamily2)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_GraphicsDispose($backbuffer)
    _GDIPlus_BitmapDispose($bitmap)
    _GDIPlus_GraphicsDispose($graphics)
    _GDIPlus_Shutdown()
    WinClose($hwnd)
    Exit
EndFunc ;==>Close

Thanks to Malkey for the transparent code part (one of the real GDI+ masters )

:)

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

  • 2 weeks later...

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...