Jump to content
Sign in to follow this  
flashlab

explorer shell context menu for autoit

Recommended Posts

flashlab

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 :doh:The idea and original code come from http://www.codeproject.com/KB/cs/shellContextMenu.aspx, And the dll file was compiled by sd007

ONE PROBLEM :oops: : the program works fine on XP, but several items won't show on win7-x64, such as unlocker, foobar2000...Anyone can fix this? :bye:

Here is an simple apply based on Yashied‘’s TVExplorer UDF

#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   ;==>ClientToScreen

Posted Image

ExplorerShellContextMenu.7z

Edited by flashlab
  • Like 1

Share this post


Link to post
Share on other sites
wakillon

Why not start by show your AutoIt Code ? :oops:


AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites
wakillon

You are right, run fine on XP

Thanks to share.


AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

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  

×