Jump to content

How to add links from an ini to a right click menu?


bb01
 Share

Recommended Posts

I hand picked those examples to not require the full path as there was no absolute sure way to know if the paths would be correct on your PC and the script does not accept path macro's. (although it can be made to do so)

I think it should work if you supply the full path to the executables in the inifile.

This part is not directly related to your script:

Arrays are incredibly usefull, but there are some common pitfalls.

If you keep the following in mind when experimenting I'm sure you'll find them pretty intuitive soon. (1D and 2D arrays at least)

Local $aExample[10] ;make an array with 10 rows

MsgBox(0,"this will not work",$aExample[10]) ; this will cause a crash.
;arrays count from 0, that means $aExample[0] to $aExample[9], NOT $aExample[1] to $aExample[10]

MsgBox(0,"this will not work",$aExample[0][0]) ; this will cause a crash.
;Even though row0, column0 exists in this array, this will cause a crash as the number of subscripts does not match the number of dimensions.

* Never assume a function has returned an array. If the function fail for whatever reason it will usually return nothing. Use IsArray() to check!

* Never assume the size of an array. Some functions return their size in the first cell, other have to be checked with Ubound.

* Remember the first example when working with Ubound.

* Make sure you read the function description to know how many dimensions the array should have and if the returned array has a count in the first cell, (referred to as a 1-based array) or not (referred to as a 0-based array)

* "For" loops allow you to easily read array cells one by one, and can be nested for multi dimension arrays (warning: gets confusing fast!)

* If you have an array related problem with a script, use _ArrayDisplay to check if the array has the contents you would expect.

@Melba23: Supplying code has backfired for me more than once. It's just so much easier to explain a concept by giving an example and I enjoy the distraction. ;)

Link to comment
Share on other sites

hmmm, ok.. I see that now... how do i get it so that i can add as many links as i want (or the end user) & dont need to change anything to the script once its compiled..

Eg..

If i have 20 links in there & then want to add another 20, using the arrays, am i able to do that, without having to recompile the scripts..

Basicly, so it'll read everything under Progs & will place it into the progs section of the menu..

As everything i'm seeing to do with arrays, seems to need a total amount, but if i dont know what the total will be, it can make it hard..

Trust me to pick something that i'm not fully up on...

Link to comment
Share on other sites

I started writing the example trying to use your ini layout at first, but decided against it later, however as a result I left the Step value in the for loops, causing the script to skip every second link. This might have added to the confustion. My original post has had the script updated and I added extra example links to the ini.

The script I supplied allows you to add as many links as could ever be practical by just changing the ini file. You don't need to change the script. You are unlikely to ever reach a technical limit by increasing the number of links.

The current script doesn't allow you to add extra sections. I did this on purpose as the use of arrays is clearer this way, but it is easily implemented. Ask if you're interested, but I suggest you get comfortable with fixed sections first.

I'm not sure what trouble you're having regarding the size of arrays. IniRead creates arrays in the right size unless there is an array and stores the size for you to use in the first cell. You can resize an array using ReDim.

If an array does not hold it's own size in a cell, you can retrieve it using Ubound. There is no need to hard code a size into the script.

Edit: Did you see the spoiler in my previous post? I used a spoiler tag so you wouldn't confuse them as directly related to your script, but reading your question regarding array size I think you might have missed the part about Ubound.

Edited by Tvern
Link to comment
Share on other sites

Hi

ShellExecute($aUserProg[1][$iIndex])

needs to be changed to ShellExecute($aUserProg[$iIndex][1])

I almost facepalmed myself off my chair. Some example I'm setting. It looks like I was rushing things a bit yesterday and it just goes to show that working with arrays is extremely usefull, but you need to pay attention to what you are doing.

I've updated the example an hope it works now, but havn't tested it.

Link to comment
Share on other sites

I almost facepalmed myself off my chair. Some example I'm setting. It looks like I was rushing things a bit yesterday and it just goes to show that working with arrays is extremely usefull, but you need to pay attention to what you are doing.

I've updated the example an hope it works now, but havn't tested it.

Working mutch better now.

Not sure ShellExecute is always doing the job though!

Link to comment
Share on other sites

Neither do I, but for example purposes it keeps things simple and extra functionality can be tagged on later.

I think it would actually be best to make a section for each link, specifying what group it should go into, what name it has, a link, parameters and the way it should be executed. (Run, Shelexecute, etc). It would be a completely different script from what the OP posted though.

Link to comment
Share on other sites

Hi Tvern

you said "The current script doesn't allow you to add extra sections. I did this on purpose as the use of arrays is clearer this way, but it is easily implemented. Ask if you're interested, but I suggest you get comfortable with fixed sections first."

I saw this thread and started to learn arrays using your examples, which are brilliant and very helpful thankyou. I would like to ask you to continue teaching please and would you please show me the next step of adding extra sections so that only the ini file needes amending not the script thanks in advance

Jamie

Drunken Frat-Boy Monkey Garbage

Link to comment
Share on other sites

looks like i've opened a hornet's nest Tvern.. But thank you for your help, am learning a lot about arrays this way..

Good to hear.

@engjcowi: I got to go, but this is one way of doing it.

#RequireAdmin
#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=psi-32x32.ico
#AutoIt3Wrapper_outfile=PSIrightclick.exe
#AutoIt3Wrapper_Compression=4
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <array.au3>
#NoTrayIcon

Opt("TrayMenuMode", BitOR(1, 2))

If Not FileExists(@ScriptDir & "\links.ini") Then
    MsgBox(4096, "Error", "Make sure the links.ini is in the same folder as PSIrightclick.exe")
    Exit
EndIf

$aSections = IniReadSectionNames(@ScriptDir & "\links.ini") ;$aSections now holds all the ini section names, but none of the other data.
If Not IsArray($aSections) Then
    MsgBox(4096, "Error", "Not a valid ini file")
    Exit
EndIf

;Alright. So we know our section names and we can read them with Inireadsection in a For loop.
;However while we can easily change the name of the section we want to read, it's not so easy to change the variable names for the resulting arrays.
;One option would be to pre-assign a whole bunch of variables and use those, but it would be hard to implement in the loop, limit the script and be plain ugly.
;We could store all the arrays inside another array, but it would mean you can't access the arrays directly anymore and it is a pretty good way to create an unreadable script. There used to be issues with performance doing this as well.
;Another option would be to create one really long array, but where would we store the section names used to determine what menu they should go into?
;We could re-organise the ini file. this is probably the best long term option, but what would work? A good way to find out would be to attempt something and remember what problems occur, then rewrite the script to resolve them.
;This is about all I can think of at the moment, that doesn't mean this list is complete.

;For now I will use the option of adding all items to one array. To make sure I put items in the menu where they belong, I'll make the menu as I read the sections. Another option would have been to add another column to the array, specifying the section each item belongs to.

Global $aData[1][2] ;this array will be holding all control ID's and links for the items from each section
Global $aTemp ;this array will be re-used storing one section at a time until it has been put into $aData

For $i = 1 To $aSections[0] ;loop through all the sections
    $aTemp = IniReadSection(@ScriptDir & "\links.ini", $aSections[$i]) ;read the section into an array for now.
    $aSections[$i] = TrayCreateMenu($aSections[$i]) ;create a menu for the section

    ;To re-create the seperator lines you have to specify them in the ini, by calling the last item of a section "seperator = line"
    ;To create a line inside a menu, just create an item line this: "= line" at the desired location.
    If $aTemp[$aTemp[0][0]][0] = "seperator" And $aTemp[$aTemp[0][0]][1] = "line" Then ;if the final entry in this section is "seperator = line", then a seperator line will be created under the corrosponding menu.
        TrayCreateItem("") ;create seperator line.
        $aTemp[0][0] -= 1 ;exclude the last item from the loop that creates controls.
    EndIf

    $UBound = UBound($aData) ;get the current size of the data array
    ReDim $aData[$UBound+$aTemp[0][0]][2] ;resize the data array to make space for the new sections entries
    For $i0 = 1 To $aTemp[0][0] ;loop through all the items in the current section
        $aData[$i0+$UBound-1][0] = TrayCreateItem($aTemp[$i0][0], $aSections[$i]) ;I'm storing the name of the item in column 2
        $aData[$i0+$UBound-1][1] = $aTemp[$i0][1] ;I'm storing the link of the item in column 3
    Next
Next

$aboutitem = TrayCreateItem("About")
TrayCreateItem("")

$exititem = TrayCreateItem("Exit")

TraySetState()
TraySetClick(16)

While 1
    $msg = TrayGetMsg()
    Select
    Case $msg = 0
    ContinueLoop
    Case $msg = $aboutitem
    ShellExecute(@ScriptDir & "\graphic.exe")
    Case $msg = $exititem ;you only need one of these
    ExitLoop
    Case Else
    ;check if the control ID is present in thr array,
    $iIndex = _ArraySearch($aData, $msg, 1)
    If Not @error Then
    ShellExecute($aData[$iIndex][1]) ;if so execute the link that goes with it
    ContinueLoop
    EndIf
    EndSelect
WEnd
Exit

If you have a look at what I did you might notice that:

There is no real good way to create sub menu's, sub-sub menu's etc using this script.

It will only use shellexecute on any item.

I was thinking this would be a good setup for an ini file:

[Progs]
Parent = none
Type = Menu
[Calculator]
Parent = Progs
Type = Item
Action = ShellExecute
Value = Calc.exe
Params = ""
[Seperator1]
Parent = none
Type = Seperator

It should allow you to choose one of a few default actions to perform on the provided Value, It allows you to make as many embedded menu's as you like and you can add extra functionality relatively easy. (You might like a tooltip for some items. Just add it in there!)

This might not be an easy thing to wrap your head around at first though.

Link to comment
Share on other sites

Thats not related to this topic is it? Just open a new topic for it.

As a first hint I would look into ControlSend, although that if it's a remote sesstion I doubt that'll work.

PS. If you open a new topic for this, try to supply a little more information about the windows you're trying to manipulated. preferably with au3info data.

Link to comment
Share on other sites

ok heres the output of it all..

Rightclick.Au3:-

#RequireAdmin
#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=32x32.ico
#AutoIt3Wrapper_outfile=NewRightclick.exe
#AutoIt3Wrapper_Compression=4
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <array.au3>
#NoTrayIcon

Opt("TrayMenuMode", BitOR(1, 2)) ;Combined style 1 and 2 using BitOr

;Check if the file exists
If Not FileExists(@ScriptDir & "\links.ini") Then
    MsgBox(4096, "", "Error occurred, Make sure the links.ini is in the same folder as PSIrightclick.exe")
    Exit
EndIf

;read sections into 2D arrays.
$aAV = IniReadSection(@ScriptDir & "\links.ini", "AV")
$aBurn = IniReadSection(@ScriptDir & "\links.ini", "CD/DVD")
$aProg = IniReadSection(@ScriptDir & "\links.ini", "Prog")
$aUserProg = IniReadSection(@ScriptDir & "\links.ini", "UserProg")
$aWeb = IniReadSection(@ScriptDir & "\links.ini", "Web")
$aUserWeb = IniReadSection(@ScriptDir & "\links.ini", "UserWeb")
$aDrive = IniReadSection(@ScriptDir & "\links.ini", "Drive")

;uncomment the next lines to see the resulting arrays
;~ _ArrayDisplay($aProg,"$aProg")
;~ _ArrayDisplay($aUserProg,"$aUserProg")
;~ _ArrayDisplay($aWeb,"$aWeb")
;~ _ArrayDisplay($aUserWeb,"$aUserWeb")
;~ _ArrayDisplay($aDrive,"$aDrive")

;create items for entries in the ini
If IsArray($aAV) Then
    $Otheritem = TrayCreateMenu("AV Programs")
    For $i = 1 To $aAV[0][0]
        $aAV[$i][0] = TrayCreateItem($aAV[$i][0], $Otheritem) ;the name of the program is replaced by the ID of the control. The link stays in the array.
    Next
EndIf

If IsArray($aBurn) Then
    $Otheritem = TrayCreateMenu("CD/DVD Tools")
    For $i = 1 To $aBurn[0][0]
        $aBurn[$i][0] = TrayCreateItem($aBurn[$i][0], $Otheritem) ;the name of the program is replaced by the ID of the control. The link stays in the array.
    Next
EndIf

If IsArray($aProg) Then
    $Otheritem = TrayCreateMenu("Misc Programs")
    For $i = 1 To $aProg[0][0]
        $aProg[$i][0] = TrayCreateItem($aProg[$i][0], $Otheritem) ;the name of the program is replaced by the ID of the control. The link stays in the array.
    Next
EndIf
If IsArray($aUserProg) Then
    $Otheritem2 = TrayCreateMenu("User Programs")
    For $i = 1 To $aUserProg[0][0]
        $aUserProg[$i][0] = TrayCreateItem($aUserProg[$i][0], $Otheritem2)
    Next
EndIf
If IsArray($aProg) Or IsArray($aUserProg) Or IsArray($aAV) Or IsArray($aBurn) Then TrayCreateItem("") ;only create the dividing line if items are present

If IsArray($aWeb) Then
    $Webitem = TrayCreateMenu("Web Links")
    For $i = 1 To $aWeb[0][0]
        $aWeb[$i][0] = TrayCreateItem($aWeb[$i][0], $Webitem)
    Next
EndIf
If IsArray($aUserWeb) Then
    $Webitem2 = TrayCreateMenu("User Web Links")
    For $i = 1 To $aUserWeb[0][0]
        $aUserWeb[$i][0] = TrayCreateItem($aUserWeb[$i][0], $Webitem2)
    Next
EndIf
If IsArray($aWeb) Or IsArray($aUserWeb) Then TrayCreateItem("")

If IsArray($aDrive) Then
    $Driveitem = TrayCreateMenu("Drives")
    For $i = 1 To $aDrive[0][0]
        $aDrive[$i][0] = TrayCreateItem($aDrive[$i][0], $Driveitem)
    Next
    TrayCreateItem("")
EndIf

$aboutitem = TrayCreateItem("About")
TrayCreateItem("")

$exititem = TrayCreateItem("Exit")

TraySetState()
TraySetClick(16)

;uncomment the next lines to see the modified arrays. Now ith CtrlId's where the names used to be
;~ _ArrayDisplay($aProg,"$aProg")
;~ _ArrayDisplay($aUserProg,"$aUserProg")
;~ _ArrayDisplay($aWeb,"$aWeb")
;~ _ArrayDisplay($aUserWeb,"$aUserWeb")
;~ _ArrayDisplay($aDrive,"$aDrive")

While 1
    $msg = TrayGetMsg()
    Select
        Case $msg = 0
            ContinueLoop
        Case $msg = $aboutitem
            ShellExecute(@ScriptDir & "\graphic.exe")
        Case $msg = $exititem ;you only need one of these
            ExitLoop
        Case Else
            ;check if the control ID is present in an array,
            $iIndex = _ArraySearch($aProg, $msg, 1)
            If Not @error Then
                ShellExecute($aProg[$iIndex][1]) ;if so execute the link that goes with it
                ContinueLoop
            EndIf

            $iIndex = _ArraySearch($aBurn, $msg, 1)
            If Not @error Then
                ShellExecute($aBurn[$iIndex][1])
                ContinueLoop
            EndIf

            $iIndex = _ArraySearch($aAV, $msg, 1)
            If Not @error Then
                ShellExecute($aAV[$iIndex][1])
                ContinueLoop
            EndIf
            
            $iIndex = _ArraySearch($aUserProg, $msg, 1)
            If Not @error Then
                ShellExecute($aUserProg[$iIndex][1])
                ContinueLoop
            EndIf

            $iIndex = _ArraySearch($aWeb, $msg, 1)
            If Not @error Then
                ShellExecute($aWeb[$iIndex][1])
                ContinueLoop
            EndIf

            $iIndex = _ArraySearch($aUserWeb, $msg, 1)
            If Not @error Then
                ShellExecute($aUserWeb[$iIndex][1])
                ContinueLoop
            EndIf

            $iIndex = _ArraySearch($aDrive, $msg, 1)
            If Not @error Then
                ShellExecute($aDrive[$iIndex][1])
                ContinueLoop
            EndIf
    EndSelect
WEnd
Exit

graphics.au3:-

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt('MustDeclareVars', 1)

graphics2()


; graphics 2
Func graphics2()
    Local $gui, $background, $pic, $basti_stay, $msg
    Local $sFile = @ScriptDir & "\Backups\logo4.gif"
    
    $gui = GUICreate("New Right Click Menu v1.2", 400, 100)
    ; background picture
    $background = GUICtrlCreatePic(@ScriptDir & "\Backups\msoobe.jpg", 0, 0, 400, 100)
        
    GUISetState(@SW_SHOW)

    ; transparent MDI child window
    $pic = GUICreate("", 369, 68, 20, 20, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $gui)
    ; transparent pic
    $basti_stay = GUICtrlCreatePic($sFile, 0, 0, 369, 68)
    GUISetState(@SW_SHOW)

    Do
        $msg = GUIGetMsg()

    Until Sleep(900)
    Exit
EndFunc

links.ini:-

[AV]
AVG Portable = AV\AVG.exe
Bat Portable = AV\Bat.exe
Auto Cleaner = AV\AutoClean.exe

[CD/DVD]
Nero Portable = Burn\Nero.exe
CDBurner Portable = Burn\CDBurn.exe
Isoburner = Burn\Isoburn.exe

[Prog]
Calc = SpeedCrunch\speedcrunch.exe
Notepad++ = Notepad+\notepad++.exe
MS Word = C:\Program Files\Microsoft Office\OFFICE11\WINWORD.EXE
MS Outlook = C:\Program Files\Microsoft Office\OFFICE11\OUTLOOK.EXE

[UserProg]
CMD Prompt = CMD.exe
Norton Ghost = Ghost\ghost32.exe
Norton Ghost Server = Ghost\GhostSrv.exe
Norton Ghost Image Explorer = Ghost\Ghostexp.exe
System Spec's = Speccy\Speccy.exe
H/D Disk Info = DiskInfo\DiskInfo.exe
CD/DVD Burner = Burner\StarBurn.exe
AutoIt Wrapper = AutoIt3Wrapper.exe
Clear Memory CMD = clearmem.cmd
Winzip = C:\Program Files\WinZip\WINZIP32.EXE

[Web]
Bits && Bytes = http://bits-and-bytes.us

[UserWeb]
Google.com = http://www.google.com
Autoit Help Forums= http://www.autoitscript.com/forum/index.php?act=idx

[Drive]
G Drive = G:\
U Drive = U:\
Root Drive = C:\

Thanks to Tvern & everyone else for all there help..

Seems to run smoothly now, & allows us to add any links etc to it...

Edited by bb01
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...