flashlab Posted March 24, 2012 Posted March 24, 2012 (edited) Now it's possible to display shell context menu in a control(treeview,listview,list...) just like you right click on a file/folder in windows explorer. Hope you will like it The idea and original code come from http://www.codeproject.com/KB/cs/shellContextMenu.aspx, And the dll file was compiled by sd007ONE PROBLEM : the program works fine on XP, but several items won't show on win7-x64, such as unlocker, foobar2000...Anyone can fix this? Here is an simple apply based on Yashied‘’s TVExplorer UDFexpandcollapse popup#Include <GUIConstantsEx.au3> #Include <GUITreeView.au3> #Include <TVExplorer.au3> #Include <TreeViewConstants.au3> #Include <WindowsConstants.au3> #Include <WinAPIEx.au3> Opt('GUIOnEventMode', 1) Global $hForm, $hTV, $Input, $hFocus = 0, $Dummy, $Style Global $__RegAsmPath, $ShellContextMenu ;COM Handle _NETFramework_Load(@ScriptDir & "ExplorerShellContextMenu.dll") If Not @error Then $ShellContextMenu = ObjCreate("ExplorerShellContextMenu.ShowContextMenu") Else MsgBox(0,'',"error=" & @error &@CRLF&@CRLF& _ "1=ExplorerShellContextMenu.dll has been registered"&@CRLF& _ "2=DLL file does not exist"&@CRLF& _ "3=.NET Framework 2.0 required!"&@CRLF& _ "4=can't register the .net DLL") EndIf If Not _WinAPI_DwmIsCompositionEnabled() Then $Style = $WS_EX_COMPOSITED Else $Style = -1 EndIf $hForm = GUICreate('TVExplorer UDF Example', 700, 406, -1, -1, -1, $Style) GUISetOnEvent($GUI_EVENT_CLOSE, '_GUIEvent') GUISetIcon(@WindowsDir & 'explorer.exe') $Input = GUICtrlCreateInput('', 20, 20, 660, 19) GUICtrlSetState(-1, $GUI_DISABLE) $hTV = _GUICtrlTVExplorer_Create('', 20, 48, 660, 310, -1, $WS_EX_CLIENTEDGE, -1, '_TVEvent') _TVSetPath($Input, _GUICtrlTVExplorer_GetSelected($hTV)) _GUICtrlTVExplorer_SetExplorerStyle($hTV) $Dummy = GUICtrlCreateDummy() GUICtrlSetOnEvent(-1, '_GUIEvent') HotKeySet('{F5}', '_TVRefresh') GUISetState() While 1 Sleep(1000) WEnd Func _GUIEvent() Local $Path Switch @GUI_CtrlId Case $GUI_EVENT_CLOSE GUIDelete() _GUICtrlTVExplorer_DestroyAll() Exit Case $Dummy $Path = _GUICtrlTVExplorer_GetSelected($hFocus) _GUICtrlTVExplorer_AttachFolder($hFocus) _GUICtrlTVExplorer_Expand($hFocus, $Path, 0) $hFocus = 0 EndSwitch EndFunc ;==>_GUIEvent Func _TVEvent($hWnd, $iMsg, $sPath, $hItem) Switch $iMsg Case $TV_NOTIFY_BEGINUPDATE GUISetCursor(1, 1) Case $TV_NOTIFY_ENDUPDATE GUISetCursor(2) Case $TV_NOTIFY_SELCHANGED If $hTV = $hWnd Then _TVSetPath($Input, $sPath) EndIf Case $TV_NOTIFY_DBLCLK ; Nothing Case $TV_NOTIFY_RCLICK Local $asCurInfo = GUIGetCursorInfo() ClientToScreen($hForm, $asCurInfo[0], $asCurInfo[1]) $ShellContextMenu.Show($sPath,$asCurInfo[0],$asCurInfo[1]) Case $TV_NOTIFY_DELETINGITEM ; Nothing Case $TV_NOTIFY_DISKMOUNTED ; Nothing Case $TV_NOTIFY_DISKUNMOUNTED ; Nothing EndSwitch EndFunc ;==>_TVEvent Func _TVSetPath($iInput, $sPath) Local $Text = _WinAPI_PathCompactPath(GUICtrlGetHandle($iInput), $sPath, -2) If GUICtrlRead($iInput) <> $Text Then GUICtrlSetData($iInput, $Text) EndIf EndFunc ;==>_TVSetPath Func _TVRefresh() Local $hWnd = _WinAPI_GetFocus() If $hTV = $hWnd Then If Not $hFocus Then $hFocus = $hWnd GUICtrlSendToDummy($Dummy) EndIf Return EndIf HotKeySet('{F5}') Send('{F5}') HotKeySet('{F5}', '_TVRefresh') EndFunc ;==>_TVRefresh Func _NETFramework_Load($DLL_File) $ShellContextMenu = ObjCreate("ExplorerShellContextMenu.ShowContextMenu") If IsObj($ShellContextMenu) Then Return SetError(1,0,0) ; already registered If Not FileExists($DLL_File) Then Return SetError(2,0,0) ; == file does not exist Local $sRoot = RegRead("HKEY_LOCAL_MACHINESOFTWAREMicrosoft.NETFramework", "InstallRoot") If @error Then Return SetError(3,0,0) ; == .NET Framework 2.0 required! Local $aFolder = _FileListToArray($sRoot , "*", 2), $sNETFolder = '' For $i = $aFolder[0] To 1 Step -1 If StringRegExp($aFolder[$i], "v2.0.d+", 0) Then $sNETFolder = $aFolder[$i] ExitLoop EndIf Next If $sNETFolder = '' Then Return SetError(3,0,0) ; == NET Framework 2.0 required! $__RegAsmPath = $sRoot & $sNETFolder & "RegAsm.exe" If Not RunWait($__RegAsmPath & " /codebase " & $DLL_File, @ScriptDir, @SW_HIDE) Then Return SetError(4,0,0); can't register the .net DLL Return 1 EndFunc ;==>_NETFramework_Load Func __UnLoad_NET_Dll($DLL_File) RunWait($__RegAsmPath & " /unregister " & $DLL_File, @ScriptDir, @SW_HIDE) ; unregister the .net DLL EndFunc Func ClientToScreen($hWnd, ByRef $x, ByRef $y) Local $stPoint = DllStructCreate("int;int") DllStructSetData($stPoint, 1, $x) DllStructSetData($stPoint, 2, $y) DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint)) $x = DllStructGetData($stPoint, 1) $y = DllStructGetData($stPoint, 2) ; release Struct not really needed as it is a local $stPoint = 0 EndFunc ;==>ClientToScreenExplorerShellContextMenu.7z Edited March 24, 2012 by flashlab JScript 1
wakillon Posted March 24, 2012 Posted March 24, 2012 Why not start by show your AutoIt Code ? AutoIt 3.3.14.2 X86 - SciTE 3.6.0 - WIN 8.1 X64 - Other Example Scripts
wakillon Posted March 25, 2012 Posted March 25, 2012 You are right, run fine on XP Thanks to share. AutoIt 3.3.14.2 X86 - SciTE 3.6.0 - WIN 8.1 X64 - Other Example Scripts
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