TrueSR Posted November 1, 2008 Posted November 1, 2008 (edited) Hi all,I'm experimenting with png's as GUI's, but i have a question :Is it possible to stretch a png file and then use it as GUI ?Example to explain a bit more :I have a nice png here :Script (thanks lod3n, PaulIA and GaryFrost) :expandcollapse popup#include <GDIPlus.au3>; this is where the magic happens, people #include <WindowsConstants.au3> #include <GuiConstantsEx.au3> Opt("MustDeclareVars", 0) Global Const $AC_SRC_ALPHA = 1 ;~ Global Const $ULW_ALPHA = 2 ; Load PNG file as GDI bitmap _GDIPlus_Startup() $pngSrc = @ScriptDir & "\back.png" $hImage = _GDIPlus_ImageLoadFromFile($pngSrc) ; Extract image width and height from PNG $width = _GDIPlus_ImageGetWidth($hImage) $height = _GDIPlus_ImageGetHeight($hImage) ; Create layered window $GUI = GUICreate("Test GUI", $width, $height, -1, -1, $WS_POPUP, $WS_EX_LAYERED) SetBitmap($GUI, $hImage, 255) ; Register notification messages GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST") GUISetState() WinSetOnTop($GUI, "", 1) ; create child MDI gui window to hold controls ; this part could use some work - there is some flicker sometimes... $controlGui = GUICreate("ControlGUI", $width, $height, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $GUI) ; child window transparency is required to accomplish the full effect, so $WS_EX_LAYERED above, and ; I think the way this works is the transparent window color is based on the image you set here: GUICtrlCreatePic(@ScriptDir & "\grey.gif", 0, 0, $width, $height) GUICtrlSetState(-1, $GUI_DISABLE) GUISetState() While 1 $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE ExitLoop EndSelect WEnd GUIDelete($controlGui) ; Release resources _WinAPI_DeleteObject($hImage) _GDIPlus_Shutdown() ; ==================================================================================================== ; Handle the WM_NCHITTEST for the layered window so it can be dragged by clicking anywhere on the image. ; ==================================================================================================== Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam) If ($hWnd = $GUI) And ($iMsg = $WM_NCHITTEST) Then Return $HTCAPTION EndFunc ;==>WM_NCHITTEST ; ==================================================================================================== ; SetBitMap ; ==================================================================================================== Func SetBitmap($hGUI, $hImage, $iOpacity) Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend $hScrDC = _WinAPI_GetDC(0) $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC) $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap) $tSize = DllStructCreate($tagSIZE) $pSize = DllStructGetPtr($tSize) DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage)) DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage)) $tSource = DllStructCreate($tagPOINT) $pSource = DllStructGetPtr($tSource) $tBlend = DllStructCreate($tagBLENDFUNCTION) $pBlend = DllStructGetPtr($tBlend) DllStructSetData($tBlend, "Alpha", $iOpacity) DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA) _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA) _WinAPI_ReleaseDC(0, $hScrDC) _WinAPI_SelectObject($hMemDC, $hOld) _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteDC($hMemDC) EndFunc ;==>SetBitmapHere is the grey.gif :So i want the GUI about 500 pixels width.It would be even greater if it is possible to take the center of the png and stretch that,so you still have the nice left and right side of the png.Thanks Edited November 1, 2008 by TrueSR
Andreik Posted November 1, 2008 Posted November 1, 2008 You can resize the image before use like this (at the end of script you can delete the new image): expandcollapse popup#include <GDIPlus.au3>; this is where the magic happens, people #include <WindowsConstants.au3> #include <GuiConstantsEx.au3> Opt("MustDeclareVars", 0) Global Const $AC_SRC_ALPHA = 1 ;~ Global Const $ULW_ALPHA = 2 ; Load PNG file as GDI bitmap _GDIPlus_Startup() $pngSrc = @ScriptDir & "\back.png" $hImage = _GDIPlus_ImageLoadFromFile($pngSrc) ; Extract image width and height from PNG $width = _GDIPlus_ImageGetHeight($hImage) $height = _GDIPlus_ImageGetHeight($hImage) If $width < 500 Then _ImageResize(@ScriptDir & "\back.png",@ScriptDir & "\resize_back.png",500, $height) $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\resize_back.png") $width = _GDIPlus_ImageGetHeight($hImage) $height = _GDIPlus_ImageGetHeight($hImage) EndIf ; Create layered window $GUI = GUICreate("Test GUI", $width, $height, -1, -1, $WS_POPUP, $WS_EX_LAYERED) SetBitmap($GUI, $hImage, 255) ; Register notification messages GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST") GUISetState() WinSetOnTop($GUI, "", 1) ; create child MDI gui window to hold controls ; this part could use some work - there is some flicker sometimes... $controlGui = GUICreate("ControlGUI", $width, $height, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $GUI) ; child window transparency is required to accomplish the full effect, so $WS_EX_LAYERED above, and ; I think the way this works is the transparent window color is based on the image you set here: GUICtrlCreatePic(@ScriptDir & "\grey.gif", 0, 0, $width, $height) GUICtrlSetState(-1, $GUI_DISABLE) GUISetState() While 1 $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE ExitLoop EndSelect WEnd GUIDelete($controlGui) ; Release resources _WinAPI_DeleteObject($hImage) _GDIPlus_Shutdown() ; ==================================================================================================== ; Handle the WM_NCHITTEST for the layered window so it can be dragged by clicking anywhere on the image. ; ==================================================================================================== Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam) If ($hWnd = $GUI) And ($iMsg = $WM_NCHITTEST) Then Return $HTCAPTION EndFunc;==>WM_NCHITTEST ; ==================================================================================================== ; SetBitMap ; ==================================================================================================== Func SetBitmap($hGUI, $hImage, $iOpacity) Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend $hScrDC = _WinAPI_GetDC(0) $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC) $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap) $tSize = DllStructCreate($tagSIZE) $pSize = DllStructGetPtr($tSize) DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage)) DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage)) $tSource = DllStructCreate($tagPOINT) $pSource = DllStructGetPtr($tSource) $tBlend = DllStructCreate($tagBLENDFUNCTION) $pBlend = DllStructGetPtr($tBlend) DllStructSetData($tBlend, "Alpha", $iOpacity) DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA) _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA) _WinAPI_ReleaseDC(0, $hScrDC) _WinAPI_SelectObject($hMemDC, $hOld) _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteDC($hMemDC) EndFunc;==>SetBitmap Func _ImageResize($sInImage, $sOutImage, $newW, $newH) Local $oldImage, $GC, $newBmp, $newGC _GDIPlus_Startup() ; Load Image $oldImage = _GDIPlus_ImageLoadFromFile($sInImage) ;Create New image $GC = _GDIPlus_ImageGetGraphicsContext($oldImage) $newBmp = _GDIPlus_BitmapCreateFromGraphics($newW, $newH, $GC) $newGC = _GDIPlus_ImageGetGraphicsContext($newBmp) ;Draw _GDIPlus_GraphicsDrawImageRect($newGC, $oldImage, 0, 0, $newW, $newH) _GDIPlus_ImageSaveToFile($newBmp, $sOutImage) ;Clenaup _GDIPlus_GraphicsDispose($GC) _GDIPlus_GraphicsDispose($newGC) _GDIPlus_BitmapDispose($newBmp) _GDIPlus_ImageDispose($oldImage) _GDIPlus_Shutdown() EndFunc ;==>_ImageResize
TrueSR Posted November 1, 2008 Author Posted November 1, 2008 Thanks ! Works great ! And you can get the center of the image with _GDIPlus_BitmapCloneArea right ?
Andreik Posted November 1, 2008 Posted November 1, 2008 Thanks ! Works great !And you can get the center of the image with _GDIPlus_BitmapCloneArea right ?I don't know about what center are you talking.The center of image should be:$X = Width/2$Y = Height/2If I`m wrong please correct me. Or you want to say something else.
TrueSR Posted November 1, 2008 Author Posted November 1, 2008 I mean this piece :Cut away 40 pixels from the left and 40 from the right.Sorry if it wasn't clear.
Andreik Posted November 1, 2008 Posted November 1, 2008 I mean this piece :Cut away 40 pixels from the left and 40 from the right.Sorry if it wasn't clear.No need to say sorry. Now I understand what you want to say.If you look in GDIPlus.au3 you`ll see that _GDIPlus_GraphicsDrawImageRect use function GdipDrawImageRectI from GDIPlus.dll ,no _GDIPlus_BitmapCloneArea, to resize the picture.
TrueSR Posted November 1, 2008 Author Posted November 1, 2008 No need to say sorry. Now I understand what you want to say.If you look in GDIPlus.au3 you`ll see that _GDIPlus_GraphicsDrawImageRect use function GdipDrawImageRectI from GDIPlus.dll ,no _GDIPlus_BitmapCloneArea, to resize the picture.Oké, thank you very much, you solved my question very fast !
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