Hallo Community,
ich habe ein Problem wenn ich ein mit GDI+ geladenes Bild (*.png), auf der GUI, auf eine andere Position ziehe (drag). Wenn ich das nächste Bild (von insgesamt drei) in die unmittelbare Nähe des ersten gezogenen Bildes ziehe, habe ich einen Überlappungseffekt, der nicht transparent ist, wie ich ihn gern hätte.
Das animierte GIF sollte hoffentlich mein Problem weiter erklären (wie auf GitHub).
Warum sind die GDI+ PNG Bilder nicht transparent auf der GUI?
Ich möchte nicht unbedingt ein Buffer System zur Darstellung einsetzen oder muss ich dies?
Danke für Vorschläge, Tipps und Hilfe - ich bin dankbar!
Sven
Vorher:
[Solved] Finale Lösung:
Danke der Community und besonders UEZ und @argumentum (EN Forum).
Code:
Code
#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 )
Alles anzeigen