JRowe Posted September 24, 2009 Share Posted September 24, 2009 I know it's reinventing the wheel, in one sense, but I've just hacked through the PNG as GUI code, and discovered that I could place large(unlimited?) numbers of windows containing semi-transparent png images as children of the parent GUI, that animate smoothly, without flicker,through both fading and moving, and register their events cleanly (i.e.mouse-over, click, drag, etc.) I have the basic idea for a message handler, but I'd like to reuse windows messages wherever possible, such as in the case of the $WM_NCHITTEST included in the PNG as GUI setup, which allowed dragging of the background image. I'llpost a demo tomorrow, after I clean things up a bit (I'm using pngsfrom all over my computer). Basically, the setup goes like this: Create a GUI with _GUICreate_Alpha, thanks to Kip. Func _GUICreate_Alpha($sTitle, $sPath, $iX=-1, $iY=-1, $iOpacity=255) Local $hGUI, $hImage, $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend $hImage = _GDIPlus_ImageLoadFromFile($sPath) $width = _GDIPlus_ImageGetWidth($hImage) $height = _GDIPlus_ImageGetHeight($hImage) $hGUI = GUICreate($sTitle, $width, $height, $iX, $iY, $WS_POPUP, $WS_EX_LAYERED) $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", $width) DllStructSetData($tSize, "Y", $height) $tSource = DllStructCreate($tagPOINT) $pSource = DllStructGetPtr($tSource) $tBlend = DllStructCreate($tagBLENDFUNCTION) $pBlend = DllStructGetPtr($tBlend) DllStructSetData($tBlend, "Alpha", $iOpacity) DllStructSetData($tBlend, "Format", 1) _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, 2) _WinAPI_ReleaseDC(0, $hScrDC) _WinAPI_SelectObject($hMemDC, $hOld) _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteObject($hImage) _WinAPI_DeleteDC($hMemDC) EndFunc Create a control container GUI, that contains normal windows controls, like inputs, edits, buttons, and so on. $controlGui= GUICreate("ControlGUI", 800, 600, 0, 0, $WS_POPUP,BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), WinGetHandle("My PNG GUI")) GUICtrlCreatePic(@ScriptDir & "\appIcons\grey.gif", 0, 0, 800, 600) GUICtrlSetState(-1, $GUI_DISABLE) $button1 = GuiCtrlCreateButton("test",100,100, 68,22) Create each individual additional GUI widget as a child of the "My PNG GUI" using the SetBitMap() function from lod3n. 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 I'dlike to UDF-ize this idea, and create advanced GUI widgets like Accordions, Carousels, and so on. Are there any resources or guidelines in designing something like this? I'd like to keep it to as little overhead as possible, and reuseexisting Windows functionality. So, I thought I'd post the idea here to see if I could interest any others in the idea. I'd love the assistance of a pro or two. I think it looks cool, and could lead to some great eye candy. It was a pain in the arse to get the PNGs to behave correctly. I kid you not. Major kudos to PaulIA, who made this stuff possible. [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center] Link to comment Share on other sites More sharing options...
JRowe Posted September 25, 2009 Author Share Posted September 25, 2009 http://www.autoitscript.com/forum/index.php?showtopic=102961 [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center] Link to comment Share on other sites More sharing options...
reb Posted September 25, 2009 Share Posted September 25, 2009 Very Interesting!! I converted one of my jpg photos to png and replaced it in your script. It works very well. Since these are buttons I guess you could click them and run a script. Lots of neat possibilities. Good work. REB MEASURE TWICE - CUT ONCE Link to comment Share on other sites More sharing options...
JRowe Posted September 25, 2009 Author Share Posted September 25, 2009 They aren't buttons, actually, they're individual windows, children of the parent image. However, they can be used as buttons by intercepting the button related interactions with the GUI (mousedown, mouseup.) I'm looking at the rotation and other animations people have done using the GDIPlus functions. There's a whole lot of stuff out there that's never been consolidated. This should be a lot of fun. [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center] Link to comment Share on other sites More sharing options...
reb Posted September 25, 2009 Share Posted September 25, 2009 My mistake. Thanks for the info on how to use them as buttons. It will be interesting to see how far this will go when everybody gets a look at your work. Should be lots of action then. REB MEASURE TWICE - CUT ONCE Link to comment Share on other sites More sharing options...
JRowe Posted September 26, 2009 Author Share Posted September 26, 2009 (edited) So I'm trying to come up with every conceivable basic element that is needed for more advanced functions. I have parenting, z order, dimensions, placement, styling, behaviors, user functions, event tracking, animations, animation target, transition type, and skinning. Animations happen outside of drawing. For example, a resize event would re-draw the GUI in the appropriate location. An animation event doesn't necessarily redraw the element, but can use the existing image and modify its location, orientation, or size.;String Name of Widget. Error thrown if Duplicate name tried $GUIArray[$n][0] = $Name ;Skin Name $GUIArray[$n][1] = $Skin ;Int $GUIArray[$n][2] = $X ;Int $GUIArray[$n][3] = $Y ;Int $GUIArray[$n][4] = $Width ;Int $GUIArray[$n][5] = $Height ;Relative z order, changes depending on parent object. $GUIArray[$n][6] = $ZOrder ;User Specified Data, handled in the $Notification function $GUIArray[$n][7] = $Data ;$GUIArray Index of Parent Element $GUIArray[$n][8] = $Parent ;Hardcoded "Type" of Widget $GUIArray[$n][9] = $Type ;0,1,2,4,8,16,32 and so on, binary delimited styles, using BitOr($PNGGUIModal) style, etc $GUIArray[$n][10] = $Styles ;Set by the main GUI loop on any event $GUIArray[$n][11] = $CurrentEvent ;Widget Function Name, can be redirected, disabled, etc - ButtonFnc for buttons, LabelFnc for labels, etc $GUIArray[$n][12] = $Notification ;Denotes type of Animation being performed. Fade, Translate, Rotate, Scale, Crop, etc. $GUIArray[$n][13] = $Animation ;Denotes Transition type $GUIArray[$n][14] = $Transition ;Denotes Current Animation target. Target depends onnimationType $GUIArray[$n][15] = $AnimationTarget ;Widget dependent flag denoting state of widget $GUIArray[$n][16] = $WidgetStateThe user will create a button like so:_PNGGUIButtonCreate($sMyButtonName, $x, $y, "Button Title", "myButtonFunction", $width=100, $height=25, $skin = "currentSkin", $Styles = "default")This would return the unique name of the button (if the $sMyButtonName string isn't unique, an error is thrown.)The user will only have to specify a name, a place, a title, and a function. The rest would be handled by the skin or the default parameters of the widget, or both.PNG GUI System:$myButton = _PNGGUIButtonCreate($sName, $x, $y, $Title, $Function)AutoIt GUI System:$myButton = GUICtrlCreateButton($sTitle, $x, $y)The PNG GUI system has two additional parameters for a plain vanilla widget, but when you take into consideration the attendant event handling required to fire an event for the default GUI system, the two are about equally easy to use.Animations will be a parameter used in the widget function. A widget can have different animation targets that respond to different events (color changes, fading,moving, and so on.) Animations will be time based, so that each loop of the GUI process will update the screen, so that animation speed will be independent of the system it's run on, and animations won't block the process. Transitions will allow different effects to be used, based on performance and visual expectations of the widget designer. Complex GUI interactions, such as the animation of an Accordion control, or a Sliding Menu Ribbon, or even an iTunes coverFlow control, can be easily defined, designed, and implemented with this specification of elements.I think I've covered all the bases, and I'll begin programming this system tomorrow afternoon. Please comment if you have any ideas, critiques, or insights, I truly appreciate any discussion. I especially want to know if anyone sees problems or redundancy that can be taken out of the system.Thanks! Edited September 26, 2009 by JRowe [center]However, like ninjas, cyber warriors operate in silence.AutoIt Chat Engine (+Chatbot) , Link Grammar for AutoIt , Simple Speech RecognitionArtificial Neural Networks UDF , Bayesian Networks UDF , Pattern Matching UDFTransparent PNG GUI Elements , Au3Irrlicht 2Advanced Mouse Events MonitorGrammar Database GeneratorTransitions & Tweening UDFPoker Hand Evaluator[/center] Link to comment Share on other sites More sharing options...
wraithdu Posted September 26, 2009 Share Posted September 26, 2009 This is a truly unique and amibitious project. I can't wait to see what you come up with. What you have so far sounds really well thought out and comprehensive. I don't think I have anything to add at the moment, maybe when we start to see some of it in action. I'd like to offer my assistance if you need some help. GDI+ isn't my strong suit, but I'll help with what I can. Link to comment Share on other sites More sharing options...
picea892 Posted September 28, 2009 Share Posted September 28, 2009 I did some monkeying around trying to make the moon go around the earth. I'm most of the way there but couldn't figure out a way to put the child gui behind the primary gui. I suspect there is a way but couldn't figure it out. Anyways here is the code. It might help in your endeavour. expandcollapse popup#include <GDIPlus.au3> #include <WindowsConstants.au3> #include <GuiConstantsEx.au3> #include <StaticConstants.au3> Global Const $AC_SRC_ALPHA = 1 Global $GuiSize = 100, $hScrDC, $hMemDC, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend Global $t1, $iX1 = 100, $iY1 = 100, $tPoint, $pPoint, $Speed = 3, $iValX = $Speed, $iValY = $Speed _GDIPlus_Startup() $pngSrc = @ScriptDir & "\earth.png" ; Load Image $oldImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\moon.png") ;ToolTip(_GDIPlus_ImageGetWidth($oldImage)&" x "&_GDIPlus_ImageGetHeight($oldImage)) ;This allows the png to be dragged by clicking anywhere on the main image. GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST") $GUI = _GUICreate_Alpha("Look at the shiny", $pngSrc) $myGuiHandle = WinGetHandle("Look at the shiny") GUISetState() ;This is an invisible control container. You can create regular windows controls on this panel. $controlGui = GUICreate("ControlGUI", 800, 800, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $myGuiHandle) GUICtrlSetBkColor($controlGui, 0xFF00FF) GUICtrlSetState(-1, $GUI_DISABLE) ;This png is draggable as if it were a child window. It has about 50 pixels at the top that allow it to be dragged $TransparentButtonTest = GUICreate("Test321", 300, 300, 350, 350, $WS_EX_MDICHILD, $WS_EX_LAYERED, $myGuiHandle) SetBitMap($TransparentButtonTest, $oldImage, 255) GUISetState() $iX1=350 $iY1=350 $iW=200 $iH=200 $direction=1 $size=1 While 1 $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE ExitLoop EndSelect sleep(30) WinMove($TransparentButtonTest,"",$iX1,$iY1) ; DllStructSetData($tPoint, "X", $iX1) ; Update point destination dll data structure X value. ; DllStructSetData($tPoint, "Y", $iY1) ; Update point destination dll data structure Y value. ; _WinAPI_UpdateLayeredWindow($TransparentButtonTest, $hScrDC, $pPoint, $pSize, $hMemDC, $pSource, 0, $pBlend, $AC_SRC_ALPHA) $hImage1=_ImageResize($iW,$iH) SetBitMap($TransparentButtonTest, $hImage1, 255) $iX1=$iX1+(3*$direction) $iY1=$iY1+(1*$direction) if $direction=1 Then $iW=$iW+(1*$size) $iH=$iH+(1*$size) EndIf If $iX1>325 and $iX1<375 and $size=1 Then $size=-1 elseIf $iX1>600 and $size=-1 Then $direction=-1 $size=1 elseIf $iX1<100 and $size=-1 Then $direction=1 $size=1 EndIf WEnd _GDIPlus_ImageDispose($oldImage) _GDIPlus_Shutdown() Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam) If ($hwnd = WinGetHandle("Look at the shiny")) And ($iMsg = $WM_NCHITTEST) Then Return $HTCAPTION EndIf EndFunc Func _GUICreate_Alpha($sTitle, $sPath, $iX=-1, $iY=-1, $iOpacity=255) Local $hGUI, $hImage, $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend $hImage = _GDIPlus_ImageLoadFromFile($sPath) $width = _GDIPlus_ImageGetWidth($hImage) $height = _GDIPlus_ImageGetHeight($hImage) $hGUI = GUICreate($sTitle, $width, $height, $iX, $iY, $WS_POPUP, $WS_EX_LAYERED) $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", $width) DllStructSetData($tSize, "Y", $height) $tSource = DllStructCreate($tagPOINT) $pSource = DllStructGetPtr($tSource) $tBlend = DllStructCreate($tagBLENDFUNCTION) $pBlend = DllStructGetPtr($tBlend) DllStructSetData($tBlend, "Alpha", $iOpacity) DllStructSetData($tBlend, "Format", 1) _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, 2) _WinAPI_ReleaseDC(0, $hScrDC) _WinAPI_SelectObject($hMemDC, $hOld) _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteObject($hImage) _WinAPI_DeleteDC($hMemDC) EndFunc ;==>_GUICreate_Alpha 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) $tPoint = DllStructCreate($tagPOINT) ; Create point destination structure here $pPoint = DllStructGetPtr($tPoint) ; Create pointer to this dll data structure, $pPTDest parameter 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 _ImageDrawText($hImage, $sText, $iX = 0, $iY = 0, $iRGB = 0x000000, $iSize = 9, $iStyle = 0, $sFont = "Arial") Local $w, $h, $hGraphic1, $hBitmap, $hGraphic2, $hBrush, $hFormat, $hFamily, $hFont, $tLayout, $aInfo $w = _GDIPlus_ImageGetWidth($hImage) $h = _GDIPlus_ImageGetHeight($hImage) ;Create a new bitmap, this way the original opened png is left unchanged $hGraphic1 = _GDIPlus_GraphicsCreateFromHWND(_WinAPI_GetDesktopWindow()) $hBitmap = _GDIPlus_BitmapCreateFromGraphics($w, $h, $hGraphic1) $hGraphic2 = _GDIPlus_ImageGetGraphicsContext($hBitmap) ; Draw the original opened png into my newly created bitmap _GDIPlus_GraphicsDrawImageRect($hGraphic2, $hImage, 0, 0, $w, $h) ;Create the font $hBrush = _GDIPlus_BrushCreateSolid ("0xFF" & Hex($iRGB, 6)) $hFormat = _GDIPlus_StringFormatCreate() $hFamily = _GDIPlus_FontFamilyCreate ($sFont) $hFont = _GDIPlus_FontCreate ($hFamily, $iSize, $iStyle) $tLayout = _GDIPlus_RectFCreate ($iX, $iY, 0, 0) $aInfo = _GDIPlus_GraphicsMeasureString ($hGraphic2, $sText, $hFont, $tLayout, $hFormat) ;Draw the font onto the new bitmap _GDIPlus_GraphicsDrawStringEx ($hGraphic2, $sText, $hFont, $aInfo[0], $hFormat, $hBrush) ;Cleanup the no longer needed resources _GDIPlus_FontDispose ($hFont) _GDIPlus_FontFamilyDispose ($hFamily) _GDIPlus_StringFormatDispose ($hFormat) _GDIPlus_BrushDispose ($hBrush) _GDIPlus_GraphicsDispose ($hGraphic2) _GDIPlus_GraphicsDispose ($hGraphic1) ;Return the new bitmap Return $hBitmap EndFunc Func _ImageResize($newW, $newH) Local $GC, $newBmp, $newGC ;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) ;Cleanup ;_GDIPlus_BitmapDispose($newBmp) _GDIPlus_GraphicsDispose($GC) _GDIPlus_GraphicsDispose($newGC) Return $newBmp EndFunc ;==>_ImageResize Link to comment Share on other sites More sharing options...
a440hz Posted May 12, 2010 Share Posted May 12, 2010 Excellent work! How DOES one place a Child behind the MainGUI? Something to do with z-order but I can't get _WinAPI_SetWindowPos to work with $WS_EX_MDICHILD. Are you experienced? 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