geon79 Posted August 26, 2015 Share Posted August 26, 2015 I have a nagging problem I can't seem to find the solution of. What I'd like to create are graphic objects that overlay with specific areas of the screen and are completely "inconsistent" in the sense that any click will pass right through to the underlying window. My purpose is to highlight precisely specific areas that a user should click with bright colours: these areas are very irregular so they will be typically be drawn on a pixel-by-pixel basis. The rest of the window must be completely visible, so total transparency of the background of the hosting GUI is mandatory and the coloured areas must not block the clicking of what's under them, of course. Any idea of how it could be done?Thanks all in advance for help. Link to comment Share on other sites More sharing options...
MikahS Posted August 26, 2015 Share Posted August 26, 2015 Have a look at:WinSetTrans Snips & Scripts My Snips: graphCPUTemp ~ getENVvarsMy Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4 Feel free to use any of my code for your own use. Forum FAQ Link to comment Share on other sites More sharing options...
Surya Posted August 26, 2015 Share Posted August 26, 2015 Try this:#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Global $hGui = GUICreate("Click-through topmost GUI", -1, -1, -1, -1, -1, BitOR($WS_EX_TOPMOST, $WS_EX_TRANSPARENT, $WS_EX_LAYERED)) ; ............. Add your controls here GUISetControlsVisible($hGui) guisetstate(@SW_SHOW) Func GUISetControlsVisible($hWnd) ;thanks to the author of the function Local $aM_Mask, $aCtrlPos, $aMask $aM_Mask = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", 0, "long", 0) $aLastID = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", GUICtrlGetHandle(-1)) For $i = 3 To $aLastID[0] $aCtrlPos = ControlGetPos($hWnd, '', $i) If Not IsArray($aCtrlPos) Then ContinueLoop $aMask = DllCall("gdi32.dll", "long", "CreateRectRgn", _ "long", $aCtrlPos[0], _ "long", $aCtrlPos[1], _ "long", $aCtrlPos[0] + $aCtrlPos[2], _ "long", $aCtrlPos[1] + $aCtrlPos[3]) DllCall("gdi32.dll", "long", "CombineRgn", "long", $aM_Mask[0], "long", $aMask[0], "long", $aM_Mask[0], "int", 2) Next DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $hWnd, "long", $aM_Mask[0], "int", 1) EndFunc No matter whatever the challenge maybe control on the outcome its on you its always have been. MY UDF: Transpond UDF (Sent vriables to Programs) , Utter UDF (Speech Recognition) Link to comment Share on other sites More sharing options...
geon79 Posted August 26, 2015 Author Share Posted August 26, 2015 (edited) It doesn't work A GUI will show at all only if GUISetState(@SW_SHOW) is called before GUISetControlsVisible function is called and the extended style "layered" is removed, but even then the result is wrong graphically (shows the top left part of the GUI window, not the control) and it isn't transparent. Setting the style to $WS_POPUP does show the control correctly but I can't click through it, probably because the GUI lacks the "layered" attribute.My programming skills aren't enough to understand how it's supposed to work. Any idea? #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> HotKeySet("{ESC}","esc") Global $hGui = GUICreate("Click-through topmost GUI", 100, 100,200, 200, -1, BitOR($WS_EX_TOPMOST, $WS_EX_TRANSPARENT, $WS_EX_LAYERED)) GuiCtrlCreateLabel("Label",-1,-1) GUISetState(@SW_SHOW) GUISetControlsVisible($hGui) While 1 Sleep(100) WEnd Func GUISetControlsVisible($hWnd) ;thanks to the author of the function Local $aM_Mask, $aCtrlPos, $aMask $aM_Mask = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", 0, "long", 0) $aLastID = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", GUICtrlGetHandle(-1)) For $i = 3 To $aLastID[0] $aCtrlPos = ControlGetPos($hWnd, '', $i) If Not IsArray($aCtrlPos) Then ContinueLoop $aMask = DllCall("gdi32.dll", "long", "CreateRectRgn", _ "long", $aCtrlPos[0], _ "long", $aCtrlPos[1], _ "long", $aCtrlPos[0] + $aCtrlPos[2], _ "long", $aCtrlPos[1] + $aCtrlPos[3]) DllCall("gdi32.dll", "long", "CombineRgn", "long", $aM_Mask[0], "long", $aMask[0], "long", $aM_Mask[0], "int", 2) Next DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $hWnd, "long", $aM_Mask[0], "int", 1) EndFunc Func esc() ;ESC to quit Exit EndFunc Edited August 26, 2015 by geon79 Additional analysis Link to comment Share on other sites More sharing options...
Surya Posted August 26, 2015 Share Posted August 26, 2015 Here is a more modified version :expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinApi.au3> Global $trans = 200 HotKeySet("{ESC}","esc") Global $hgui = GUICreate("Click-through topmost GUI", 100, 100,200, 200,$WS_POPUP) GuiCtrlCreateLabel("Label",-1,-1) WinSetOnTop($hgui, "", 1) WinSetTrans($hgui,"",$trans) GUISetControlsVisible($hgui) _WinAPI_SetWindowLong($hgui, $GWL_EXSTYLE, _ BitOR(_WinAPI_GetWindowLong($hgui, $GWL_EXSTYLE), $WS_EX_TRANSPARENT)) GUISetState() While 1 Sleep(100) WEnd Func GUISetControlsVisible($hWnd) ;thanks to the author of the function Local $aM_Mask, $aCtrlPos, $aMask $aM_Mask = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", 0, "long", 0) $aLastID = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", GUICtrlGetHandle(-1)) For $i = 3 To $aLastID[0] $aCtrlPos = ControlGetPos($hWnd, '', $i) If Not IsArray($aCtrlPos) Then ContinueLoop $aMask = DllCall("gdi32.dll", "long", "CreateRectRgn", _ "long", $aCtrlPos[0], _ "long", $aCtrlPos[1], _ "long", $aCtrlPos[0] + $aCtrlPos[2], _ "long", $aCtrlPos[1] + $aCtrlPos[3]) DllCall("gdi32.dll", "long", "CombineRgn", "long", $aM_Mask[0], "long", $aMask[0], "long", $aM_Mask[0], "int", 2) Next DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $hWnd, "long", $aM_Mask[0], "int", 1) EndFunc Func esc() ;ESC to quit Exit EndFuncSet the $trans variable to your suitable transparency value No matter whatever the challenge maybe control on the outcome its on you its always have been. MY UDF: Transpond UDF (Sent vriables to Programs) , Utter UDF (Speech Recognition) Link to comment Share on other sites More sharing options...
geon79 Posted August 26, 2015 Author Share Posted August 26, 2015 Now the label shows, but still I can't click through it. I couldn't anticipate this would be so much trouble to implement! Link to comment Share on other sites More sharing options...
geon79 Posted August 26, 2015 Author Share Posted August 26, 2015 Ok, I don't know exactly why, with a few changes it actually works without using WinAPI, all it needs is the extended style $WS_EX_TRANSPARENT in the GUI creation. Why didn't it work in previous versions? I haven't got he slightest clue.Now it's usable, thanks a lot Surya for help. The only final improvement that would make it perfect is having totally transparent background (for Graphic controls mainly), I can set only overall transparency at the moment, $GUI_BKCOLOR_TRANSPARENT seems to be ignored even for labels (while other colours can be set).expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Global $trans = 200 HotKeySet("{ESC}","esc") Global $hgui = GUICreate("Click-through topmost GUI", 250, 250,350, 350,$WS_POPUP,$WS_EX_TRANSPARENT) GuiCtrlCreateLabel("Label",60,60) GUICtrlSetBkColor(-1,$GUI_BKCOLOR_TRANSPARENT) GUICtrlCreateGraphic(0,0,21,21) GUICtrlSetGraphic(-1,$GUI_GR_COLOR,0xff0000) GUICtrlSetGraphic(-1,$GUI_GR_PIXEL,10,10) GUICtrlSetGraphic(-1,$GUI_GR_COLOR,0x33ff22) GUICtrlSetGraphic(-1,$GUI_GR_ELLIPSE,0,0,21,21) WinSetOnTop($hgui, "", 1) WinSetTrans($hgui,"",$trans) GUISetControlsVisible($hgui) GUISetState() While 1 Sleep(100) WEnd Func GUISetControlsVisible($hWnd) ;thanks to the author of the function Local $aM_Mask, $aCtrlPos, $aMask $aM_Mask = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", 0, "long", 0) $aLastID = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", GUICtrlGetHandle(-1)) For $i = 3 To $aLastID[0] $aCtrlPos = ControlGetPos($hWnd, '', $i) If Not IsArray($aCtrlPos) Then ContinueLoop $aMask = DllCall("gdi32.dll", "long", "CreateRectRgn", _ "long", $aCtrlPos[0], _ "long", $aCtrlPos[1], _ "long", $aCtrlPos[0] + $aCtrlPos[2], _ "long", $aCtrlPos[1] + $aCtrlPos[3]) DllCall("gdi32.dll", "long", "CombineRgn", "long", $aM_Mask[0], "long", $aMask[0], "long", $aM_Mask[0], "int", 2) Next DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $hWnd, "long", $aM_Mask[0], "int", 1) EndFunc Func esc() ;ESC to quit Exit EndFunc Link to comment Share on other sites More sharing options...
Surya Posted August 27, 2015 Share Posted August 27, 2015 If you want to move the gui by dragging add a label/picture to the gui and set the style $GUI_WS_EX_PARENTDRAG to itand Glad that i could help No matter whatever the challenge maybe control on the outcome its on you its always have been. MY UDF: Transpond UDF (Sent vriables to Programs) , Utter UDF (Speech Recognition) 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