Sign in to follow this  
Followers 0

_ContextMenu() - Create an entry in the desktop contextmenu, with the program icon as well.

31 posts in this topic

Posted (edited)

I created this after about adding an entry to the desktop contextmenu with an icon. I therefore thought it would be useful to create for those who would like to add an entry, but wouldn't know where to begin. :huh2:

UDF:

#include-once

; #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
; #INDEX# =======================================================================================================================
; Title .........: _ContextMenu
; AutoIt Version : v3.2.12.1 or higher
; Language ......: English
; Description ...: Create an entry in the desktop contextmenu, with the program icon as well.
; Note ..........: Thanks to GEOSoft for the initial idea & LaCastiglione for the link on how to add an icon to the desktop contextmenu.
; 				   Link: http://www.autoitscript.com/forum/topic/129677-need-an-answer-to-a-simple-problem/
; Author(s) .....: guinness
; Remarks .......: Special thanks to KaFu for EnumRegKeys2Array() which I used as inspiration for enumerating the Registry Keys.
; Warning .......: This has been tested on Windows 7 only.
; ===============================================================================================================================

; #INCLUDES# =========================================================================================================
; None

; #GLOBAL VARIABLES# =================================================================================================
; None

; #CURRENT# =====================================================================================================================
; _ContextMenu_Install: Creates an entry in the 'All Users/Current Users' registry for displaying a program entry in the desktop shell contextmenu.
; _ContextMenu_Uninstall: Deletes an entry in the 'All Users/Current Users' registry for displaying a program entry in the desktop shell contextmenu.
; ===============================================================================================================================

; #INTERNAL_USE_ONLY#============================================================================================================
; __ContextMenu_RegistryGet ......; Retrieve an array of registry entries for a specific key.
; ===============================================================================================================================

; #FUNCTION# =========================================================================================================
; Name...........: _ContextMenu_Install()
; Description ...: Creates an entry in the 'All Users/Current Users' registry for displaying a program entry in the desktop shell contextmenu.
; Syntax.........: _ContextMenu_Install($sText, [$sName = @ScriptName, [$sFilePath = @ScriptFullPath, [$sIconPath = @ScriptFullPath, [$iIcon = 0, [$iAllUsers = 0, [$iExtended = 0]]]]]])
; Parameters ....: $sText - Text to be shown in the contextmenu.
;                  $sName - [Optional] Name of the program. [Default = Script name]
;                  $sFilePath - [Optional] Location of the program executable. [Default = Full script location]
;                  $sIconPath - [Optional] Location of the icon e.g. program executable or dll file. [Default = Full script location]
;                  $$iIcon - [Optional] Index of icon to be used. [Default = 0 - Main icon]
;                  $iAllUsers - [Optional] Add to Current Users (0) or All Users (1) [Default = 0 - Current user]
;                  $iExtended - [Optional] Show in the Extended contextmenu using Shift + Right click. [Default = 0 - Show in main contextmeu.]
; Requirement(s).: v3.2.12.1 or higher
; Return values .: Success - RegWrite() Return code.
;                  Failure - none
; Author ........: guinness
; Example........; Yes
;=====================================================================================================================
Func _ContextMenu_Install($sText, $sName = @ScriptName, $sFilePath = @ScriptFullPath, $sIconPath = @ScriptFullPath, $iIcon = 0, $iAllUsers = 0, $iExtended = 0)
	Local $i64Bit = "", $sRegistryKey = ""

	If @OSArch = "X64" Then
		$i64Bit = "64"
	EndIf
	If $iAllUsers Then
		$sRegistryKey = "HKEY_LOCAL_MACHINE" & $i64Bit & "\SOFTWARE\Classes\Directory\Background\shell\"
	Else
		$sRegistryKey = "HKEY_CURRENT_USER" & $i64Bit & "\SOFTWARE\Classes\Directory\Background\shell\"
	EndIf

	$sName = StringLower(StringReplace($sName, ".exe", ""))
	If $sName = "" Or $sFilePath = "" Then
		Return SetError(1, 0, 0)
	EndIf

	_ContextMenu_Uninstall($sName, $iAllUsers)

	RegWrite($sRegistryKey & $sName, "", "REG_SZ", $sText)
	RegWrite($sRegistryKey & $sName, "Icon", "REG_EXPAND_SZ", $sIconPath & "," & $iIcon)
	RegWrite($sRegistryKey & $sName & "\command", "", "REG_SZ", $sFilePath)
	If $iExtended Then
		RegWrite($sRegistryKey & $sName, "Extended", "REG_SZ", "")
	EndIf
	Return SetError(@error, 0, @error)
EndFunc   ;==>_ContextMenu_Install

; #FUNCTION# =========================================================================================================
; Name...........: _ContextMenu_Uninstall()
; Description ...: Deletes an entry in the 'All Users/Current Users' registry for displaying a program entry in the desktop shell contextmenu.
; Syntax.........: _ContextMenu_Uninstall([$sName = @ScriptName, [$iAllUsers = 0]])
; Parameters ....: $sName - [Optional] Name of the Program [Default = Script name.]
;                  $iAllUsers - [Optional] Was it added to Current Users (0) or All Users (1). [Default = 0 - Current user]
; Requirement(s).: v3.2.12.1 or higher
; Return values .: Success - Returns 2D Array of registry entries.
;                  Failure - Returns 0 and sets @error to 1.
; Author ........: guinness
; Example........; Yes
;=====================================================================================================================
Func _ContextMenu_Uninstall($sName = @ScriptName, $iAllUsers = 0)
	Local $aArray, $i64Bit = "", $sDelete, $sRegistryKey = ""

	If @OSArch = "X64" Then
		$i64Bit = "64"
	EndIf
	If $iAllUsers Then
		$sRegistryKey = "HKEY_LOCAL_MACHINE" & $i64Bit & "\SOFTWARE\Classes\Directory\Background\shell\"
	Else
		$sRegistryKey = "HKEY_CURRENT_USER" & $i64Bit & "\SOFTWARE\Classes\Directory\Background\shell\"
	EndIf

	$sName = StringLower(StringReplace($sName, ".exe", ""))
	If $sName = "" Then
		Return SetError(1, 0, 0)
	EndIf

	$aArray = __ContextMenu_RegistryGet($sRegistryKey)

	If $aArray[0][0] > 0 Then
		For $A = 1 To $aArray[0][0]
			If $aArray[$A][0] = $sName And $sDelete <> $aArray[$A][1] Then
				$sDelete = $aArray[$A][1]
				RegDelete($sDelete)
			EndIf
		Next
	EndIf
	Return $aArray
EndFunc   ;==>_ContextMenu_Uninstall

; #INTERNAL_USE_ONLY#============================================================================================================
Func __ContextMenu_RegistryGet($sRegistryKey)
	Local $aArray[1][5] = [[0, 5]], $iCount_1 = 0, $iCount_2 = 0, $iDimension, $iError = 0, $sRegistryKey_All, $sRegistryKey_Main, $sRegistryKey_Name, $sRegistryKey_Value

	While 1
		If $iError Then
			ExitLoop
		EndIf
		$sRegistryKey_Main = RegEnumKey($sRegistryKey, $iCount_1 + 1)
		If @error Then
			$sRegistryKey_All = $sRegistryKey
			$iError = 1
		Else
			$sRegistryKey_All = $sRegistryKey & $sRegistryKey_Main
		EndIf

		$iCount_2 = 0
		While 1
			$sRegistryKey_Name = RegEnumVal($sRegistryKey_All, $iCount_2 + 1)
			If @error Then
				ExitLoop
			EndIf

			If ($aArray[0][0] + 1) >= $iDimension Then
				$iDimension = ($aArray[0][0] + 1) * 2
				ReDim $aArray[$iDimension][$aArray[0][1]]
			EndIf

			$sRegistryKey_Value = RegRead($sRegistryKey_All, $sRegistryKey_Name)
			$aArray[$aArray[0][0] + 1][0] = $sRegistryKey_Main
			$aArray[$aArray[0][0] + 1][1] = $sRegistryKey_All
			$aArray[$aArray[0][0] + 1][2] = $sRegistryKey & $sRegistryKey_Main & "\" & $sRegistryKey_Name
			$aArray[$aArray[0][0] + 1][3] = $sRegistryKey_Name
			$aArray[$aArray[0][0] + 1][4] = $sRegistryKey_Value
			$aArray[0][0] += 1
			$iCount_2 += 1
		WEnd
		$iCount_1 += 1
	WEnd
	ReDim $aArray[$aArray[0][0] + 1][$aArray[0][1]]
	Return $aArray
EndFunc   ;==>__ContextMenu_RegistryGet

Example 1:

#include "_ContextMenu.au3"

_Main()

Func _Main()
	_ContextMenu_Install("Start ContextMenu") ; Add the running EXE to the desktop contextmenu.
	Sleep(10000)
	_ContextMenu_Uninstall() ; Remove the running EXE from the desktop contextmenu.
EndFunc   ;==>_Main

All of the above has been included in a ZIP file. ContextMenu.zip

Warning: This has been tested on Windows 7 only.

Edited by guinness

Share this post


Link to post
Share on other sites



Posted

Only tested on Windows 7.

Yep, not working on Win XP (SP3) :huh2:.

Share this post


Link to post
Share on other sites

Posted (edited)

Is it even possible as I found this "how to" in XP >> http://www.askvg.com/add-your-favorite-program-shortcut-in-desktop-context-menu-in-windows-xp/

Edited by guinness

Share this post


Link to post
Share on other sites

Posted

Not working on Vista either, but then these 2 are on their way out anyways. :huh2:

Share this post


Link to post
Share on other sites

Posted

Yep, Win7 only. I use this technique in ICU, but sadly you either have to have UAC disabled or run the script as Admin, because you need access to the HKEY_LOCAL_MACHINE reg-hive, which is restricted. Thanks for the appreciation :huh2:...

Share this post


Link to post
Share on other sites

Posted

these 2 are on their way out anyways. :huh2:

I have to disagree.

Well, the first one (XP) definitly will not go out at least for next 5 years, and the second one (Vista)... hm, as far as i know/feel, it's never have been "in" ;)

Share this post


Link to post
Share on other sites

Posted

Just because people are still using Windows 95 doesn't mean it's still "in", same thing for XP in the next couple of years IMHO. But that's neither here nor there as far as the UDF goes, and no need to derail this any further.

Share this post


Link to post
Share on other sites

Posted (edited)

Just because people are still using Windows 95 doesn't mean it's still "in", same thing for XP

You can't be serious really? :huh2:

Windows XP used by ~50% of all windows users, that's more than other systems all togheter, so make the math ;)

Edited by MrCreatoR

Share this post


Link to post
Share on other sites

Posted (edited)

Oldie but goodie! You should allow for the possibility to use another EXE's icon or a DLL or an ICO file (all should work). Currently you're forcing the target app for the icon. Also you need to allow for command line params, otherwise it's pretty useless as a context menu entry.

Edited by wraithdu

Share this post


Link to post
Share on other sites

Posted (edited)

Currently you're forcing the target app for the icon.

Try this perhaps? >>

_ContextMenu_Install("Open md5hash", "md5hash", "C:\Program Files\Internet Explorer\iexplore.exe", 0)

Also you need to allow for command line params, otherwise it's pretty useless as a context menu entry.

Correct me if I'm wrong (which I could be sometimes) but I think this is a little different than adding to the entry "HKCR\md5hash\shell\open\command\" as this will only be shown when right clicking directly on the desktop/blank area of explorer or if you use the Extended parameter it will be shown when using Shift + Right Click. I found out the hard way yesterday by doing a little test and adding "%1" to the end of the FilePath :huh2: It didn't work, but I thought I would try it. Thanks wraithdu for testing too.

Global $sFilePath = "C:\Program Files\Internet Explorer\iexplore.exe"

MsgBox(64, "Replace using %1 as the passed File.", StringReplace($sFilePath, '.exe', '.exe "%1"'))

Also KaFu I know/knew about ICU but I didn't copy from you scouts honour ;)

Edited by guinness

Share this post


Link to post
Share on other sites

Posted

Aw crap, ur right. I forgot these shortcuts can't have params, my bad. But I still think you need a separate param for an icon that's not the target exe.

Although this page could just be missing something from your reply... I'm on my phone in a meeting right now.

Share this post


Link to post
Share on other sites

Posted

But I still think you need a separate param for an icon that's not the target exe.

Do do you mean have Internet Explorer as the Icon?

Share this post


Link to post
Share on other sites

Posted

I mean the icon registry key can be ANY exe, dll, or ico. It does not need to be the target exe's icon. So you should allow that the icon parameter to your function be a full path to another exe, ico, or dll (with index).

Share this post


Link to post
Share on other sites

Posted (edited)

But I thought thats what I had already, I'm really confused as to why this doesn't work for you? >> From my previous post, this will change the icon to IE on my system.

_ContextMenu_Install("Open md5hash", "md5hash", "C:\Program Files\Internet Explorer\iexplore.exe", 0)
Edited by guinness

Share this post


Link to post
Share on other sites

Posted (edited)

But doesn't this command open IE, while naming the entry 'Open md5hash'? It still uses the icon of whatever program you're opening. What if I want to open IE with a random shell32.dll icon?

Edited by wraithdu

Share this post


Link to post
Share on other sites

Posted (edited)

Definitely possible, take a look at the ICU source. Heres the MSDN documentation ("In Windows 7 and later, cascading menu implementation is supported through registry settings."):

http://msdn.microsoft.com/en-us/library/cc144171%28VS.85%29.aspx#static_cascading

"Prior to Windows 7, the creation of cascading menus was possible only through the implementation of the IContextMenu interface." Maybe that's something for our AutoItObject team :huh2:;)...

http://msdn.microsoft.com/en-us/library/bb776095%28v=VS.85%29.aspx

Edited by KaFu

Share this post


Link to post
Share on other sites

Posted (edited)

wraithdu please except my apologies I wasn't thinking logically, perhaps tiredness was a huge factor?! I felt a little stupid when I was testing, it was an "of course!!" moment. I have updated the OP with your request.

Example of what you requested:

_ContextMenu_Install("Open md5hash", "md5hash", @ScriptDir & "\md5hash.exe", "C:\Program Files\Internet Explorer\iexplore.exe", 0)
Edited by guinness

Share this post


Link to post
Share on other sites

Posted

No problem! You could also leave the icon as a single param, then check the passed type: if it's an integer, use the target exe for the icon with the integer as the index; if it's a string, assume it is a path to another exe, dll, or ico, and use that explicitly. It would require the user to manually append any index though.

Share this post


Link to post
Share on other sites

Posted

It's another idea true, I will leave if for today and see what others think as well.

Share this post


Link to post
Share on other sites

Posted (edited)

Thanks Guinness! This is just what I've been looking for.

In the last few months, have there been any updates that allow this to work on WinXP (and I guess Vista)?

Would be sweet if this functionality or your UDF is incorporated to the latest Beta of AutoIt that was released last weekend.

However, I want to add a function of the application I want to link to within the contextMenu.

For example, MyPlayerApp has functions where it can either add to queue or play. If I right click an MP3 file, I want it to expose the functions and allow you to choose either Add to Queue or PLAY in "MyPlayerApp", not just open the player.

I hope I am making sense.

Any help in pointing me in the right direction would be much appreciated.

Edited by coffeeturtle

Share this post


Link to post
Share on other sites

Posted (edited)

I just saw your other UDF...

But I can't be tied to, as in the example above, to .mp3...maybe .ogg, etc.

Perhaps more accurately, I would like to click specific text on the screen and run a function of another autoit app I am developing.

I'll keep poking around.

I love your signature line with all of those valuable scripts you designed. Thanks for the great work!

Edited by coffeeturtle

Share this post


Link to post
Share on other sites

Posted

Perhaps more accurately, I would like to click specific text on the screen and run a function of another autoit app I am developing.

It's possible, maybe this is what you're looking for >>

Share this post


Link to post
Share on other sites

Posted

It's possible, maybe this is what you're looking for >>

Thanks for the quick response!

I might be able to tweak this to my needs and thank you for pointing me in this direction. It looks like cool stuff.

Sorry, I didn't explain myself properly though. I want to select words/sentences/paragraphs in a document/email/website.

Then right-click the selected area which will produce a contextmenu with the functions of my autoitscript available. OR perform a hotkey action.

Thanks again for any input.

Share this post


Link to post
Share on other sites

Posted

Now that makes sense. I think what you are trying to achieve can't be done through AutoIt, but for example with Opera you can add custom menus yourself & if you know Javascript and HTML you can create extensions.

Share this post


Link to post
Share on other sites

Posted

Ah! Thanks. That is an option at least.

Do you think my idea is good enough to ask it as a feature in the next Autoit?

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




  • Recently Browsing   0 members

    No registered users viewing this page.