CyberneticSoldier Posted March 29, 2009 Share Posted March 29, 2009 Hi everyone, I've recently been working on a shortcut bar program like "Caravelle". What I want to do is make the bar appear underneath your mouse (with a key on the keyboard/mouse click) and hide/close it if you don't click on it. The bar is going to be a ring with shortcuts in it that appears around your mouse, so I'd like to not show any window frames or anything, just the ring. Anyway I now have hit some problems and I'm wondering if what I want to do is possible or could be done in another way? This is the code so far. expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <Misc.au3> $dll = DllOpen("user32.dll") HotKeySet("^`", "Terminate") While 1 Sleep(10) If _IsPressed("1", $dll) And _IsPressed("11", $dll) Then ; invisible window $pic = GUICreate("ShortCut_NavRing", 1680, 1050, -2, -2, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW)) ; transparent pic for background, you can't see the icons without it. $basti_stay = GUICtrlCreatePic("opacity.gif", 0, 0, 0, 0) ; get mouse pos to determine where to place the icon and place it $pos = MouseGetPos() $folder1 = GuiCtrlCreateIcon("shell32.dll", 5, $pos[0], $pos[1]) $folder2 = GuiCtrlCreateLabel("Create Folder", $pos[0]+2, $pos[1]+32) ; make it visible GUISetState(@SW_SHOW) Do $msg = GUIGetMsg() If Not WinActive("ShortCut_NavRing") Then ExitLoop If $msg = $folder1 Then MsgBox(0, "Info", "Only a test...") Until _IsPressed("1B", $dll) GUICtrlDelete($folder1) GUICtrlDelete($folder2) GUICtrlDelete($basti_stay) GUICtrlDelete($pic) ;WinClose("ShortCut_NavRing") EndIf WEnd Func Terminate() DllClose($dll) Exit 0 EndFunc My questions/problems are: 1: Why can't I see the icons without setting a background image? The one I use now is only 1 by 1 pixel so I think there is also a way without it, I just don't know how. 2: Why won't the icon(s) go away when I switch to another window? When I click on a part of the desktop the "auto close" works fine, but when I click in the window of a program the icon gets stuck on the desktop (they do go away when I close the script). They only stick to the desktop when I don't click on the icon, if I press ESC they don't stick. Please try the code to see what I mean I've been thinking about some alternatives my self, but I can't get those to work or have no idea how to do it. I've thought about hiding and showing the gui, instead of deleting it, but how can I place those icons dynamically? Or moving the entire gui it self, but I don't know how to do that and if it'll give me the effect I want. Here is the picture I used for the background, so you can test the code Hopefully someone can help me and thanks in advance Link to comment Share on other sites More sharing options...
Nahuel Posted March 30, 2009 Share Posted March 30, 2009 Well, here's an example I made using Gary's udf to round the corners of a GUI. expandcollapse popup#include <GUIConstants.au3> #include <WindowsConstants.au3> #include <Misc.au3> $W = 350 $H = 350 $GUI = GUICreate("Menu", $W, $H,-1,-1, $WS_POPUP,BitOR($WS_EX_TOOLWINDOW,$WS_EX_TOPMOST)) GuiRoundCorners($GUI ,0,0,$W,$H) $dll = DllOpen("User32.dll") While 1 If _IsPressed("01",$dll) Then _ShowMenu() EndIf WEnd ;=============================================================================== ; ; Function Name: GuiRoundCorners() ; Description: Rounds the corners of a window ; Parameter(s): $h_win ; $i_x1 ; $i_y1 ; $i_x3 ; $i_y3 ; Requirement(s): AutoIt3 ; Return Value(s): ; Author(s): gaFrost ; ;=============================================================================== Func GuiRoundCorners($h_win, $i_x1, $i_y1, $i_x3, $i_y3) Dim $pos, $ret, $ret2 $pos = WinGetPos($h_win) $ret = DllCall("gdi32.dll", "long", "CreateRoundRectRgn", "long", $i_x1, "long", $i_y1, "long", $pos[2], "long", $pos[3], "long", $i_x3, "long", $i_y3) If $ret[0] Then $ret2 = DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $h_win, "long", $ret[0], "int", 1) If $ret2[0] Then Return 1 Else Return 0 EndIf Else Return 0 EndIf EndFunc;==>_GuiRoundCorners Func _ShowMenu() $mp = MouseGetPos() WinMove($GUI,"",$mp[0]-($W/2),$mp[1]-($H/2)) GUISetState() Do Sleep(100) Until _IsPressed("1B", $dll) Or not WinActive($GUI) GUISetState(@SW_HIDE) EndFunc It will show a round window wherever you click on. You can also make a "ring". You'll need to cut a hole in the gui. This is doable, search! 1: Why can't I see the icons without setting a background image? The one I use now is only 1 by 1 pixel so I think there is also a way without it, I just don't know how.I don't know the answer to this question, but I do know that if you use a layered window combined with a pic control, it will not show anything if the pic's path is not correct. I don't think using a 1x1 pic to make a window fully transparent without affecting the controls is bad. If there's another way, I doubt it's simpler. 2: Why won't the icon(s) go away when I switch to another window? When I click on a part of the desktop the "auto close" works fine, but when I click in the window of a program the icon gets stuck on the desktop (they do go away when I close the script). They only stick to the desktop when I don't click on the icon, if I press ESC they don't stick. Please try the code to see what I mean This doesn't happen to me. I made some fixes to your code: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <Misc.au3> $dll = DllOpen("user32.dll") HotKeySet("^`", "Terminate") While 1 Sleep(10) If _IsPressed("1", $dll) And _IsPressed("11", $dll) Then ; invisible window $pic = GUICreate("ShortCut_NavRing", @DesktopWidth, @DesktopHeight, -2, -2, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW)) ; transparent pic for background, you can't see the icons without it. $basti_stay = GUICtrlCreatePic("bg.bmp", 0, 0, @DesktopWidth, @DesktopHeight,$WS_CLIPSIBLINGS) ; get mouse pos to determine where to place the icon and place it $pos = MouseGetPos() $folder1 = GuiCtrlCreateIcon("shell32.dll", 5, $pos[0], $pos[1]) $folder2 = GuiCtrlCreateLabel("Create Folder", $pos[0]+2, $pos[1]+32) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) ; make it visible GUISetState(@SW_SHOW) Do $msg = GUIGetMsg() If Not WinActive("ShortCut_NavRing") Then ExitLoop If $msg = $folder1 or $msg = $folder2 Then MsgBox(0, "Info", "Only a test...") Until _IsPressed("1B", $dll) GUIDelete() ;WinClose("ShortCut_NavRing") EndIf WEnd Func Terminate() DllClose($dll) Exit 0 EndFunc *I changed the size of the window to be @DesktopWidth x @DesktopHeight so it works in any screen size. You should really consider making this smaller, since it isn't really necessary to make such a huge GUI when you can just create one big enough for the icon to fit in. *I added the $WS_CLIPSIBLINGS style to the pic control, so it doesn't overlap the other controls and make them unclickable. *I made the label transparent. This is another thing you should keep in mind. If the background of the place where you want to create the folder is too dark, you won't see the text of the label. Would be nice if I could make the icon background transparent as well. I don't know how to do this, but a quick search told me it's not possible. You could search harder or try to use common images instead of icons. Link to comment Share on other sites More sharing options...
Nahuel Posted March 30, 2009 Share Posted March 30, 2009 Here's a step forward on the transparency. expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <Misc.au3> #Include <WinAPI.au3> $dll = DllOpen("user32.dll") HotKeySet("^`", "Terminate") While 1 Sleep(10) If _IsPressed("1", $dll) And _IsPressed("11", $dll) Then $pos = MouseGetPos() ; invisible window $pic = GUICreate("ShortCut_NavRing", 70, 50,$pos[0]-10, $pos[1]-10, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW,$WS_EX_TOPMOST)) ; transparent pic for background, you can't see the icons without it. $basti_stay = GUICtrlCreatePic("bg.bmp", 0, 0,70, 50,$WS_CLIPSIBLINGS) GUISetState(@SW_SHOW) $hDC = _WinAPI_GetDC($pic) $icon = _WinAPI_LoadShell32Icon(-5) _WinAPI_DrawIcon($hDC,0,0,$icon) ;$folder1 = GuiCtrlCreateIcon("shell32.dll", 5, $pos[0], $pos[1]) $folder2 = GuiCtrlCreateLabel("Create Folder",2,32) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) ; make it visible Do $msg = GUIGetMsg() If Not WinActive("ShortCut_NavRing") Then ExitLoop If $msg = $folder2 Then MsgBox(0, "Info", "Only a test...") Until _IsPressed("1B", $dll) _WinAPI_ReleaseDC($pic, $hDC) _WinAPI_DestroyIcon($icon) GUIDelete() ;WinClose("ShortCut_NavRing") EndIf WEnd Func Terminate() DllClose($dll) Exit 0 EndFunc Link to comment Share on other sites More sharing options...
CyberneticSoldier Posted March 30, 2009 Author Share Posted March 30, 2009 Wow, thanks big time Nahuel Well I don't know what you did to fix the icon stickiness (and apparently you don't either), but it's gone now *I made the label transparent. This is another thing you should keep in mind. If the background of the place where you want to create the folder is too dark, you won't see the text of the label.The label already was transparent, at least on my pc it was. I also really like the round gui code, so I think I'm going to use that as well It'll look a lot better then what I had in mind (using the GDI+ to draw the ring), though the hole is easier with GDI+, as I don't need more code to make the hole.Anyway I'm going to take a closer look at your code and work on it.And thanks again 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