Gianni Posted September 24, 2016 Posted September 24, 2016 (edited) Hi Is it possible to draw using a semitransparent paint? In short, I would like to paint on a Label control that contains text, and at the same time be able to see through the paint, so to see the text behind. Something like using an highlighter. Only to show the effect that I would achieve, here are two listings. The first, using transparency on the whole gui, allows to draw an ellipse into the gui's body showing at the same time what's beneath the ellipse's border. (the inner of the ellipse should be totally transparent.) Click on the GUI and drag to draw the ellipse. expandcollapse popup#include <Misc.au3> ; for _IsPressed (01 Left mouse button) #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> #include <WinAPIGdi.au3> Opt("MouseCoordMode", 0) Global $hUser32dll = DllOpen("user32.dll") ; for _IsPressed Local $aPos ; -- Create the GUI ------------------------------- Global $hGUI = GUICreate("Preview of an ellipse (click and drag to draw)", 400, 400, 100, 100, -1, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST)) Local $iTransparent = 0x0FF0FF ; tansparent color ; This sets which color to be transparent and opacity of the whole window _WinAPI_SetLayeredWindowAttributes($hGUI, $iTransparent, 127) ; last param opacity intensity: 0 totally transp, 255 NOT transp GUISetBkColor($iTransparent, $hGUI) ; background becomes transparent GUISetState(@SW_SHOW) ; MAIN LOOP While 1 $aPos = MouseGetPos() $aMsg = GUIGetMsg($GUI_EVENT_ARRAY) ; $GUI_EVENT_ARRAY -> returns an array containing the event and extended information Select Case $aMsg[0] = $GUI_EVENT_CLOSE ConsoleWrite("Bye" & @LF) Exit ; End() EndSelect If _IsPressed("01", $hUser32dll) Then ; draw the ellipse following mouse position. ; returns only when left mouse button is released _Preview_Ellipse($hGUI, $aPos[0], $aPos[1], 24) EndIf WEnd Func _Preview_Ellipse($hGUIx, $iX, $iY, $iPenSize = 9, $iColor = 0xFF0000, $iFill = 0x0FF0FF) ; Creates $tagRECT structure with the coordinates of the specified rectangle Local $tRECT = _WinAPI_CreateRect($iX, $iY, $iX, $iY) Local $hDC = _WinAPI_GetWindowDC($hGUIx) Local $hPen = _WinAPI_CreatePen($PS_SOLID, $iPenSize, $iColor) ; border size and color Local $hBrush = _WinAPI_CreateBrushIndirect($BS_SOLID, $iFill) ; fill color Local $hObj1 = _WinAPI_SelectObject($hDC, $hBrush) Local $hObj2 = _WinAPI_SelectObject($hDC, $hPen) Local $aPreviousPos[2], $aPos[2] While _IsPressed("01", $hUser32dll) ; stay here till left mouse button is released ; get the mouse coordinates: ; $aPos[0] = X coord (horizontal), $aPos[1] = Y coord (vertical) $aPos = MouseGetPos() ; if mouse has mooved then redraw the ellipse accordingly If $aPreviousPos[0] <> $aPos[0] Or $aPreviousPos[1] <> $aPos[1] Then ; mouse has mooved ; take track of new mouse position $aPreviousPos[0] = $aPos[0] $aPreviousPos[1] = $aPos[1] ; DllStructSetData($tRECT, 1, $iX) ; initial point is fixed ; DllStructSetData($tRECT, 2, $iY) DllStructSetData($tRECT, 3, $aPos[0]) ; new mouse position DllStructSetData($tRECT, 4, $aPos[1]) ; erase content of the gui (erase the previous ellipse) _WinAPI_RedrawWindow($hGUIx, 0, 0, BitOR($RDW_INVALIDATE, $RDW_ERASE, $RDW_UPDATENOW)) ; Draws the new ellipse (based on new mouse position) _WinAPI_Ellipse($hDC, $tRECT) EndIf ; WEnd ; if left button is released then exit ; free resources _WinAPI_SelectObject($hDC, $hObj1) _WinAPI_SelectObject($hDC, $hObj2) _WinAPI_DeleteObject($hPen) _WinAPI_DeleteObject($hBrush) _WinAPI_ReleaseDC($hGUIx, $hDC) _WinAPI_RedrawWindow($hGUIx, 0, 0, BitOR($RDW_INVALIDATE, $RDW_ERASE, $RDW_UPDATENOW)) ; erase content of the gui EndFunc ;==>_Preview_Ellipse This second listing is a botched attempt to achieve the same effect on a Label control located on a normal window (not transparent). expandcollapse popup#include <Misc.au3> ; for _IsPressed (01 Left mouse button) #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> #include <WinAPIGdi.au3> Opt("MouseCoordMode", 0) Global $hUser32dll = DllOpen("user32.dll") ; for _IsPressed Local $aPos ; -- Create the GUI ------------------------------- Global $hGUI = GUICreate("Preview of an ellipse (click and drag to draw)", 400, 400, 100, 100) ; , -1, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST)) ; Label Local $s = StringReplace(StringFormat('%22s', ""), " ", "the quick brown fox jumps over the lazy dog ") Local $hLabel = GUICtrlGetHandle(GUICtrlCreateLabel($s, 10, 10, 250, 250)) GUICtrlSetBkColor(-1, 0xAAAA00) ; Local $iTransparent = 0x0FF0FF ; tansparent color ; This sets which color to be transparent and opacity of the whole window ; _WinAPI_SetLayeredWindowAttributes($hGUI, $iTransparent, 127) ; last param opacity intensity: 0 totally transp, 255 NOT transp ; GUISetBkColor($iTransparent, $hGUI) ; background becomes transparent GUISetState(@SW_SHOW) ; MAIN LOOP While 1 $aPos = MouseGetPos() $aMsg = GUIGetMsg($GUI_EVENT_ARRAY) ; $GUI_EVENT_ARRAY -> returns an array containing the event and extended information Select Case $aMsg[0] = $GUI_EVENT_CLOSE ConsoleWrite("Bye" & @LF) Exit ; End() EndSelect If _IsPressed("01", $hUser32dll) Then ; draw the ellipse following mouse position. ; returns only when left mouse button is released _Preview_Ellipse($hLabel, $aPos[0], $aPos[1], 24) EndIf WEnd Func _Preview_Ellipse($hGUIx, $iX, $iY, $iPenSize = 9, $iColor = 0xFF0000, $iFill = 0x0FF0FF) ; Creates $tagRECT structure with the coordinates of the specified rectangle Local $tRECT = _WinAPI_CreateRect($iX, $iY, $iX, $iY) Local $hDC = _WinAPI_GetWindowDC($hGUIx) Local $hPen = _WinAPI_CreatePen($PS_SOLID, $iPenSize, $iColor) ; border size and color Local $hBrush = _WinAPI_CreateBrushIndirect($BS_SOLID, $iFill) ; fill color Local $hObj1 = _WinAPI_SelectObject($hDC, $hBrush) Local $hObj2 = _WinAPI_SelectObject($hDC, $hPen) Local $aPreviousPos[2], $aPos[2] While _IsPressed("01", $hUser32dll) ; stay here till left mouse button is released ; get the mouse coordinates: ; $aPos[0] = X coord (horizontal), $aPos[1] = Y coord (vertical) $aPos = MouseGetPos() ; if mouse has mooved then redraw the ellipse accordingly If $aPreviousPos[0] <> $aPos[0] Or $aPreviousPos[1] <> $aPos[1] Then ; mouse has mooved ; take track of new mouse position $aPreviousPos[0] = $aPos[0] $aPreviousPos[1] = $aPos[1] ; DllStructSetData($tRECT, 1, $iX) ; initial point is fixed ; DllStructSetData($tRECT, 2, $iY) DllStructSetData($tRECT, 3, $aPos[0]) ; new mouse position DllStructSetData($tRECT, 4, $aPos[1]) ; erase content of the gui (erase the previous ellipse) _WinAPI_RedrawWindow($hGUIx, $tRECT, 0, BitOR($RDW_INVALIDATE, $RDW_ERASE, $RDW_UPDATENOW)) ; Draws the new ellipse (based on new mouse position) _WinAPI_Ellipse($hDC, $tRECT) EndIf ; WEnd ; if left button is released then exit ; free resources _WinAPI_SelectObject($hDC, $hObj1) _WinAPI_SelectObject($hDC, $hObj2) _WinAPI_DeleteObject($hPen) _WinAPI_DeleteObject($hBrush) _WinAPI_ReleaseDC($hGUIx, $hDC) _WinAPI_RedrawWindow($hGUIx, 0, 0, BitOR($RDW_INVALIDATE, $RDW_ERASE, $RDW_UPDATENOW)) ; erase content of the gui EndFunc ;==>_Preview_Ellipse I'm sure to be on the wrong way (I admit my knowledge on graphics is close to zero) How can I achieve that effect? Thanks on advance for any help. Edited September 24, 2016 by Chimp Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....
Gianni Posted September 26, 2016 Author Posted September 26, 2016 (edited) I made a little progress, learned that the alpha component of the color structure is there precisely to allow the transparency of color.... This new listing works quite well, but there is a boring flickering while drawing the ellipse. the flikering could be reduced if I could use the extended styles $WS_EX_COMPOSITED, $WS_EX_LAYERED in the GUICreate() function. Unfortunatelly if I use those styles, the drawing of the ellipse doesn't works anymore. Anyone knows how to allow the use of the $WS_EX_COMPOSITED, $WS_EX_LAYERED styles or any other way to eliminate flicker? Thank You Click on text in the Label and drag to draw the ellipse (and to see the boring flickering). expandcollapse popup#include <Misc.au3> ; for _IsPressed (01 Left mouse button) #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> #include <WinAPIGdi.au3> #include <GDIPlus.au3> ; Start GDIPlus _GDIPlus_Startup() Opt("MouseCoordMode", 2) Global $hUser32dll = DllOpen("user32.dll") ; for _IsPressed Local $aPos ; -- Create the GUI ------------------------------- Global $hGUI = GUICreate("Preview of an ellipse (click and drag to draw)", 400, 400, 100, 100);, Default,BitOR($WS_EX_COMPOSITED, $WS_EX_LAYERED)) ; Label Local $s = StringReplace(StringFormat('%22s', ""), " ", "the quick brown fox jumps over the lazy dog ") Local $hLabel = GUICtrlGetHandle(GUICtrlCreateLabel($s, 10, 10, 250, 250)) GUICtrlSetBkColor(-1, 0xAAAA00) GUISetState(@SW_SHOW) ; MAIN LOOP While 1 $aPos = MouseGetPos() $aMsg = GUIGetMsg($GUI_EVENT_ARRAY) Select Case $aMsg[0] = $GUI_EVENT_CLOSE ConsoleWrite("Bye" & @LF) Exit ; End EndSelect If _IsPressed("01", $hUser32dll) Then ; draw the ellipse following mouse position. ; returns only when left mouse button is released _Preview_Ellipse($hLabel, $aPos[0], $aPos[1], 20) ; X Y starting point, pensize EndIf WEnd Func _Preview_Ellipse($hGUIx, $iX, $iY, $iPenSize = 9, $iColor = 0xFF0000, $iFill = 0x0FF0FF) ; Creates $tagRECT structure with the coordinates of the specified rectangle Local $tRECT = _WinAPI_CreateRect($iX, $iY, $iX, $iY) Local $aRect[4] Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUIx) ; Create solid brush ; The alpha component of color 0xAAnnnnnn determines the transparency of the color Local $hBrush = _GDIPlus_BrushCreateSolid(0xAA00FF00) Local $hPen = _GDIPlus_PenCreate2($hBrush, $iPenSize) Local $aPreviousPos[2], $aPos[2] While _IsPressed("01", $hUser32dll) ; stay here till left mouse button is released ; get the mouse coordinates: ; $aPos[0] = X coord (horizontal), $aPos[1] = Y coord (vertical) $aPos = MouseGetPos() ; if mouse has mooved then redraw the ellipse accordingly If $aPreviousPos[0] <> $aPos[0] Or $aPreviousPos[1] <> $aPos[1] Then ; mouse has mooved ; take track of new mouse position $aPreviousPos[0] = $aPos[0] $aPreviousPos[1] = $aPos[1] ; some attempts to erase the ellipse ; _WinAPI_RedrawWindow($hGUI, "", "", BitOR($RDW_ERASE, $RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME, $RDW_ALLCHILDREN)) _WinAPI_RedrawWindow($hGUIx, 0, 0, BitOR($RDW_INVALIDATE, $RDW_ERASE, $RDW_UPDATENOW)) ; _WinAPI_InvalidateRect($hGUI, $tRect, True) ; Redraws just the defined rectangle by the $tRect structure ; _GDIPlus_GraphicsClear($hGraphics, 0x00FFFFFF) ; Adjust coordinates of the rectangle If $aPos[0] < $iX Then $aRect[0] = $aPos[0] $aRect[2] = $iX Else $aRect[0] = $iX $aRect[2] = $aPos[0] EndIf If $aPos[1] < $iY Then $aRect[1] = $aPos[1] $aRect[3] = $iY Else $aRect[1] = $iY $aRect[3] = $aPos[1] EndIf ; populate the rect structure used for deleting ellipse by the function _WinAPI_InvalidateRect above DllStructSetData($tRECT, 1, $aRect[0] - $iPenSize) ; initial point is fixed DllStructSetData($tRECT, 2, $aRect[1] - $iPenSize) DllStructSetData($tRECT, 3, $aRect[2] + $iPenSize) ; new mouse position DllStructSetData($tRECT, 4, $aRect[3] + $iPenSize) ; Draws the new ellipse (based on new mouse position) _GDIPlus_GraphicsDrawEllipse($hGraphics, $aRect[0], $aRect[1], $aRect[2] - $aRect[0], $aRect[3] - $aRect[1], $hPen) EndIf ; WEnd ; if left button is released then exit ; free resources _WinAPI_DeleteObject($hPen) _WinAPI_DeleteObject($hBrush) _GDIPlus_GraphicsDispose ( $hGraphics ) _WinAPI_RedrawWindow($hGUI, 0, 0, BitOR($RDW_INVALIDATE, $RDW_ERASE, $RDW_UPDATENOW)) ; erase content of the gui EndFunc ;==>_Preview_Ellipse Edited September 26, 2016 by Chimp Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....
UEZ Posted September 26, 2016 Posted September 26, 2016 (edited) I'm not sure but without creating a child GUI it is not possible to get a flickerless graphic handle. expandcollapse popup#include <Misc.au3> ; for _IsPressed (01 Left mouse button) #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> #include <WinAPIGdi.au3> #include <GDIPlus.au3> ; Start GDIPlus _GDIPlus_Startup() Opt("MouseCoordMode", 2) Global $hUser32dll = DllOpen("user32.dll") ; for _IsPressed Global $aPos, $iW = 250, $iH = 250 ; -- Create the GUI ------------------------------- Global $hGUI = GUICreate("Preview of an ellipse (click and drag to draw)", 400, 400, 100, 100);, Default,BitOR($WS_EX_COMPOSITED, $WS_EX_LAYERED)) ; Label Global $s = StringReplace(StringFormat('%22s', ""), " ", "the quick brown fox jumps over the lazy dog ") Global $hLabel = GUICtrlGetHandle(GUICtrlCreateLabel($s, 10, 10, 250, 250)) GUICtrlSetBkColor(-1, 0xAAAA00) GUISetState(@SW_SHOW) Global $hGUI_Child = GUICreate("", $iW, $iH, 0, 0, $WS_POPUP, $WS_EX_LAYERED) _WinAPI_SetParent($hGUI_Child, $hLabel) GUISetState(@SW_SHOWNA, $hGUI_Child) Global $hBrush = _GDIPlus_BrushCreateSolid(0xA0FFFFFF) Global Const $hDC = _WinAPI_GetDC($hGUI_Child) Global Const $hGfxDC = _WinAPI_CreateCompatibleDC($hDC) Local Const $hBitmapGDI = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) ;_WinAPI_CreateDIB($iW, $iH) Global $hObjOld = _WinAPI_SelectObject($hGfxDC, $hBitmapGDI) Global $tSize = DllStructCreate($tagSIZE) $tSize.x = $iW $tSize.y = $iH Global $tSource = DllStructCreate($tagPOINT) Global $tBlend = DllStructCreate($tagBLENDFUNCTION) $tBlend.Alpha = 0xFF $tBlend.Format = 1 Global $tDest = DllStructCreate($tagPOINT), $pPoint = DllStructGetPtr($tDest) $tDest.x = $iW $tDest.y = $iH Global $hGfx = _GDIPlus_GraphicsCreateFromHDC($hGfxDC) _GDIPlus_GraphicsSetSmoothingMode($hGfx, 4) ; MAIN LOOP While 1 $aPos = MouseGetPos() $aMsg = GUIGetMsg($GUI_EVENT_ARRAY) Select Case $aMsg[0] = $GUI_EVENT_CLOSE _WinAPI_SelectObject($hGfxDC, $hObjOld) _WinAPI_ReleaseDC($hLabel, $hDC) _WinAPI_DeleteDC($hGfxDC) _WinAPI_DeleteObject($hBitmapGDI) _GDIPlus_GraphicsDispose($hGfx) _GDIPlus_BrushDispose($hBrush) _GDIPlus_Shutdown() ConsoleWrite("Bye" & @LF) Exit ; End EndSelect If _IsPressed("01", $hUser32dll) Then ; draw the ellipse following mouse position. ; returns only when left mouse button is released ;~ _Preview_Ellipse($hLabel, $aPos[0], $aPos[1], 20) ; X Y starting point, pensize _Preview_Ellipse2() EndIf WEnd Func _Preview_Ellipse2() While _IsPressed("01", $hUser32dll) _WinAPI_BitBlt($hGfxDC, 0, 0, $iW, $iH, $hGfxDC, 0, 0, $CAPTUREBLT) _GDIPlus_GraphicsFillEllipse($hGfx, 0, 0, MouseGetPos(0), MouseGetPos(1), $hBrush) _WinAPI_UpdateLayeredWindow($hGUI_Child, $hDC, Null, $tSize, $hGfxDC, $tSource, 0, $tBlend, $ULW_ALPHA) Sleep(20) WEnd EndFunc Edited September 26, 2016 by UEZ 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
Gianni Posted September 27, 2016 Author Posted September 27, 2016 Hi Herr @UEZ , many thanks for your input. Unfortunately if I try to run the script as is, it doesn't shows any ellipse. When I click and drag on the GUI nothing happens... I had already tried before to use a child window and/or also to use the $WS_EX_LAYERED style directly on the main GUI, but in both cases the drawing of the ellipse it doesn't anymore. (I'm using AutoIt 3.3.14.2 on win7 x64) I see instead that you are sucessfully running your script on your system. What's your system? I'm a bit confused because I don't know if I have some weird problem on my system or if the $WS_EX_LAYERED style has some restrictions of use... I will try to look further into the matter... Thanks again for your very welcome aid Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....
UEZ Posted September 27, 2016 Posted September 27, 2016 (edited) Signore Chimp, I tried that script on Win10 x64 version 1607. I will try it in my vm Win7 just after my meeting. Tested on Win7 (vm) with enabled Aero -> not working. Seems to be a problem with _WinAPI_SetParent() function. Try these lines instead: ... Global $hGUI_Child = GUICreate("", $iW, $iH, 10, 10, $WS_POPUP, BitOr($WS_EX_MDICHILD, $WS_EX_LAYERED), $hGUI) ;~ _WinAPI_SetParent($hGUI_Child, $hGUI) GUISetState(@SW_SHOWNA, $hGUI_Child) ... Edited September 27, 2016 by UEZ Gianni 1 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
Gianni Posted September 28, 2016 Author Posted September 28, 2016 (edited) Hi @UEZ with using those new lines from post #5 your script works very well. Many thanks for your instructive help Edited September 28, 2016 by Chimp Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....
UEZ Posted September 28, 2016 Posted September 28, 2016 U r 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
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