Aus einem alten Script, das ich für jemanden geschrieben habe der ein Bild eines Fensterrahmens verlustfrei skalieren wollte (in einzelnen Segmenten). Das sollte dann als Rahmen für eine Halbtransparente GUI dienen.
Daraus habe ich aufgrund dieses Threads das hier gemacht:
Spoiler anzeigen
#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <Misc.au3>
; - Author: name22 (http://www.autoit.de)
[/autoit] [autoit][/autoit] [autoit]Opt("GUIOnEventMode", 1)
[/autoit] [autoit][/autoit] [autoit]Global Const $nPiHalf = ACos(-1) / 2
Global $vU32dll = DllOpen("user32.dll")
;###-v-SETTINGS-v-###
[/autoit] [autoit][/autoit] [autoit]$sPath_Icons = StringRegExpReplace(@AutoItExe, "(.+)\\[^\\]+", "$1\\Examples\\GUI") ;Pfad zum Bilderordner
$iDurationON = 600 ;Zeit für das Einblenden des Fensters [in ms]
$iDurationOFF = 400 ;Zeit für das Ausblenden des Fensters [in ms]
$iIconWidthMax = 200 ;Maximale Breite der Icons
$iIconHeightMax = 150 ;Maximale Höhe der Icons
$iARGB_HoverColor = 0xE05090D0 ;Farbe des Hover-Rahmens
;###-^-SETTINGS-^-###
[/autoit] [autoit][/autoit] [autoit]$bClick = False
$iCurSel = 0
$iLastSel = 0
$tSize = DllStructCreate($tagSIZE)
$pSize = DllStructGetPtr($tSize)
$tDest = DllStructCreate($tagSIZE)
$pDest = DllStructGetPtr($tDest)
$tSource = DllStructCreate($tagPOINT)
$pSource = DllStructGetPtr($tSource)
$tBlend = DllStructCreate($tagBLENDFUNCTION)
$pBlend = DllStructGetPtr($tBlend)
DllStructSetData($tBlend, "Format", 1)
_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]$hPen_Hover = _GDIPlus_PenCreate($iARGB_HoverColor, 3)
[/autoit] [autoit][/autoit] [autoit]$hImage_BG = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\bg.png")
$aBG_Glass = _CutImage($hImage_BG)
$aIcons = _GetIcons($sPath_Icons)
$iGUIWidth = ($iIconWidthMax + 5) * $aIcons[0][0] + 36
$iGUIHeight = $iIconHeightMax + 37
$hMain = GUICreate("Example by name22", $iGUIWidth, $iGUIHeight, Default, Default, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
GUISetState()
$hDC_Main = _WinAPI_GetDC($hMain)
$hDC_Buffer = _WinAPI_CreateCompatibleDC($hDC_Main)
$hBitmap_Buffer = _WinAPI_CreateCompatibleBitmap($hDC_Main, $iGUIWidth, $iGUIHeight)
_WinAPI_SelectObject($hDC_Buffer, $hBitmap_Buffer)
$hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC_Buffer)
_GDIPlus_GraphicsSetSmoothingMode($hGraphics, 2)
GUIRegisterMsg($WM_PAINT, "_RedrawGUI")
GUISetOnEvent($GUI_EVENT_CLOSE, "_Close", $hMain)
OnAutoItExitRegister("_Shutdown")
HotKeySet("{F10}", "_Show")
[/autoit] [autoit][/autoit] [autoit]While Sleep(1000)
WEnd
Func _Show()
HotKeySet("{F10}")
Local $bComplete = False, $iTimeOffset = 0, $iTime, $vTimer = TimerInit()
GUISetState(@SW_SHOW, $hMain)
While _IsPressed("79", $vU32dll)
$iTime = Floor(TimerDiff($vTimer))
If $iTime < $iDurationON Then
$nFrac = Sin($iTime / $iDurationON * $nPiHalf)
$iWidthTmp = $nFrac * $iGUIWidth
$iHeightTmp = $nFrac * $iGUIHeight
$iAlphaTmp = Floor($nFrac * 0xFF)
_GUISettings($iWidthTmp, $iHeightTmp, @DesktopWidth / 2 - $iWidthTmp / 2, @DesktopHeight / 2 - $iHeightTmp / 2, $iAlphaTmp)
Else
If Not $bComplete Then
$bComplete = True
_GUISettings($iGUIWidth, $iGUIHeight, @DesktopWidth / 2 - $iGUIWidth / 2, @DesktopHeight / 2 - $iGUIHeight / 2)
_DrawIcons()
_RedrawGUI()
GUIRegisterMsg($WM_MOUSEMOVE, "_MouseMove")
GUIRegisterMsg($WM_LBUTTONDOWN, "_MouseClick")
EndIf
If $iCurSel <> $iLastSel Then
$iLastSel = $iCurSel
_GDIPlus_GraphicsClear($hGraphics, 0)
_DrawBG($aBG_Glass, $iGUIWidth, $iGUIHeight)
_DrawIcons($iCurSel)
_RedrawGUI()
EndIf
If $bClick Then
$bClick = False
ConsoleWrite("Icon " & $iCurSel & @CRLF)
EndIf
EndIf
Sleep(10)
WEnd
GUIRegisterMsg($WM_MOUSEMOVE, "")
GUIRegisterMsg($WM_LBUTTONDOWN, "")
HotKeySet("{F10}", "_Show")
If $iTime <= $iDurationON Then
$iTimeOffset = $iDurationOFF - $iTime / $iDurationON * $iDurationOFF
EndIf
$iTime = 0
$vTimer = TimerInit()
While $iTime <= $iDurationOFF
$iTime = Floor(TimerDiff($vTimer)) + $iTimeOffset
$nFrac = Sin((1 - $iTime / $iDurationOFF) * $nPiHalf)
$iWidthTmp = $nFrac * $iGUIWidth
$iHeightTmp = $nFrac * $iGUIHeight
$iAlphaTmp = Floor($nFrac * 0xFF)
_GUISettings($iWidthTmp, $iHeightTmp, @DesktopWidth / 2 - $iWidthTmp / 2, @DesktopHeight / 2 - $iHeightTmp / 2, $iAlphaTmp)
Sleep(10)
WEnd
_GUISettings(0, 0, 0, 0, 0)
GUISetState(@SW_HIDE, $hMain)
EndFunc
Func _MouseMove($hWnd, $Msg, $wParam, $lParam)
Local $tMouse = DllStructCreate($tagPOINT)
DllStructSetData($tMouse, "X", _WinAPI_LoWord($lParam))
DllStructSetData($tMouse, "Y", _WinAPI_HiWord($lParam))
For $i = 1 To $aIcons[0][0]
If _WinAPI_PtInRect($aIcons[$i][5], $tMouse) Then
$iCurSel = $i
Return $GUI_RUNDEFMSG
EndIf
Next
$iCurSel = 0
EndFunc
Func _MouseClick()
$bClick = True
EndFunc
Func _GUISettings($iWidth, $iHeight, $iX = -1, $iY = -1, $iAlpha = 255)
DllStructSetData($tBlend, "Alpha", $iAlpha)
DllStructSetData($tSize, "X", $iWidth)
DllStructSetData($tSize, "Y", $iHeight)
_WinAPI_DeleteObject($hBitmap_Buffer)
_GDIPlus_GraphicsDispose($hGraphics)
$hBitmap_Buffer = _WinAPI_CreateCompatibleBitmap($hDC_Main, $iWidth, $iHeight)
_WinAPI_SelectObject($hDC_Buffer, $hBitmap_Buffer)
$hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC_Buffer)
_GDIPlus_GraphicsSetSmoothingMode($hGraphics, 2)
_GDIPlus_GraphicsClear($hGraphics, 0)
_DrawBG($aBG_Glass, $iWidth, $iHeight)
If $iX = -1 And $iY = -1 Then
_RedrawGUI()
Else
DllStructSetData($tDest, "X", Floor($iX))
DllStructSetData($tDest, "Y", Floor($iY))
_WinAPI_UpdateLayeredWindow($hMain, $hDC_Main, $pDest, $pSize, $hDC_Buffer, $pSource, 0, $pBlend, $ULW_ALPHA)
EndIf
EndFunc
Func _DrawBG($aBG, $iWidth, $iHeight)
_GDIPlus_GraphicsSetSmoothingMode($hGraphics, 0)
_GDIPlus_GraphicsSetInterpolationMode($hGraphics, 5)
_GDIPlus_GraphicsSetPixelOffsetMode($hGraphics, 2)
_GDIPlus_GraphicsDrawImageRect($hGraphics, $aBG[0], 0, 0, 20, 20) ;upper left corner
_GDIPlus_GraphicsDrawImageRect($hGraphics, $aBG[1], 0, $iHeight - 17, 20, 17) ;lower left corner
_GDIPlus_GraphicsDrawImageRect($hGraphics, $aBG[2], $iWidth - 21, 0, 21, 20) ;upper right corner
_GDIPlus_GraphicsDrawImageRect($hGraphics, $aBG[3], $iWidth - 21, $iHeight - 17, 21, 17) ;lower right corner
_GDIPlus_GraphicsDrawImageRect($hGraphics, $aBG[4], 0, 20, 20, $iHeight - 37) ;left edge
_GDIPlus_GraphicsDrawImageRect($hGraphics, $aBG[5], $iWidth - 21, 20, 21, $iHeight - 37) ;right edge
_GDIPlus_GraphicsDrawImageRect($hGraphics, $aBG[6], 20, 0, $iWidth - 41, 20) ;upper edge
_GDIPlus_GraphicsDrawImageRect($hGraphics, $aBG[7], 20, $iHeight - 17, $iWidth - 41, 17) ;lower edge
_GDIPlus_GraphicsDrawImageRect($hGraphics, $aBG[8], 20, 20, $iWidth - 41, $iHeight - 37) ;center
_GDIPlus_GraphicsSetSmoothingMode($hGraphics, 2)
EndFunc
Func _DrawIcons($iHover = 4)
For $i = 1 To $aIcons[0][0]
_GDIPlus_GraphicsDrawImageRect($hGraphics, $aIcons[$i][0], $aIcons[$i][1], $aIcons[$i][2], $aIcons[$i][3], $aIcons[$i][4])
If $i = $iHover Then _GDIPlus_GraphicsDrawRect($hGraphics, $aIcons[$i][1] - 1, $aIcons[$i][2] - 1, $aIcons[$i][3] + 2, $aIcons[$i][4] + 2, $hPen_Hover)
Next
EndFunc
Func _GetIcons($sPath)
Local $aReturn[1][6] = [[0]]
Local $hSearch = FileFindFirstFile($sPath & "\*.*"), $iCount = 0
While True
$sFile = FileFindNextFile($hSearch)
If @error Then ExitLoop
If Not @extended And StringRegExp($sFile, ".+\.(jpg)|(jpeg)|(tif)|(tiff)|(png)|(bmp)|(gif)\z") Then
$aReturn[0][0] += 1
ReDim $aReturn[$aReturn[0][0] + 1][6]
$aReturn[$aReturn[0][0]][3] = False
$aReturn[$aReturn[0][0]][0] = _GDIPlus_ImageLoadFromFile($sPath & "\" & $sFile)
$iWidthTmp = _GDIPlus_ImageGetWidth($aReturn[$aReturn[0][0]][0])
$iHeightTmp = _GDIPlus_ImageGetHeight($aReturn[$aReturn[0][0]][0])
If $iWidthTmp > $iIconWidthMax Or $iHeightTmp > $iIconHeightMax Then
If ($iWidthTmp - $iIconWidthMax) >= ($iHeightTmp - $iIconHeightMax) Then
$iHeightTmp = $iIconHeightMax * ($iHeightTmp / $iWidthTmp)
$iWidthTmp = $iIconWidthMax
Else
$iWidthTmp = $iIconWidthMax * ($iHeightTmp / $iWidthTmp)
$iHeightTmp = $iIconHeightMax
EndIf
$hBitmapTmp = _GDIPlus_BitmapCreateFromScan0($iWidthTmp, $iHeightTmp)
$hGraphicsTmp = _GDIPlus_ImageGetGraphicsContext($hBitmapTmp)
_GDIPlus_GraphicsDrawImageRect($hGraphicsTmp, $aReturn[$aReturn[0][0]][0], 0, 0, $iWidthTmp, $iHeightTmp)
_GDIPlus_GraphicsDispose($hGraphicsTmp)
_GDIPlus_ImageDispose($aReturn[$aReturn[0][0]][0])
$aReturn[$aReturn[0][0]][0] = $hBitmapTmp
EndIf
$aReturn[$aReturn[0][0]][3] = $iWidthTmp
$aReturn[$aReturn[0][0]][4] = $iHeightTmp
$aReturn[$aReturn[0][0]][1] = Round($iIconWidthMax / 2 - $iWidthTmp / 2) + 20 + $iCount * ($iIconWidthMax + 5)
$aReturn[$aReturn[0][0]][2] = Round($iIconHeightMax / 2 - $iHeightTmp / 2) + 20
$aReturn[$aReturn[0][0]][5] = DllStructCreate($tagRECT)
DllStructSetData($aReturn[$aReturn[0][0]][5], "Left", $aReturn[$aReturn[0][0]][1])
DllStructSetData($aReturn[$aReturn[0][0]][5], "Top", $aReturn[$aReturn[0][0]][2])
DllStructSetData($aReturn[$aReturn[0][0]][5], "Right", $aReturn[$aReturn[0][0]][1] + $iWidthTmp)
DllStructSetData($aReturn[$aReturn[0][0]][5], "Bottom", $aReturn[$aReturn[0][0]][2] + $iHeightTmp)
$iCount += 1
EndIf
WEnd
Return $aReturn
EndFunc
Func _CutImage($hImage)
Local $aReturn[9]
$aReturn[0] = _GDIPlus_BitmapCloneArea($hImage, 0, 0, 20, 20, $GDIP_PXF32ARGB) ;upper left corner
$aReturn[1] = _GDIPlus_BitmapCloneArea($hImage, 0, 87, 20, 17, $GDIP_PXF32ARGB) ;lower left corner
$aReturn[2] = _GDIPlus_BitmapCloneArea($hImage, 86, 0, 21, 20, $GDIP_PXF32ARGB) ;upper right corner
$aReturn[3] = _GDIPlus_BitmapCloneArea($hImage, 86, 87, 21, 17, $GDIP_PXF32ARGB) ;lower right corner
$aReturn[4] = _GDIPlus_BitmapCloneArea($hImage, 0, 20, 20, 67, $GDIP_PXF32ARGB) ;left edge
$aReturn[5] = _GDIPlus_BitmapCloneArea($hImage, 86, 20, 21, 67, $GDIP_PXF32ARGB) ;right edge
$aReturn[6] = _GDIPlus_BitmapCloneArea($hImage, 20, 0, 66, 20, $GDIP_PXF32ARGB) ;upper edge
$aReturn[7] = _GDIPlus_BitmapCloneArea($hImage, 20, 87, 66, 17, $GDIP_PXF32ARGB) ;lower edge
$aReturn[8] = _GDIPlus_BitmapCloneArea($hImage, 20, 20, 66, 67, $GDIP_PXF32ARGB) ;center
Return $aReturn
EndFunc
Func _RedrawGUI()
_WinAPI_UpdateLayeredWindow($hMain, $hDC_Main, 0, $pSize, $hDC_Buffer, $pSource, 0, $pBlend, $ULW_ALPHA)
EndFunc
Func _Close()
Exit
EndFunc ;==>_Close
Func _Shutdown()
_WinAPI_ReleaseDC($hMain, $hDC_Main)
_WinAPI_DeleteDC($hDC_Buffer)
_WinAPI_DeleteObject($hBitmap_Buffer)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_ImageDispose($hImage_BG)
For $i = 0 To 8
_GDIPlus_BitmapDispose($aBG_Glass[$i])
Next
For $i = 1 To $aIcons[0][0]
_GDIPlus_ImageDispose($aIcons[$i][0])
Next
_GDIPlus_PenDispose($hPen_Hover)
_GDIPlus_Shutdown()
EndFunc ;==>_Shutdown
; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_GraphicsSetPixelOffsetMode
; Description ...: Sets the pixel offset mode of a Graphics object
; Syntax.........: _GDIPlus_GraphicsSetPixelOffsetMode($hGraphics, $iPixelOffsetMode)
; Parameters ....: $hGraphics - Pointer to a Graphics object
; $iPixelOffsetMode - Pixel offset mode:
; |0,1,3 - Pixel centers have integer coordinates
; |2,4 - Pixel centers have coordinates that are half way between integer values (i.e. 0.5, 20, 105.5, etc...)
; Return values .: Success - True
; Failure - False and either:
; |@error and @extended are set if DllCall failed
; |$GDIP_STATUS contains a non zero value specifying the error code
; Remarks .......: None
; Related .......: _GDIPlus_GraphicsGetPixelOffsetMode
; Link ..........; @@MsdnLink@@ GdipSetPixelOffsetMode
; Example .......; No
; ===============================================================================================================================
Func _GDIPlus_GraphicsSetPixelOffsetMode($hGraphics, $iPixelOffsetMode)
Local $aResult = DllCall($ghGDIPDll, "uint", "GdipSetPixelOffsetMode", "hwnd", $hGraphics, "int", $iPixelOffsetMode)
If @error Then Return SetError(@error, @extended, False)
$GDIP_STATUS = $aResult[0]
Return $aResult[0] = 0
EndFunc ;==>_GDIPlus_GraphicsSetPixelOffsetMode
; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_GraphicsSetInterpolationMode
; Description ...: Sets the interpolation mode of a Graphics object
; Syntax.........: _GDIPlus_GraphicsSetInterpolationMode($hGraphics, $iInterpolationMode)
; Parameters ....: $hGraphics - Pointer to a Graphics object
; $iInterpolationMode - Interpolation mode:
; |0 - Default interpolation mode
; |1 - Low-quality mode
; |2 - High-quality mode
; |3 - Bilinear interpolation. No prefiltering is done
; |4 - Bicubic interpolation. No prefiltering is done
; |5 - Nearest-neighbor interpolation
; |6 - High-quality, bilinear interpolation. Prefiltering is performed to ensure high-quality shrinking
; |7 - High-quality, bicubic interpolation. Prefiltering is performed to ensure high-quality shrinking
; Return values .: Success - True
; Failure - False and either:
; |@error and @extended are set if DllCall failed
; |$GDIP_STATUS contains a non zero value specifying the error code
; Remarks .......: The interpolation mode determines the algorithm that is used when images are scaled or rotated
; Related .......: _GDIPlus_GraphicsGetInterpolationMode
; Link ..........; @@MsdnLink@@ GdipSetInterpolationMode
; Example .......; No
; ===============================================================================================================================
Func _GDIPlus_GraphicsSetInterpolationMode($hGraphics, $iInterpolationMode)
Local $aResult = DllCall($ghGDIPDll, "uint", "GdipSetInterpolationMode", "hwnd", $hGraphics, "int", $iInterpolationMode)
If @error Then Return SetError(@error, @extended, False)
$GDIP_STATUS = $aResult[0]
Return $aResult[0] = 0
EndFunc ;==>_GDIPlus_GraphicsSetInterpolationMode
; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_BitmapCreateFromScan0
; Description ...: Creates a Bitmap object based on an array of bytes along with size and format information
; Syntax.........: _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight[, $iStride = 0[, $iPixelFormat = 0x0026200A[, $pScan0 = 0]]])
; Parameters ....: $iWidth - The bitmap width, in pixels
; $iHeight - The bitmap height, in pixels
; $iStride - Integer that specifies the byte offset between the beginning of one scan line and the next. This
; +is usually (but not necessarily) the number of bytes in the pixel format (for example, 2 for 16 bits per pixel)
; +multiplied by the width of the bitmap. The value passed to this parameter must be a multiple of four
; $iPixelFormat - Specifies the format of the pixel data. Can be one of the following:
; |$GDIP_PXF01INDEXED - 1 bpp, indexed
; |$GDIP_PXF04INDEXED - 4 bpp, indexed
; |$GDIP_PXF08INDEXED - 8 bpp, indexed
; |$GDIP_PXF16GRAYSCALE - 16 bpp, grayscale
; |$GDIP_PXF16RGB555 - 16 bpp; 5 bits for each RGB
; |$GDIP_PXF16RGB565 - 16 bpp; 5 bits red, 6 bits green, and 5 bits blue
; |$GDIP_PXF16ARGB1555 - 16 bpp; 1 bit for alpha and 5 bits for each RGB component
; |$GDIP_PXF24RGB - 24 bpp; 8 bits for each RGB
; |$GDIP_PXF32RGB - 32 bpp; 8 bits for each RGB. No alpha.
; |$GDIP_PXF32ARGB - 32 bpp; 8 bits for each RGB and alpha
; |$GDIP_PXF32PARGB - 32 bpp; 8 bits for each RGB and alpha, pre-mulitiplied
; $pScan0 - Pointer to an array of bytes that contains the pixel data. The caller is responsible for
; +allocating and freeing the block of memory pointed to by this parameter.
; Return values .: Success - Returns a handle to a new Bitmap object
; Failure - 0 and either:
; |@error and @extended are set if DllCall failed
; |$GDIP_STATUS contains a non zero value specifying the error code
; Remarks .......: After you are done with the object, call _GDIPlus_ImageDispose to release the object resources
; Related .......: _GDIPlus_ImageDispose
; Link ..........; @@MsdnLink@@ GdipCreateBitmapFromScan0
; Example .......; Yes
; ===============================================================================================================================
Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)
Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "int*", 0)
If @error Then Return SetError(@error, @extended, 0)
$GDIP_STATUS = $aResult[0]
Return $aResult[6]
EndFunc ;==>_GDIPlus_BitmapCreateFromScan0
Es sieht ein bisschen aus wie das Aero Fenster das erscheint wenn man Alt+Tab in WinVista/Win7 gedrückt hält (Auswahl des aktiven Fensters). Nur die Ein-/Ausblendungs Animation sieht cooler aus :D.
Das Bild im Anhang muss im Scriptverzeichnis gespeichert werden. Danach kann man das Fenster mit F10 einblenden.
Es ist also ein kleines Auswahlfenster á la Alt+Tab. Ich habe keine Ahnung wofür man so etwas gebrauchen kann, aber da hier so viele Funktionen und Prinzipien verwendet werden, die oft nicht zum Einsatz kommen und trotzdem nützlich wären, dachte ich ich könnte es ja mal hier reinstellen :). Außerdem lässt sich das a beliebig erweitern oder aufteilen. Man könnte zum Beispiel nur den Teil mit der Mauszeigerabfrage als Basis für ein paar eigene GDI+ Buttons verwenden.
Viel Spaß. Bemerkungen sind, wie immer, erwünscht.