Tvern Posted October 20, 2010 Share Posted October 20, 2010 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 More sharing options...
bb01 Posted October 21, 2010 Author Share Posted October 21, 2010 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 More sharing options...
Tvern Posted October 21, 2010 Share Posted October 21, 2010 (edited) 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 October 21, 2010 by Tvern Link to comment Share on other sites More sharing options...
JoHanatCent Posted October 21, 2010 Share Posted October 21, 2010 HiShellExecute($aUserProg[1][$iIndex])needs to be changed to ShellExecute($aUserProg[$iIndex][1]) Link to comment Share on other sites More sharing options...
Tvern Posted October 21, 2010 Share Posted October 21, 2010 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 More sharing options...
JoHanatCent Posted October 21, 2010 Share Posted October 21, 2010 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 More sharing options...
Tvern Posted October 21, 2010 Share Posted October 21, 2010 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 More sharing options...
bb01 Posted October 21, 2010 Author Share Posted October 21, 2010 thanks tvern, will have look at it properly when i get to work, am at moment seeing things cross eyed... lol Link to comment Share on other sites More sharing options...
engjcowi Posted October 21, 2010 Share Posted October 21, 2010 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 More sharing options...
bb01 Posted October 21, 2010 Author Share Posted October 21, 2010 looks like i've opened a hornet's nest Tvern.. But thank you for your help, am learning a lot about arrays this way.. Link to comment Share on other sites More sharing options...
Tvern Posted October 21, 2010 Share Posted October 21, 2010 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. expandcollapse popup#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 More sharing options...
Tvern Posted October 26, 2010 Share Posted October 26, 2010 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 More sharing options...
bb01 Posted October 26, 2010 Author Share Posted October 26, 2010 (edited) ok heres the output of it all.. Rightclick.Au3:- expandcollapse popup#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:- expandcollapse popup[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 October 26, 2010 by bb01 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