Sign in to follow this  
Followers 0
CyberneticSoldier

A few "how do I do this" questions.

4 posts in this topic

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.

#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 :D

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 post-46709-1238364897_thumb.gif

Hopefully someone can help me and thanks in advance :o

Share this post


Link to post
Share on other sites



Well, here's an example I made using Gary's udf to round the corners of a GUI.

#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:

#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.

Share this post


Link to post
Share on other sites

Here's a step forward on the transparency.

#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

Share this post


Link to post
Share on other sites

Wow, thanks big time Nahuel :o Well I don't know what you did to fix the icon stickiness (and apparently you don't either), but it's gone now :D

*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 :D 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 :P

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0