Jump to content

GDI+ Double Buffer with transparency?


Lakes
 Share

Recommended Posts

I made this transparent buffer template from UEZ rotating letters example.

#include
#include
#include
#include

Global Const $width = 640
Global Const $height = 480
Global $graphics, $backbuffer, $bitmap
Global $ScreenDc, $dc, $tSize, $pSize, $tSource, $pSource, $tBlend, $pBlend, $tPoint, $pPoint, $gdibitmap
Global $dot_k = $Width
Global $Trans, $Size, $i

Opt("GUIOnEventMode", 1)
Opt("MouseCoordMode" ,0)
$GUI= GUICreate("", $width, $height, -1, -1, 0, $WS_EX_LAYERED + $WS_EX_TOPMOST) ;Window Must be Layered for Transparency
GUISetOnEvent($GUI_EVENT_CLOSE, "Close")
_GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($GUI)
$bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
;_GDIPlus_GraphicsSetSmoothingMode($backbuffer, 2)
; == For transparency ==
$ScreenDc = _WinAPI_GetDC($GUI)
$gdibitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($bitmap)
$dc = _WinAPI_CreateCompatibleDC($ScreenDc)
_WinAPI_SelectObject($dc, $gdibitmap)
; == _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)
Global $alpha = 200
Global $alpha_steps = 5
DllStructSetData($tBlend, "Alpha", $alpha)
DllStructSetData($tBlend, "Format", 1)
$tPoint = DllStructCreate($tagPOINT)
$pPoint = DllStructGetPtr($tPoint)
DllStructSetData($tPoint, "X", 0)
DllStructSetData($tPoint, "Y", 0)
;===============================================
GUISetState()
Do
_GDIPlus_GraphicsClear($backbuffer, 0x00000000)
; This is where you do your animation/ draw stuff :-)
If $i = 264 then Close()   ;move dot across twice then Close, comment this out to loop until esc is pressed.
DrawDot()
$i += 1

; This is used for the transperancy instead of _GDIPlus_GraphicsDrawImageRect
    $gdibitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($bitmap)
    _WinAPI_SelectObject($dc, $gdibitmap)
    _WinAPI_UpdateLayeredWindow($GUI, $ScreenDc, 0, $pSize, $dc, $pSource, 0, $pBlend, 2)
_WinAPI_DeleteObject($gdibitmap)
Until False * Not Sleep(30)
Func DrawDot()
$dot_k -= 5
If $Dot_k <= -20 Then $dot_k = $Width
   _GDIPlus_GraphicsFillEllipse($backBuffer, $Dot_k, $Height/2 -20 ,40, 40)   ; Draw a Dot and move it
EndFunc  
Func Close()
; Clean up
_WinAPI_DeleteDC($dc)
_WinAPI_ReleaseDC($GUI, $ScreenDc)
_GDIPlus_GraphicsDispose($backbuffer)
_GDIPlus_BitmapDispose($bitmap)
_GDIPlus_GraphicsDispose($graphics)
_GDIPlus_Shutdown()
WinClose($GUI)
Exit
EndFunc   ;==>Close

So, now I want to make this transparent.

#include
#include
#include
Opt("GUIOnEventMode", 1)
Global Const $Angle = 10
Opt("GuiOnEventMode", 1)
Global $Width = 600, $Height = 600, $SizeW = $Width/2, $SizeH = $Height/2
Global $CenterX = @DesktopWidth/2, $CenterY = @DeskTopHeight/2
$hwnd = GUICreate("Image Rotate", $Width, $Height, -1, -1, $WS_POPUP)
GUISetOnEvent(-3, "close")
msgbox(0, "", "Use Scroll Wheel to Rotate Image", 2)
_GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd)
$bitmap = _GDIPlus_BitmapCreateFromGraphics($Width, $Height, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
$image = _ScreenCapture_Capture("", $CenterX, $CenterY, $CenterX + $Width, $CenterY + $Height, False)
; Create GDI+ Bitmap object from GDI Bitmap object
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($image)
$matrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixTranslate($matrix, $Width/2, $Height/2)
;SetTrans($hwnd)
GUIRegisterMsg(0x020A, "WM_MOUSEWHEEL")
GUISetState()
_GDIPlus_GraphicsSetTransform($backbuffer, $matrix)
; _GDIPlus_GraphicsDrawImageRect($backbuffer, $hBitmap, -$SizeW/2, -$SizeH/2, $SizeW, $SizeH)
_GDIPlus_GraphicsDrawImageRect($backbuffer, $hBitmap, -$SizeW, -$SizeH, $Width/2, $Height/2)
    _GDIPlus_GraphicsDrawImageRect($graphics, $hBitmap, 0, 0, $Width, $Height)
While 1
    Sleep(20)
WEnd

Func Rotate_Matrix($hmatrix, $nangle)
    _GDIPlus_GraphicsClear($backbuffer, 0xFF123456)
    _GDIPlus_MatrixRotate($matrix, $nangle)
    _GDIPlus_GraphicsSetTransform($backbuffer, $matrix)
; _GDIPlus_GraphicsDrawImageRect($backbuffer, $hBitmap, -$SizeW/2, -$SizeH/2, $SizeW, $SizeH)
    _GDIPlus_GraphicsDrawImageRect($backbuffer, $hBitmap, -$SizeW, -$SizeH, $Width, $Height)
    _GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $Width, $Height)
EndFunc  ;==>Rotate_Matrix
Func close()
    Exit
EndFunc  ;==>close

Func WM_MOUSEWHEEL($hWnd, $iMsg, $iwParam, $ilParam)
Local $iValue = _WinAPI_HiWord($iwParam) / 120
  If $iValue > 0 Then
            Rotate_Matrix($matrix, $Angle)
  Else
            Rotate_Matrix($matrix, -($Angle))
  EndIf
Return "GUI_RUNDEFMSG"
EndFunc   ;==>WM_COMMAND

And I`ve ended up with this...

#include
#include
#include
Opt("GUIOnEventMode", 1)
Global Const $Angle = 10
Opt("GuiOnEventMode", 1)
Global $Width = 600, $Height = 600, $SizeW = $Width/2, $SizeH = $Height/2
Global $ScreenDc, $dc, $tSize, $pSize, $tSource, $pSource, $tBlend, $pBlend, $tPoint, $pPoint, $gdibitmap
Global $CenterX = @DesktopWidth/2, $CenterY = @DeskTopHeight/2
;$GUI = GUICreate("Image Rotate", $Width, $Height, -1, -1, $WS_POPUP)
$GUI = GUICreate("Image Rotate", $Width, $Height, -1, -1, $WS_POPUP + $WS_EX_LAYERED + $WS_EX_TOPMOST) ;Window Must be Layered for Transparency
GUISetOnEvent(-3, "close")
;msgbox(0, "", "Use Scroll Wheel to Rotate Image", 2)
$image = _ScreenCapture_Capture("", $CenterX, $CenterY, $CenterX + $Width, $CenterY + $Height, False)
; Create GDI+ Bitmap object from GDI Bitmap object
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($image)
_GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($GUI)
$WinBitmap = _GDIPlus_BitmapCreateFromGraphics($Width, $Height, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($WinBitmap)
; == For transparency ==
$ScreenDc = _WinAPI_GetDC($GUI)
$gdibitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hbitmap)
$dc = _WinAPI_CreateCompatibleDC($ScreenDc)
_WinAPI_SelectObject($dc, $gdibitmap)
; == _WinAPI_UpdateLayeredWindow parameters ==
$tSize = DllStructCreate($tagSIZE)
$pSize = DllStructGetPtr($tSize)
DllStructSetData($tSize, "X", -$SizeW)
DllStructSetData($tSize, "Y", -$SizeH)
$tSource = DllStructCreate($tagPOINT)
$pSource = DllStructGetPtr($tSource)
$tBlend = DllStructCreate($tagBLENDFUNCTION)
$pBlend = DllStructGetPtr($tBlend)
Global $alpha = 200
Global $alpha_steps = 5
DllStructSetData($tBlend, "Alpha", $alpha)
DllStructSetData($tBlend, "Format", 1)
$tPoint = DllStructCreate($tagPOINT)
$pPoint = DllStructGetPtr($tPoint)
DllStructSetData($tPoint, "X", 0)
DllStructSetData($tPoint, "Y", 0)
;===============================================

$matrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixTranslate($matrix, $Width/2, $Height/2)
;GUIRegisterMsg(0x020A, "WM_MOUSEWHEEL")
GUISetState()
_GDIPlus_GraphicsSetTransform($backbuffer, $matrix)

; _GDIPlus_GraphicsDrawImageRect($backbuffer, $hBitmap, -$SizeW, -$SizeH, $Width/2, $Height/2)
;   _GDIPlus_GraphicsDrawImageRect($graphics, $hBitmap, 0, 0, $Width, $Height)
; This is used for the transperancy instead of _GDIPlus_GraphicsDrawImageRect
    $GDIbitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hbitmap)
    _WinAPI_SelectObject($dc, $GDIbitmap)
    _WinAPI_UpdateLayeredWindow($GUI, $ScreenDc, 0, $pSize, $dc, $pSource, 0, $pBlend, 2)
_WinAPI_DeleteObject($GDIbitmap)

While 1
    Sleep(20)
AutoRotate()
WEnd

Func Rotate_Matrix($hmatrix, $nangle)
    _GDIPlus_GraphicsClear($backbuffer, 0xFF000000)
    _GDIPlus_MatrixRotate($matrix, $nangle)
    _GDIPlus_GraphicsSetTransform($backbuffer, $matrix)
;  _GDIPlus_GraphicsDrawImageRect($backbuffer, $hBitmap, -$SizeW, -$SizeH, $Width, $Height)
;   _GDIPlus_GraphicsDrawImageRect($graphics, $WinBitmap, 0, 0, $Width, $Height)
; This is used for the transperancy instead of _GDIPlus_GraphicsDrawImageRect
    $GDIbitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hbitmap)
    _WinAPI_SelectObject($dc, $GDIbitmap)
    _WinAPI_UpdateLayeredWindow($GUI, $ScreenDc, 0, $pSize, $dc, $pSource, 0, $pBlend, 2)
_WinAPI_DeleteObject($gdibitmap)

EndFunc  ;==>Rotate_Matrix
Func close()
    Exit
EndFunc  ;==>close
Func AutoRotate()
$nAngle =+ 4
If $nAngle > 360 then $nAngle = 0
Rotate_Matrix($matrix, $nAngle)
EndFunc
Func WM_MOUSEWHEEL($GUI, $iMsg, $iwParam, $ilParam)
Local $iValue = _WinAPI_HiWord($iwParam) / 120
  If $iValue > 0 Then
            Rotate_Matrix($matrix, $Angle)
  Else
            Rotate_Matrix($matrix, -($Angle))
  EndIf
Return "GUI_RUNDEFMSG"
EndFunc   ;==>WM_COMMAND

I must be missing something...

Thanks for looking. :D

Edited by Lakes

2015 - Still no flying cars, instead blankets with sleeves.

Link to comment
Share on other sites

Try this:

#Include <ScreenCapture.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)

Global Const $width = 600
Global Const $height = 600
_GDIPlus_Startup()
Global $hBG_HBitmap = _ScreenCapture_Capture("", 0, 0, $width, $height, False)
Global $hBG_Bitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBG_HBitmap)
_WinAPI_DeleteObject($hBG_HBitmap)

Global $dx = $width
Global $dy = $height

Global $i

Global $hWnd = GUICreate("GDI+: Example by UEZ 2010", $width, $height, -1, -1, 0, $WS_EX_LAYERED + $WS_EX_TOOLWINDOW)
GUISetOnEvent(-3, "_Exit")
GUISetState()

Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
Global $hBitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $hGraphics)
Global $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
;~ _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)
;~ DllCall($ghGDIPDll, "uint", "GdipSetInterpolationMode", "handle", $hBackbuffer, "int", 7)

#region mache GUI transparent
$ScreenDc = _WinAPI_GetDC($hWnd)
$GDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
$dc = _WinAPI_CreateCompatibleDC($ScreenDc)
_WinAPI_SelectObject($dc, $GDIBitmap)
; _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)
Global $alpha = 255
DllStructSetData($tBlend, "Alpha", $alpha)
DllStructSetData($tBlend, "Format", 1)
$tPoint = DllStructCreate($tagPOINT)
$pPoint = DllStructGetPtr($tPoint)
DllStructSetData($tPoint, "X", 0)
DllStructSetData($tPoint, "Y", 0)
#endregion

Global $hMatrix = _GDIPlus_MatrixCreate()
Global $rot_mid_x = $width / 2
Global $rot_mid_y = $height / 2
_GDIPlus_MatrixTranslate($hMatrix, $rot_mid_x, $rot_mid_y)

$i = 0.5

While Sleep(30)
    _GDIPlus_GraphicsClear($hBackbuffer, 0xFF000000)

    _GDIPlus_MatrixRotate($hMatrix, $i, "False")
    _GDIPlus_GraphicsSetTransform($hBackbuffer, $hMatrix)
    _GDIPlus_GraphicsDrawImageRect($hBackbuffer, $hBG_Bitmap, -$rot_mid_x / 2, -$rot_mid_y / 2, $dx / 2, $dy / 2)

    $GDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    _WinAPI_SelectObject($dc, $gdibitmap)
    _WinAPI_UpdateLayeredWindow($hWnd, $ScreenDc, 0, $pSize, $dc, $pSource, 0, $pBlend, 1)
    _WinAPI_DeleteObject($GDIBitmap)
WEnd

Func _Exit()
    _WinAPI_DeleteDC($dc)
    _WinAPI_ReleaseDC($hWnd, $ScreenDc)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_MatrixDispose($hMatrix)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
EndFunc

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

  • 3 weeks later...

Ok, so now I want to rotate that over a static image, do I need to something like this?

Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
;
Global $hBitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $hGraphics)
Global $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
;
Global $hBitmap1   = _GDIPlus_BitmapCreateFromGraphics($width, $height, $hGraphics)
Global $hBackbuffer1  = _GDIPlus_ImageGetGraphicsContext($hBitmap1)
;
#region make GUI transparent
$ScreenDc = _WinAPI_GetDC($hWnd)
$GDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
$dc = _WinAPI_CreateCompatibleDC($ScreenDc)
_WinAPI_SelectObject($dc, $GDIBitmap)
;

$GDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap1)
$dc = _WinAPI_CreateCompatibleDC($ScreenDc)
_WinAPI_SelectObject($dc, $GDIBitmap1)
Thanks :D

2015 - Still no flying cars, instead blankets with sleeves.

Link to comment
Share on other sites

Your direction is correct!

Try this one here:

#Include <screencapture.au3>
#include <windowsconstants.au3>
Opt("GUIOnEventMode", 1)

Global Const $width = 600
Global Const $height = 600
_GDIPlus_Startup()
Global $hFG_HBitmap = _ScreenCapture_Capture("", 0, 0, $width, $height, False)
Global $hFG_Bitmap = _GDIPlus_BitmapCreateFromHBITMAP($hFG_HBitmap)
_WinAPI_DeleteObject($hFG_HBitmap)
Global $hBG_Bmp = _GDIPlus_BitmapCloneArea($hFG_Bitmap, 0, 0, $width, $height)
Global $dx = $width
Global $dy = $height

Global $i

Global $hWnd = GUICreate("GDI+: Example by UEZ 2010", $width, $height, -1, -1, 0, $WS_EX_LAYERED + $WS_EX_TOOLWINDOW)
GUISetOnEvent(-3, "_Exit")
GUISetState()

Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
Global $hFG_Bitmap_Rot = _GDIPlus_BitmapCreateFromGraphics($width, $height, $hGraphics)
Global $hBackbuffer_Rot = _GDIPlus_ImageGetGraphicsContext($hFG_Bitmap_Rot)

Global $hBG_Bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $hGraphics)
Global $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBG_Bitmap)

;~ _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)
;~ DllCall($ghGDIPDll, "uint", "GdipSetInterpolationMode", "handle", $hBackbuffer, "int", 7)

#region mache GUI transparent
$ScreenDc = _WinAPI_GetDC($hWnd)
$GDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBG_Bitmap)
$dc = _WinAPI_CreateCompatibleDC($ScreenDc)
_WinAPI_SelectObject($dc, $GDIBitmap)
; _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)
Global $alpha = 255
DllStructSetData($tBlend, "Alpha", $alpha)
DllStructSetData($tBlend, "Format", 1)
$tPoint = DllStructCreate($tagPOINT)
$pPoint = DllStructGetPtr($tPoint)
DllStructSetData($tPoint, "X", 0)
DllStructSetData($tPoint, "Y", 0)
#endregion

Global $hMatrix = _GDIPlus_MatrixCreate()
Global $rot_mid_x = $width / 2
Global $rot_mid_y = $height / 2
_GDIPlus_MatrixTranslate($hMatrix, $rot_mid_x, $rot_mid_y)

$i = 0.5

While Sleep(30)
    _GDIPlus_GraphicsClear($hBackbuffer_Rot, 0x00000000)
    _GDIPlus_MatrixRotate($hMatrix, $i, 0)
    _GDIPlus_GraphicsSetTransform($hBackbuffer_Rot, $hMatrix)
    _GDIPlus_GraphicsDrawImageRect($hBackbuffer_Rot, $hFG_Bitmap, -$rot_mid_x / 2, -$rot_mid_y / 2, $dx / 2, $dy / 2)

    _GDIPlus_GraphicsDrawImage($hBackbuffer,  $hBG_Bmp, 0, 0)
    _GDIPlus_GraphicsDrawImage($hBackbuffer,  $hFG_Bitmap_Rot , 0, 0)

    $GDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBG_Bitmap)
    _WinAPI_SelectObject($dc, $gdibitmap)
    _WinAPI_UpdateLayeredWindow($hWnd, $ScreenDc, 0, $pSize, $dc, $pSource, 0, $pBlend, 0)
    _WinAPI_DeleteObject($GDIBitmap)
WEnd

Func _Exit()
    _WinAPI_DeleteDC($dc)
    _WinAPI_ReleaseDC($hWnd, $ScreenDc)
    _GDIPlus_MatrixDispose($hMatrix)
    _GDIPlus_BitmapDispose($hFG_Bitmap_Rot)
    _GDIPlus_BitmapDispose($hBG_Bitmap)
    _GDIPlus_BitmapDispose($hBG_Bmp)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_GraphicsDispose($hBackbuffer_Rot)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
EndFunc

Br,

UEZ

Edit: disabled the transparency of the bitmaps

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

  • Recently Browsing   0 members

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