Sven-Seyfert Posted October 25, 2017 Share Posted October 25, 2017 (edited) Hi Community, I'm new at the forum but familiar with AutoIt since few years. I got a problem when I drag a GDI+ loaded image on the GUI to a other position. When I drag the next image (of three) in the nearly position of the first dragged image, I got a overlapped effect which isn't transparence like I would want to have. The animated GIF should hopefully explain my problem further (like on GitHub).Why the GDI+ PNG images aren't transparence on the GUI? I don't want to use a buffer system for the illustration on the GUI or do I have to? Thanks for any suggestion - I'm grateful! Sven [Solved] Final solution: Thanks to the community, especially to @UEZ and @argumentum . CODE Spoiler expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=..\Libraries\icon.ico #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_Res_Fileversion=0.5 #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ; ------------------------------------------------------------------------------ ; GDIPlusGame_MapEditor (2017-11-13) ; ------------------------------------------------------------------------------ ; includes --------------------------------------------------------------------- #include-once #include <GDIPlus.au3> #include <GuiConstantsEx.au3> #include <String.au3> #include <WindowsConstants.au3> ; opt and just singleton ------------------------------------------------------- Opt( 'MustDeclareVars', 1 ) Local $aInst = ProcessList( 'GDIPlusGame_MapEditor.exe' ) If $aInst[0][0] > 1 Then Exit ; declaration ------------------------------------------------------------------ Local Const $sPathImg = '.\tiles\' Local Const $sExtImg = '.png' Local Const $iGuiWidth = 1000 Local Const $iGuiHeight = 690 Local Const $iGuiLeft = 10 Local Const $iGuiTop = 10 Local Const $iGuiTrans = 255 Local Const $vTransColor1 = 0xABCDEF Local Const $vTransColor2 = 0xFFABCDEF Local $aImgInformations[4][7] = [['Object', 'Width', 'Height', 'X', 'Y', 'Id', 'Name']] ; init ------------------------------------------------------------------------- _GDIPlus_Startup() Local $aImgWidths[4][1] Local $iMaxImgWidth Func _getImageObjectsForGettingWidth( $aArray, $sImgName ) For $i = 1 To UBound( $aArray ) - 1 Step 1 If StringLen( $i ) == 1 Then $aArray[$i][0] = _GDIPlus_ImageLoadFromFile( $sPathImg & $sImgName & '0' & $i & '_01' & $sExtImg ) If StringLen( $i ) <> 1 Then $aArray[$i][0] = _GDIPlus_ImageLoadFromFile( $sPathImg & $sImgName & $i & '_01' & $sExtImg ) Next Return $aArray EndFunc Func _setMaxImgWidth( $aArray ) For $i = 1 To UBound( $aArray ) - 1 Step 1 Local $iWidthSave = _GDIPlus_ImageGetWidth( $aArray[$i][0] ) If $iWidthSave > $iMaxImgWidth Then $iMaxImgWidth = $iWidthSave Next Return $iMaxImgWidth EndFunc $aImgWidths = _getImageObjectsForGettingWidth( $aImgWidths, 'tree' ) $iMaxImgWidth = _setMaxImgWidth( $aImgWidths ) ; gui -------------------------------------------------------------------------- Local $hMainGui = GUICreate( 'GDIPlusGame_MapEditor', $iGuiWidth + $iMaxImgWidth, $iGuiHeight, $iGuiLeft, $iGuiTop, -1, $WS_EX_LAYERED ) GUISetBkColor( $vTransColor1, $hMainGui ) _WinAPI_SetLayeredWindowAttributes( $hMainGui, $vTransColor1, $iGuiTrans ) GUISetState( @SW_SHOW, $hMainGui ) ; functions -------------------------------------------------------------------- Func _createGraphicsBufferSystem() Global $hDC = _WinAPI_GetDC( $hMainGui ) Global $hDCBitmap = _WinAPI_CreateCompatibleBitmap( $hDC, $iGuiWidth + $iMaxImgWidth, $iGuiHeight ) Global $hDCBuffer = _WinAPI_CreateCompatibleDC( $hDC ) Global $hDCObject = _WinAPI_SelectObject( $hDCBuffer, $hDCBitmap ) Global $hGraphics = _GDIPlus_GraphicsCreateFromHDC( $hDCBuffer ) EndFunc Func _loadImageObjects( $aArray, $sImgName ) For $i = 1 To UBound( $aArray ) - 1 Step 1 If StringLen( $i ) == 1 Then $aArray[$i][0] = _GDIPlus_ImageLoadFromFile( $sPathImg & $sImgName & '0' & $i & '_01' & $sExtImg ) If StringLen( $i ) <> 1 Then $aArray[$i][0] = _GDIPlus_ImageLoadFromFile( $sPathImg & $sImgName & $i & '_01' & $sExtImg ) Next Return $aArray EndFunc Func _getImgObjectsSize( $aArray ) For $i = 1 To UBound( $aArray ) - 1 Step 1 Local $hImg = $aArray[$i][0] $aArray[$i][1] = _GDIPlus_ImageGetWidth( $hImg ) $aArray[$i][2] = _GDIPlus_ImageGetHeight( $hImg ) Next Return $aArray EndFunc Func _setImgObjectsPosition( $aArray ) Local $iTopPosOfFirstImg = 0 For $i = 1 To UBound( $aArray ) - 1 Step 1 Local $iImgHeight = $aArray[$i][2] $aArray[$i][3] = $iGuiWidth $aArray[$i][4] = $iTopPosOfFirstImg $iTopPosOfFirstImg += $iImgHeight Next Return $aArray EndFunc Func _setHelpLabelsForImgObjects( $aArray ) For $i = 1 To UBound( $aArray ) - 1 Step 1 $aArray[$i][5] = GUICtrlCreateLabel( '', $aArray[$i][3], $aArray[$i][4], $aArray[$i][1], $aArray[$i][2] ) Next Return $aArray EndFunc Func _setImgNameForImgObjects( $aArray, $sImgName ) For $i = 1 To UBound( $aArray ) - 1 Step 1 If StringLen( $i ) == 1 Then $aArray[$i][6] = $sImgName & '0' & $i & '_01' If StringLen( $i ) <> 1 Then $aArray[$i][6] = $sImgName & $i & '_01' Next Return $aArray EndFunc Func _setGraphicsMode() _GDIPlus_GraphicsSetSmoothingMode( $hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY ) _GDIPlus_GraphicsSetPixelOffsetMode( $hGraphics, $GDIP_PIXELOFFSETMODE_HIGHQUALITY ) Global $hBrush = _GDIPlus_BrushCreateSolid( $vTransColor2 ) EndFunc Func _imgControlMoveLoop( $aImgs ) ; 0 to 6 => 'Object', 'Width', 'Height', 'X', 'Y', 'Id', 'Name' Do _callGdipFillRectangle() _getMouseInfos( $hMainGui ) If $iMouseLeftDown And $cHoveredCtrl Then Local $iCtrl = _findImgCtrl( $cHoveredCtrl, $aImgs ) Local $iDX = Abs( MouseGetPos( 0 ) - $aImgs[$iCtrl][3] ) Local $iDY = Abs( MouseGetPos( 1 ) - $aImgs[$iCtrl][4] ) Do _callGdipFillRectangle() _getMouseInfos( $hMainGui ) $aImgs[$iCtrl][3] = MouseGetPos( 0 ) - $iDX $aImgs[$iCtrl][4] = MouseGetPos( 1 ) - $iDY _drawImages( $aImgs ) _performBitBlockTranfer() Until Not $iMouseLeftDown _writeImgInfosToConsole( $aImgs ) ControlMove( $hMainGui, '', $aImgs[$iCtrl][5], $aImgs[$iCtrl][3], $aImgs[$iCtrl][4] ) Else _drawImages( $aImgs ) EndIf _performBitBlockTranfer() Until Not Sleep( 10 ) EndFunc Func _callGdipFillRectangle() DllCall( $__g_hGDIPDll, 'int', 'GdipFillRectangle', 'handle', $hGraphics, 'handle', $hBrush, 'float', 0, 'float', 0, 'float', $iGuiWidth + $iMaxImgWidth, 'float', $iGuiHeight ) EndFunc Func _getMouseInfos( $hWin ) Global $aMouseInfos = GUIGetCursorInfo( $hWin ) Global $iMouseLeftDown = $aMouseInfos[2] Global $cHoveredCtrl = $aMouseInfos[4] EndFunc Func _findImgCtrl( $iCtrl, $aArray ) For $i = 1 To UBound( $aArray ) - 1 Step 1 Local $iHelpLabelCtrlForImage = $aArray[$i][5] If $iHelpLabelCtrlForImage = $iCtrl Then Return $i Next EndFunc Func _drawImages( $aArray ) For $i = 1 To UBound( $aArray ) - 1 Step 1 _GDIPlus_GraphicsDrawImageRect( $hGraphics, $aArray[$i][0], $aArray[$i][3], $aArray[$i][4], $aArray[$i][1], $aArray[$i][2] ) Next EndFunc Func _performBitBlockTranfer() _WinAPI_BitBlt( $hDC, 0, 0, $iGuiWidth + $iMaxImgWidth, $iGuiHeight, $hDCBuffer, 0, 0, $SRCCOPY ) EndFunc Func _writeImgInfosToConsole( $aArray ) ConsoleWrite( _StringRepeat( '-', 81 ) & @CRLF ) For $i = 0 To UBound( $aArray ) - 1 Step 1 ConsoleWrite( $aArray[$i][0] & ', ' & $aArray[$i][1] & ', ' & $aArray[$i][2] & ', ' & _ $aArray[$i][3] & ', ' & $aArray[$i][4] & ', ' & $aArray[$i][5] & ', ' & _ $aArray[$i][6] & @CRLF ) Next EndFunc Func _disposeAndExit() For $i = 1 To UBound( $aImgInformations ) - 1 _GDIPlus_ImageDispose( $aImgInformations[$i][0] ) Next _GDIPlus_BrushDispose( $hBrush ) _GDIPlus_GraphicsDispose( $hGraphics ) _WinAPI_SelectObject( $hDCBuffer, $hDCObject ) _WinAPI_DeleteDC( $hDCBuffer ) _WinAPI_DeleteObject( $hDCBitmap ) _WinAPI_ReleaseDC( $hMainGui, $hDC ) GUIDelete( $hMainGui ) _GDIPlus_Shutdown() Exit EndFunc ; processing ------------------------------------------------------------------- AutoItSetOption( 'GUIOnEventMode', 1 ) GUISetOnEvent( $GUI_EVENT_CLOSE, '_disposeAndExit' ) _createGraphicsBufferSystem() Local $aImgInfos = _loadImageObjects( $aImgInformations, 'tree' ) $aImgInfos = _getImgObjectsSize( $aImgInfos ) $aImgInfos = _setImgObjectsPosition( $aImgInfos ) $aImgInfos = _setHelpLabelsForImgObjects( $aImgInfos ) $aImgInfos = _setImgNameForImgObjects( $aImgInfos, 'tree' ) _setGraphicsMode() _imgControlMoveLoop( $aImgInfos ) AutoItSetOption( 'GUIOnEventMode', 0 ) BEFORE Spoiler AFTER Spoiler Edited November 13, 2017 by Sven-Seyfert argumentum 1 Link to comment Share on other sites More sharing options...
Sven-Seyfert Posted October 26, 2017 Author Share Posted October 26, 2017 (edited) I wrote the solution of my problem at post #1. Especially for you @qwert as a hint . Edited November 13, 2017 by Sven-Seyfert Link to comment Share on other sites More sharing options...
Moderators JLogan3o13 Posted October 26, 2017 Moderators Share Posted October 26, 2017 @Sven-Seyfert simply edit your initial post and put [Solved] in front of the title. "Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball How to get your question answered on this forum! Link to comment Share on other sites More sharing options...
qwert Posted October 27, 2017 Share Posted October 27, 2017 Thanks for posting this question/solution. However, when I attempt to confirm the script, I get an unexpected result: the background of the window is transparent and properly displays the individual PNGs. But the transparency of individual PNGs is lost when they overlap. Have I misinterpreted your intention for the script? Link to comment Share on other sites More sharing options...
UEZ Posted October 28, 2017 Share Posted October 28, 2017 FYI: https://autoit.de/index.php?thread/85580-gdi-transparenz-problem-bei-bildüberlappung/&postID=685890#post685890 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 More sharing options...
qwert Posted October 29, 2017 Share Posted October 29, 2017 Thanks, UEZ. Your solution works well. But does your response mean that the approach that the OP took can't be made to work? I ask because the While loop (not OnEventMode) was better suited for an application that I had in mind. Link to comment Share on other sites More sharing options...
UEZ Posted October 29, 2017 Share Posted October 29, 2017 6 hours ago, qwert said: But does your response mean that the approach that the OP took can't be made to work? I ask because the While loop (not OnEventMode) was better suited for an application that I had in mind. Well, I got the same result as you have posted in #4 and I'm wondering why the solution #2 works properly for him!?!?. But that doesn't mean that the approach he made isn't good and you can use also this way or the OnEventMode - it depends on the architecture (how to achieve the goal of your program) of your code. The problem of objects (sprites) in GDI+ is that you cannot get information about them using the mouse cursor for drag 'n drop activities. Thus you have to find a workaround, e.g. using hidden GUI elements such as labels. The disadvantage is, as you already seen it, that the position of the hidden control is visible for a short time when you move it. There might be a way to suppress it... 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 More sharing options...
Sven-Seyfert Posted October 31, 2017 Author Share Posted October 31, 2017 On 27.10.2017 at 3:46 PM, qwert said: However, when I attempt to confirm the script, I get an unexpected result: the background of the window is transparent and properly displays the individual PNGs. But the transparency of individual PNGs is lost when they overlap. Have I misinterpreted your intention for the script? Hi @qwert, no you correctly interpreted my intention. I forgot to say, that I solve the overlap problem of the PNG images with a GDI+ buffer system which I want to implement. But the solution of @UEZ is a great help for my work. Thank you @UEZ for the explaination that I cannot get information about the sprites by mouse and so on (I didn't know) . Thanks for your help - I'm grateful! Sven Link to comment Share on other sites More sharing options...
qwert Posted November 1, 2017 Share Posted November 1, 2017 22 hours ago, Sven-Seyfert said: that I solve the overlap problem of the PNG images with a GDI+ buffer system which I want to implement @Sven: thanks for clarifying that. As someone who has become interested in your particular approach (using a While loop) to manipulating images on a background, I would appreciate hearing about what changes you eventually make to solve the issues. Being somewhat familiar with GDI+ and layered GUIs, I would like to hear if it works out ... or if you use the OnEventMode method UEZ put forth. In either case, thanks for posting this topic and your example. Link to comment Share on other sites More sharing options...
argumentum Posted November 7, 2017 Share Posted November 7, 2017 (edited) On 11/1/2017 at 0:24 PM, qwert said: I would appreciate hearing about what changes you eventually make to solve the issues. I don't mean to butt in but, this is a merge of both and ( in my view ) the solution, as @Sven-Seyfert showed a transparent background as his preference. expandcollapse popup;coded by UEZ ; https://autoit.de/index.php?thread/85580-gdi-transparenz-problem-bei-bild%C3%BCberlappung/&postID=685890#post685890 #include <GDIPlus.au3> #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> _GDIPlus_Startup() Global $hGUI, $bExit Global Const $iW = @DesktopWidth * 0.95, $iH = @DesktopHeight * 0.90, $iWh = $iW / 2, $iHh = $iH / 2, $sTitle = "GDI+ Test" AutoItSetOption("GUIOnEventMode", 1) GDIPlus_Test() AutoItSetOption("GUIOnEventMode", 0) _GDIPlus_Shutdown() Func GDIPlus_Test() $bExit = False $hGUI = GUICreate($sTitle, $iW, $iH, -1, -1, -1, $WS_EX_LAYERED) ; <- changed here GUISetState(@SW_SHOW, $hGUI) GUISetBkColor( 0xABCDEF ) ; <- changed here _WinAPI_SetLayeredWindowAttributes( $hGUI, 0xABCDEF, 255 ) ; <- changed here Local Const $hDC = _WinAPI_GetDC($hGUI) Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC) Local Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap) Local Const $hCanvas = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer) _GDIPlus_GraphicsSetSmoothingMode($hCanvas, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsSetPixelOffsetMode($hCanvas, $GDIP_PIXELOFFSETMODE_HIGHQUALITY) Local $aSprites[3][6], $i, $iDX, $iDY, $iControl, $aInfo, $aCtrlPos For $i = 0 To UBound($aSprites) - 1 $aSprites[$i][0] = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\tree0" & $i + 1 & "_01.png") $aSprites[$i][1] = _GDIPlus_ImageGetWidth($aSprites[$i][0]) $aSprites[$i][2] = _GDIPlus_ImageGetHeight($aSprites[$i][0]) $aSprites[$i][3] = Random(0, $iW - $aSprites[$i][1], 1) $aSprites[$i][4] = Random(0, $iH - $aSprites[$i][2], 1) $aSprites[$i][5] = GUICtrlCreateLabel("", $aSprites[$i][3], $aSprites[$i][4], $aSprites[$i][1], $aSprites[$i][2]) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) _GDIPlus_GraphicsDrawImageRect($hCanvas, $aSprites[$i][0], $aSprites[$i][3], $aSprites[$i][4], $aSprites[$i][1], $aSprites[$i][2]) Next Local Const $hBrush_Clr = _GDIPlus_BrushCreateSolid(0xFFABCDEF), _ ; <- changed here $hBrush_FPS = _GDIPlus_BrushCreateSolid(0xFFABCDEF) ; <- changed here $iFPS = 0 GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_About") Do DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush_Clr, "float", 0, "float", 0, "float", $iW, "float", $iH) $aInfo = GUIGetCursorInfo($hGUI) If $aInfo[2] And $aInfo[4] Then $iControl = FindCtrl($aInfo[4], $aSprites) If Not @error Then $iDX = Abs(MouseGetPos(0) - $aSprites[$iControl][3]) $iDY = Abs(MouseGetPos(1) - $aSprites[$iControl][4]) Do DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush_Clr, "float", 0, "float", 0, "float", $iW, "float", $iH) $aInfo = GUIGetCursorInfo($hGUI) $aCtrlPos = ControlGetPos($hGUI, "", $aSprites[$iControl][5]) $aSprites[$iControl][3] = MouseGetPos(0) - $iDX $aSprites[$iControl][4] = MouseGetPos(1) - $iDY For $i = 0 To UBound($aSprites) - 1 _GDIPlus_GraphicsDrawImageRect($hCanvas, $aSprites[$i][0], $aSprites[$i][3], $aSprites[$i][4], $aSprites[$i][1], $aSprites[$i][2]) Next _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hDC_backbuffer, 0, 0, $SRCCOPY) Until Not $aInfo[2] ControlMove($hGUI, "", $aSprites[$iControl][5], $aSprites[$iControl][3], $aSprites[$iControl][4]) EndIf Else For $i = 0 To UBound($aSprites) - 1 _GDIPlus_GraphicsDrawImageRect($hCanvas, $aSprites[$i][0], $aSprites[$i][3], $aSprites[$i][4], $aSprites[$i][1], $aSprites[$i][2]) Next EndIf _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hDC_backbuffer, 0, 0, $SRCCOPY) If $bExit Then ExitLoop Until Not Sleep(10) For $i = 0 To UBound($aSprites) - 1 _GDIPlus_ImageDispose($aSprites[$i][0]) Next _GDIPlus_BrushDispose($hBrush_Clr) _GDIPlus_BrushDispose($hBrush_FPS) _GDIPlus_GraphicsDispose($hCanvas) _WinAPI_SelectObject($hDC_backbuffer, $DC_obj) _WinAPI_DeleteDC($hDC_backbuffer) _WinAPI_DeleteObject($hHBitmap) _WinAPI_ReleaseDC($hGUI, $hDC) GUIDelete($hGUI) EndFunc ;==>GDIPlus_Test Func FindCtrl($iCtrl, $aArray) Local $i For $i = 0 To UBound($aArray) - 1 If $aArray[$i][5] = $iCtrl Then Return $i Next Return SetError(0, 0, -1) EndFunc Func _Exit_About() $bExit = True EndFunc ;==>_Exit_About Edited November 7, 2017 by argumentum added pic. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
qwert Posted November 8, 2017 Share Posted November 8, 2017 @augumentum: excellent work! It worked like you indicated it would. And by changing one statement, I was able to have a colored backdrop for the PNGs, which was something I was hoping for. _WinAPI_SetLayeredWindowAttributes( $hGUI, 0xABCDEe, 255 ) Granted, I haven't fully explored things in the context of a real application—like having text and JPGs on the layout—but it's a great start. Thanks for posting. argumentum and Earthshine 2 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now