qwert Posted May 27, 2008 Posted May 27, 2008 (edited) I'm trying to place a transparent rectangle over an external window by having a transparent GUI on top. Everything is working except the background of the rectangle itself. What am I missing? Is there a better approach? #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> $Main_Gui = GUICreate("", 400, 400, -1, -1, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST) $exit = GUICtrlCreateButton("Exit", 200, 100, 80, 21) GUICtrlCreateGraphic(20, 50, 200, 200) GUICtrlSetGraphic(-1, $GUI_GR_RECT, 50, 50, 80, 80) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) GUISetState() While 1 If GUIGetMsg() = $exit Then Exit WEnd Thanks for any help. Edited May 31, 2008 by qwert
qwert Posted May 30, 2008 Author Posted May 30, 2008 After two full days and countless searches, I now believe it's not possible to make the background color of a graphic control transparent. Here's a link to another post with basically the same question:linkI'm at the point I need to move on to develop another approach. The best alternative I have now is to use GUICtrlCreatePic to put up a transparent GIF and then draw individual lines on it with DLL calls. It just seems odd that so many controls can set background transparency but graphic controls can't.Anyone able confirm this restriction? (for me and for others)Thanks.
jpam Posted May 30, 2008 Posted May 30, 2008 Looking for this ? #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> $Main_Gui = GUICreate("", 400, 400, -1, -1, $WS_POPUP, $WS_EX_LAYERED) GUISetBkColor(0x000000) GUICtrlCreateLabel("", 50, 0, 200, 50, -1, $GUI_WS_EX_PARENTDRAG) GUICtrlSetFont(-1,14,900) $exit = GUICtrlCreateButton("Exit", 200, 100, 80, 21) GUICtrlCreateGraphic(120, 200, 120, 120) GUICtrlSetGraphic(-1, $GUI_GR_RECT, 0, 0, 120, 120) GUICtrlSetBkColor(-1, 0xABCDEF) DllCall("user32.dll", "int", "SetLayeredWindowAttributes", "hwnd", $Main_Gui, "long", 0xEFCDAB , "byte", 255, "long", 0x1 + 0x2) GUISetState() While 1 If GUIGetMsg() = $exit Then Exit WEnd
jpam Posted May 30, 2008 Posted May 30, 2008 one with a Ellipse expandcollapse popup#include <GuiConstantsEx.au3> #include <WindowsConstants.au3> $Main_Gui = GUICreate("", 400, 400, -1, -1, -1, $WS_EX_LAYERED) GUICtrlCreateLabel("", 50, 0, 200, 50, -1, $GUI_WS_EX_PARENTDRAG) GUICtrlSetFont(-1,14,900) $exit = GUICtrlCreateButton("Exit", 200, 100, 80, 21) DllCall("user32.dll", "int", "SetLayeredWindowAttributes", "hwnd", $Main_Gui, "long", 0xEFCDAB , "byte", 255, "long", 0x1 + 0x2) GUISetState() $hdc = GetHDC() DrawEllipse($hdc, 100, 160, 300, 360, 1, 0xEFCDAB , 0xEFCDAB) While 1 $msg = GUIGetMsg() If $msg = $exit Then Exit If $msg = -3 Then Exit WEnd Func GetHDC() Local $S_WIN_TILLE = WinGetTitle("", "") Local $S_ClientSize = WinGetClientSize($S_WIN_TILLE, "") Local $S_WIN_GETHANDLE = WinGetHandle($S_WIN_TILLE, "") Local $S_RAW_HDC = DllCall("user32.dll", "ptr", "GetDC", "hwnd", $S_WIN_GETHANDLE) $hDC = "0x" & Hex($S_RAW_HDC[0]) Return $hDC EndFunc Func DrawEllipse($S_Destination, $S_left, $S_top, $S_right, $S_bottom, $S_linewidth, $S_linecolor, $S_fillcolor) $S_pen = DllCall("gdi32.dll", "int", "CreatePen", _ "int", 0, _ "int", $S_linewidth, _ "int", $S_linecolor) $S_obj = DllCall("gdi32.dll", "int", "SelectObject", _ "int", $S_Destination, _ "int", $S_pen[0]) DllCall("gdi32.dll", "int", "DeleteObject", _ "int", $S_obj[0]) $S_brush = DllCall("gdi32.dll", "int", "CreateSolidBrush", _ "int", $S_fillcolor) $S_obj = DllCall("gdi32.dll", "int", "SelectObject", _ "int", $S_Destination, _ "int", $S_brush[0]) DllCall("gdi32.dll", "int", "DeleteObject", _ "int", $S_obj[0]) DllCall("gdi32.dll", "int", "Ellipse", _ "int", $S_Destination, _ "int", $S_left, _ "int", $S_top, _ "int", $S_right, _ "int", $S_bottom) EndFunc
jpam Posted May 30, 2008 Posted May 30, 2008 or with some text ? expandcollapse popup#include <GuiConstantsEx.au3> #include <WindowsConstants.au3> $Main_Gui = GUICreate("", 400, 400, -1, -1, -1, $WS_EX_LAYERED) GUICtrlCreateLabel("", 50, 0, 200, 50, -1, $GUI_WS_EX_PARENTDRAG) GUICtrlSetFont(-1,14,900) $exit = GUICtrlCreateButton("Exit", 200, 100, 80, 21) DllCall("user32.dll", "int", "SetLayeredWindowAttributes", "hwnd", $Main_Gui, "long", 0xEFCDAB , "byte", 255, "long", 0x1 + 0x2) GUISetState() $hdc = GetHDC() SetText($hdc, "Hello", 50, 150, 0xEFCDAB , 0, 120, 1200, "Arial") SetText($hdc, "World", 50, 250, 0xEFCDAB , 0, 120, 1200, "Arial") While 1 $msg = GUIGetMsg() If $msg = $exit Then Exit If $msg = -3 Then Exit WEnd Func GetHDC() Local $S_WIN_TILLE = WinGetTitle("", "") Local $S_ClientSize = WinGetClientSize($S_WIN_TILLE, "") Local $S_WIN_GETHANDLE = WinGetHandle($S_WIN_TILLE, "") Local $S_RAW_HDC = DllCall("user32.dll", "ptr", "GetDC", "hwnd", $S_WIN_GETHANDLE) $hDC = "0x" & Hex($S_RAW_HDC[0]) Return $hDC EndFunc Func SetText($S_Destination, $S_Text, $S_x, $S_y, $S_TextColor, $S_BKColor, $Font_H, $Font_W, $Font_Name) $font = DllCall("gdi32.dll", "int", "CreateFontA", _ "int", $Font_H, _ "int", 0, _ "int", 0, _ "int", 0, _ "int", $Font_W, _ "Int", 0, _ "int", 0, _ "int", 0, _ "int", 0, _ "int", 0, _ "int", 0, _ "int", 0, _ "int", 0, _ "str", $Font_Name) $oldfont = DllCall("gdi32.dll", "int", "SelectObject", _ "hwnd", $S_Destination, _ "int", $font[0]) If $S_BKColor = 0 Then DllCall("gdi32.dll", "int", "SetBkMode", _ "hwnd", $S_Destination, _ "int", "TRANSPARENT") EndIf DllCall("gdi32.dll", "int", "SetTextColor", _ "hwnd", $S_Destination, _ "int", $S_TextColor) DllCall("gdi32.dll", "int", "SetBkColor", _ "hwnd", $S_Destination, _ "int", $S_BKColor) DllCall("gdi32.dll", "int", "TextOutA", _ "hwnd", $S_Destination, _ "int", $S_x, _ "int", $S_y, _ "str", $S_Text, _ "int", StringLen($S_Text)) DllCall("gdi32.dll", "int", "selectObject", _ "hwnd", $S_Destination, _ "int", $oldfont[0]) DllCall("gdi32.dll", "int", "DeleteObject", _ "hwnd", $font[0]) EndFunc
qwert Posted May 30, 2008 Author Posted May 30, 2008 (edited) jpam, thanks for the examples. I had found the one with the ellipse during my searches. What I'm looking for is to make the background of the entire area of the graphic transparent-- and then have the ellipse (with no fill) lay over whatever is underneath. The two examples below show the difference. Edited May 30, 2008 by qwert
jpam Posted May 30, 2008 Posted May 30, 2008 like this ? expandcollapse popup#include <GuiConstantsEx.au3> #include <WindowsConstants.au3> $Main_Gui = GUICreate("", 400, 400, -1, -1, -1, $WS_EX_LAYERED) GUICtrlCreateLabel("", 50, 0, 200, 50, -1, $GUI_WS_EX_PARENTDRAG) GUISetBkColor(0xABCDEF) GUICtrlSetFont(-1,14,900) $exit = GUICtrlCreateButton("Exit", 200, 100, 80, 21) DllCall("user32.dll", "int", "SetLayeredWindowAttributes", "hwnd", $Main_Gui, "long", 0xEFCDAB , "byte", 255, "long", 0x1 + 0x2) GUISetState() $hdc = GetHDC() DrawEllipse($hdc, 100, 160, 300, 360, 1, 0x000000 , 0xEFCDAB) While 1 $msg = GUIGetMsg() If $msg = $exit Then Exit If $msg = -3 Then Exit WEnd Func GetHDC() Local $S_WIN_TILLE = WinGetTitle("", "") Local $S_ClientSize = WinGetClientSize($S_WIN_TILLE, "") Local $S_WIN_GETHANDLE = WinGetHandle($S_WIN_TILLE, "") Local $S_RAW_HDC = DllCall("user32.dll", "ptr", "GetDC", "hwnd", $S_WIN_GETHANDLE) $hDC = "0x" & Hex($S_RAW_HDC[0]) Return $hDC EndFunc Func DrawEllipse($S_Destination, $S_left, $S_top, $S_right, $S_bottom, $S_linewidth, $S_linecolor, $S_fillcolor) $S_pen = DllCall("gdi32.dll", "int", "CreatePen", _ "int", 0, _ "int", $S_linewidth, _ "int", $S_linecolor) $S_obj = DllCall("gdi32.dll", "int", "SelectObject", _ "int", $S_Destination, _ "int", $S_pen[0]) DllCall("gdi32.dll", "int", "DeleteObject", _ "int", $S_obj[0]) $S_brush = DllCall("gdi32.dll", "int", "CreateSolidBrush", _ "int", $S_fillcolor) $S_obj = DllCall("gdi32.dll", "int", "SelectObject", _ "int", $S_Destination, _ "int", $S_brush[0]) DllCall("gdi32.dll", "int", "DeleteObject", _ "int", $S_obj[0]) DllCall("gdi32.dll", "int", "Ellipse", _ "int", $S_Destination, _ "int", $S_left, _ "int", $S_top, _ "int", $S_right, _ "int", $S_bottom) EndFunc
martin Posted May 30, 2008 Posted May 30, 2008 DllCall("gdi32.dll", "int", "SetBkMode", _ "hwnd", $S_Destination, _ "int", "TRANSPARENT")I think it should not be a string thereConst $TRANSPARENT = 1, $OPAQUE = 2 Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
qwert Posted May 30, 2008 Author Posted May 30, 2008 like this ?Exactly like that! I'll have time to really examine it in a couple of hours -- but it looks good right now.Thanks very much.
jpam Posted May 30, 2008 Posted May 30, 2008 @ martin it must be declared as "0x00000020" @ qwert glad i could help you
martin Posted May 30, 2008 Posted May 30, 2008 @ martinit must be declared as "0x00000020"@ qwert glad i could help you Transparent I suppose you mean?It seems that any value that is not 2 gives transparent. Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
qwert Posted May 31, 2008 Author Posted May 31, 2008 @ qwert glad i could help you Everything is working very well using the method you posted. But I do have a couple of questions, since I've never worked with the Graphics.GetHdc Method. Sometimes I need to be able to delete the first rectangle and replace it with a different rectangle. So what I've done is change the function to return the handle of the drawn object as follows: $S_rect = DllCall("gdi32.dll", "int", "Rectangle", _ "int", $S_Destination, _ "int", $S_left, _ "int", $S_top, _ "int", $S_right, _ "int", $S_bottom) Return $_rect EndFunc I then use this DllCall to erase the previous rectangle. $rect = DrawRect($hdc, 100, 160, 800, 560, 1, 0x000000 , 0xEFCDAB) Sleep(3000) DllCall("gdi32.dll", "int", "DeleteObject", "int", $rect) It seems to work, but is it the proper way? Also, could you comment on the "CreatePen/SelectObject/DeleteObject" sequence used in the function. Doesn't this delete the pen before it's used? And if I call the function more than once, should the delete steps be put off until exiting the scipt? I certainly appreciate your help on this. It's opening up a new area of capability.
jpam Posted May 31, 2008 Posted May 31, 2008 here a cleanup version with comments to erase a Rectangle ,simple draw a new one over the old one with the transparent line color. expandcollapse popup#include <GuiConstantsEx.au3> #include <WindowsConstants.au3> $Main_Gui = GUICreate("", 400, 400, -1, -1, -1, $WS_EX_LAYERED) GUICtrlCreateLabel("", 50, 0, 200, 50, -1, $GUI_WS_EX_PARENTDRAG) GUISetBkColor(0xABCDEF) GUICtrlSetFont(-1,14,900) $exit = GUICtrlCreateButton("Exit", 200, 100, 80, 21) DllCall("user32.dll", "int", "SetLayeredWindowAttributes", "hwnd", $Main_Gui, "long", 0xEFCDAB , "byte", 255, "long", 0x1 + 0x2) GUISetState() $hdc = GetHDC() DrawEllipse($hdc, 100, 160, 300, 360, 1, 0x000000 , 0xEFCDAB) Sleep(2000) DrawEllipse($hdc, 100, 160, 300, 360, 1, 0xEFCDAB , 0xEFCDAB) ; draw a new shape over the old one ; with transparent line color to erase old shape from screen While 1 $msg = GUIGetMsg() If $msg = $exit Then Exit If $msg = -3 Then Exit WEnd Func GetHDC() Local $S_WIN_TILLE = WinGetTitle("", "") Local $S_ClientSize = WinGetClientSize($S_WIN_TILLE, "") Local $S_WIN_GETHANDLE = WinGetHandle($S_WIN_TILLE, "") Local $S_RAW_HDC = DllCall("user32.dll", "ptr", "GetDC", "hwnd", $S_WIN_GETHANDLE) $hDC = "0x" & Hex($S_RAW_HDC[0]) Return $hDC EndFunc Func DrawEllipse($S_Destination, $S_left, $S_top, $S_right, $S_bottom, $S_linewidth, $S_linecolor, $S_fillcolor) $S_hNewPen = DllCall("gdi32.dll", "int", "CreatePen", _ ; Create new pen to draw with "int", 0, _ "int", $S_linewidth, _ "int", $S_linecolor) $S_hOldPen = DllCall("gdi32.dll", "int", "SelectObject", _ ; Select new pen into DC "int", $S_Destination, _ ; and save handle to old one "int", $S_hNewPen[0]) $S_NewBrush = DllCall("gdi32.dll", "int", "CreateSolidBrush", _ ; Create new brush to fill shapes "int", $S_fillcolor) $S_OldBrush = DllCall("gdi32.dll", "int", "SelectObject", _ ; Select new brush into DC "int", $S_Destination, _ ; and save handle to old one "int", $S_NewBrush[0]) DllCall("gdi32.dll", "int", "Rectangle", _ ; draw Rectangle "int", $S_Destination, _ "int", $S_left, _ "int", $S_top, _ "int", $S_right, _ "int", $S_bottom) DllCall("gdi32.dll", "int", "SelectObject", _ ; Displace New Pen from DC "int", $S_Destination, _ "int", $S_hOldPen[0]) DllCall("gdi32.dll", "int", "DeleteObject", _ ; delete pen to free up system resources "int", $S_hNewPen[0]) ; when a pen is still selected in the dc ,you can not delete it DllCall("gdi32.dll", "int", "SelectObject", _ ; Displace New brush from DC "int", $S_Destination, _ ; when a Brush is still selected in the dc ,you can not delete it "int", $S_OldBrush[0]) DllCall("gdi32.dll", "int", "DeleteObject", _ ; delete brush to free up system resources "int", $S_NewBrush[0]) ; when a brush is still selected in the dc ,you can not delete it EndFunc
qwert Posted May 31, 2008 Author Posted May 31, 2008 here's a cleanup version with commentsExcellent work.Given the new order of the steps, it does look like the pen create and delete steps could be pulled outside of the draw function for the case where repeated calls will be made using the same settings. I'll give it a try just to know, although it works great, as is.Thanks again for your help.
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