[решено] Перехват F4 в проводнике Windows для открытия выделенного файла в заданном редакторе

Ответить
Аватара пользователя
Vadikan

[решено] Перехват F4 в проводнике Windows для открытия выделенного файла в заданном редакторе

Сообщение Vadikan »

Привет, коллеги!



Прошу прощения за потребительский подход, но если у кого-то возникнет желание нарисовать скрипт, я буду признателен Изображение



Total Commander по F4 стандартно открывает выделенный файл в указанном текстовом редакторе. Хочется тоже самое получить в проводнике Windows 7. Для примера пойдет notepad.



Возможно?



Спасибо!
Аватара пользователя
madmasles

Re: [решено] Перехват F4 в проводнике Windows для открытия выделенного файла в заданном редакторе

Сообщение madmasles »

Vadikan,

1. А если выделено более одного файла, то что должен делать скрипт в этом случае?

2. Как я понимаю, работать скрипт должен только для активного окна проводника?

3. Открывать выделенный файл скрипт должен независимо от его расширения в блокноте или программой по умолчанию?

4. Если программой по умолчанию, то надо ли обрабатывать выделенную папку?
Аватара пользователя
Yashied

Re: [решено] Перехват F4 в проводнике Windows для открытия выделенного файла в заданном редакторе

Сообщение Yashied »

Код:

Код: Выделить всё

#AutoIt3Wrapper_Icon=F4.ico
#NoTrayIcon
#Include 
#Include 
Opt('TrayMenuMode', 3)
_Singleton('F42Notepad')
_HotKeyAssign(0x73, '_F4', -1, '[REGEXPCLASS:(Explore|Cabinet)WClass]')
$Exit = TrayCreateItem('Exit')
TraySetIcon(@ScriptFullPath)
TraySetToolTip('F42Notepad')
While 1
    Switch TrayGetMsg()
        Case $Exit
            Exit
    EndSwitch
WEnd
Func _F4()
    Local $aList = _WindowsExplorer_ExtractSelectedDirAndFiles(WinGetHandle(''))
    If Not @error Then
        For $i = 2 To $aList[0] + 1
            If Not StringInStr(FileGetAttrib($aList[$i]), 'D') Then
                Run(@SystemDir & '\Notepad.exe "' & $aList[$i] & '"')
            EndIf
        Next
    EndIf
EndFunc   ;==>_F4
; ===================================================================================================================
; Name...........: _WindowsExplorer_ExtractSelectedDirAndFiles
; Description....: Function to extract LocationURL and selected files from a "Windows Explorer" Window
; Syntax.........: _WindowsExplorer_ExtractSelectedDirAndFiles($hWnd)
; Parameters.....: $hWnd - Windows handle of an "Windows Explorer" Window
; AutoIt Version.: 3.3.6.1
; Return values..: Success  -   Array
;                               Array[0] = Number of files selected in right-hand Listview
;                               Array[1] = LocationURL - selected in left-hand Treeview or Window Rebar
;                               Array[2] - Array[n] = URL of selected files in right-hand Listview
;                  Failure  -   Array
;                               Array[0] = 0
;                               Array[1] = ""
;                               Sets the @error flag to non-zero.
;                               @error = 1 - $hwnd is not a valid window handle
;                               @error = 2 - $hwnd is not a window handle for an "Windows Explorer" Window
;                               @error = 3 - "Shell.Application" object could not be created
;                               @error = 4 - "$oShellApp.Windows()" object could not be created
; Author.........: Ascend4nt, KaFu, klaus.s
; ===================================================================================================================
Func _WindowsExplorer_ExtractSelectedDirAndFiles($hWnd, $oError = 0)
    Local $aExplorerSelectedFiles[2] = [0, ""]
    If Not IsHWnd($hWnd) Then Return SetError(1, 0, $aExplorerSelectedFiles)
    Local $aWinList = WinList("[REGEXPCLASS:(Explore|Cabinet)WClass]")
    While 1
        For $i = 1 To UBound($aWinList) - 1
            If $hWnd = $aWinList[$i][1] Then ExitLoop 2
        Next
        Return SetError(2, 0, $aExplorerSelectedFiles)
    WEnd
    If Not IsObj($oError) And Not ObjEvent("AutoIt.Error") Then $oError = ObjEvent("AutoIt.Error", "_WindowsExplorer_ExtractSelectedDirAndFiles")
    Local $fErrorHandling = False
    If IsObj($oError) Then $fErrorHandling = True
    Local $oShellApp = ObjCreate("Shell.Application")
    If Not IsObj($oShellApp) Then Return SetError(3, 0, $aExplorerSelectedFiles)
    Local $oShellApp_Windows = $oShellApp.Windows()
    If Not IsObj($oShellApp_Windows) Then Return SetError(4, 0, $aExplorerSelectedFiles)
    For $oShellApp_Inst In $oShellApp_Windows
        If $oShellApp_Inst.hwnd = $hWnd Then ExitLoop
    Next
    Local $iShellApp_Inst_SelectedItems_Count = $oShellApp_Inst.Document.SelectedItems.Count
    If $fErrorHandling And $oError.number Then Return SetError(5, 0, $aExplorerSelectedFiles)
    Local $sShellApp_Inst_LocationURL = $oShellApp_Inst.LocationURL
    Local $aRet = DllCall('shlwapi.dll', 'long', 'PathCreateFromUrlW', 'wstr', $sShellApp_Inst_LocationURL, 'wstr', '', 'dword*', 65534, 'dword', 0)
    If Not @error And $aRet[0] = 0 Then $sShellApp_Inst_LocationURL = $aRet[2]
    $aExplorerSelectedFiles[0] = $iShellApp_Inst_SelectedItems_Count
    $aExplorerSelectedFiles[1] = $sShellApp_Inst_LocationURL
    ReDim $aExplorerSelectedFiles[$aExplorerSelectedFiles[0] + 2]
    Local $oShellApp_Inst_SelectedItems = $oShellApp_Inst.Document.SelectedItems
    If $fErrorHandling And $oError.number Then Return SetError(6, 0, $aExplorerSelectedFiles)
    Local $iCounter = 2
    For $oShellApp_Inst_SelectedItem In $oShellApp_Inst_SelectedItems
        $aExplorerSelectedFiles[$iCounter] = $oShellApp_Inst_SelectedItem.path
        $iCounter += 1
    Next
    Return $aExplorerSelectedFiles
EndFunc   ;==>_WindowsExplorer_ExtractSelectedDirAndFiles
Вложения
F42Notepad.7z
(341.86 КБ) 0 скачиваний
F42Notepad.7z
(341.86 КБ) 0 скачиваний
Аватара пользователя
madmasles

Re: [решено] Перехват F4 в проводнике Windows для открытия выделенного файла в заданном редакторе

Сообщение madmasles »

Yashied,

Вы меня опередили. Изображение

Мой вариант (чуть-чуть отличается):

Код:

Код: Выделить всё

#NoTrayIcon
#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=icon.ico
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Run_Obfuscator=y
#Obfuscator_Parameters=/striponly
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
#Obfuscator_Ignore_Funcs= _OpenWith, _WindowsExplorer_ExtractSelectedFiles, _Exit, _RegRun, _RegRunDel, _ScriptDestroy
#include ;Yashied, http://autoit-script.ru/index.php.htm/topic,296.0.html
#include ;Yashied, http://autoit-script.ru/index.php.htm/topic,47.0.html
#include 
Opt('MustDeclareVars', 1)
Global Const $VK_ESCAPE = 0x1B
Global Const $VK_F4 = 0x73
Global $sTitleScript = @ScriptName & '{[/@$@\]}'
If WinExists($sTitleScript) Then Exit
AutoItWinSetTitle($sTitleScript)
;ключи:
If $CmdLine[0] Then
    Switch $CmdLine[1]
        Case '-RunYes' ;поместить в автозагрузку текущего пользователя
            _RegRun()
        Case '-RunNo' ;удалить из автозагрузки текущего пользователя
            _RegRunDel()
        Case '-Del' ;удалить утилиту
            _RegRunDel()
            _ScriptDestroy()
    EndSwitch
EndIf
_HotKeyAssign($VK_F4, '_OpenWith', $HK_FLAG_DEFAULT, '[REGEXPCLASS:(Explore|Cabinet)WClass]');F4
_HotKeyAssign(BitOR($CK_CONTROL, $CK_SHIFT, $VK_ESCAPE), '_Exit');Ctrl+Shift+Esc - выход
_WinAPI_EmptyWorkingSet()
While 1
    Sleep(10)
WEnd
Func _Exit()
    Exit
EndFunc   ;==>_Exit
Func _OpenWith()
    Local $h_Win_Handle, $a_List_Active, $s_Program = @WindowsDir & '\notepad.exe'
    $h_Win_Handle = WinGetHandle('[ACTIVE]')
    $a_List_Active = _WindowsExplorer_ExtractSelectedFiles($h_Win_Handle)
    If Not @error And $a_List_Active[0] Then
        For $i = 1 To $a_List_Active[0]
            Run($s_Program & ' "' & $a_List_Active[$i] & '"')
        Next
    Else
        _WinAPI_MessageBeep(2)
    EndIf
    _WinAPI_EmptyWorkingSet()
EndFunc   ;==>_OpenWith
;trancexx, http://www.autoitscript.com/forum/topic/89833-windows-explorer-current-folder/page__view__findpost__p__875866
Func _WindowsExplorer_ExtractSelectedFiles($h_Wnd, $o_Error = 0)
    Local $a_ExplorerSelectedFiles[1] = [0], $a_WinList, $f_ErrorHandling, $o_ShellApp, $o_ShellApp_Windows, _
            $i_ShellApp_Inst_SelectedItems_Count, $o_ShellApp_Inst_SelectedItems, $i_Counter, $s_Path_Selected, _
            $s_Attrib_Selected
    If Not IsHWnd($h_Wnd) Then Return SetError(1, 0, $a_ExplorerSelectedFiles)
    $a_WinList = WinList('[REGEXPCLASS:(Explore|Cabinet)WClass]')
    While 1
        For $i = 1 To UBound($a_WinList) - 1
            If $h_Wnd = $a_WinList[$i][1] Then ExitLoop 2
        Next
        Return SetError(2, 0, $a_ExplorerSelectedFiles)
    WEnd
    If Not IsObj($o_Error) And Not ObjEvent('AutoIt.Error') Then $o_Error = ObjEvent('AutoIt.Error', '_WindowsExplorer_ExtractSelectedFiles')
    If IsObj($o_Error) Then $f_ErrorHandling = True
    $o_ShellApp = ObjCreate('Shell.Application')
    If Not IsObj($o_ShellApp) Then Return SetError(3, 0, $a_ExplorerSelectedFiles)
    $o_ShellApp_Windows = $o_ShellApp.Windows()
    If Not IsObj($o_ShellApp_Windows) Then Return SetError(4, 0, $a_ExplorerSelectedFiles)
    For $o_ShellApp_Inst In $o_ShellApp_Windows
        If $o_ShellApp_Inst.hwnd = $h_Wnd Then ExitLoop
    Next
    $i_ShellApp_Inst_SelectedItems_Count = $o_ShellApp_Inst.Document.SelectedItems.Count
    If $f_ErrorHandling And $o_Error.number Then Return SetError(5, 0, $a_ExplorerSelectedFiles)
    $o_ShellApp_Inst_SelectedItems = $o_ShellApp_Inst.Document.SelectedItems
    If $f_ErrorHandling And $o_Error.number Then Return SetError(6, 0, $a_ExplorerSelectedFiles)
    For $o_ShellApp_Inst_SelectedItem In $o_ShellApp_Inst_SelectedItems
        $s_Path_Selected = $o_ShellApp_Inst_SelectedItem.path
        If $f_ErrorHandling And $o_Error.number Then Return SetError(7, 0, $a_ExplorerSelectedFiles)
        $s_Attrib_Selected = FileGetAttrib($s_Path_Selected)
        If Not StringInStr($s_Attrib_Selected, 'D') Then
            $i_Counter += 1
            ReDim $a_ExplorerSelectedFiles[$i_Counter + 1]
            $a_ExplorerSelectedFiles[$i_Counter] = $s_Path_Selected
            $a_ExplorerSelectedFiles[0] = $i_Counter
        EndIf
    Next
    Return SetError(0, 0, $a_ExplorerSelectedFiles)
EndFunc   ;==>_WindowsExplorer_ExtractSelectedFiles
Func _RegRun()
    Local $s_RegRun = 'HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
    If RegRead($s_RegRun, @ScriptName) = '' Or RegRead($s_RegRun, @ScriptName)  '"' & @ScriptFullPath & '"' Then
        RegWrite($s_RegRun, @ScriptName, 'REG_SZ', '"' & @ScriptFullPath & '"')
    EndIf
EndFunc   ;==>_RegRun
Func _RegRunDel()
    Local $s_RegRun = 'HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
    RegDelete($s_RegRun, @ScriptName)
EndFunc   ;==>_RegRunDel
Func _ScriptDestroy()
    Local $s_Temp, $s_Path, $s_Temp, $s_Text_Del, $h_File
    $s_Temp = _TempFile(@TempDir, '~', '.bat')
    $s_Path = FileGetShortName(@ScriptFullPath)
    $s_Text_Del = '@echo off' & @CRLF & ':loop' & @CRLF & 'del ' & $s_Path & @CRLF & 'if exist ' & _
            $s_Path & ' goto loop' & @CRLF & 'del ' & $s_Temp
    $h_File = FileOpen($s_Temp, 2)
    FileWrite($h_File, $s_Text_Del)
    FileClose($h_File)
    Run($s_Temp, '', @SW_HIDE)
    Exit
EndFunc   ;==>_ScriptDestroy
Аватара пользователя
madmasles

Re: [решено] Перехват F4 в проводнике Windows для открытия выделенного файла в заданном редакторе

Сообщение madmasles »

Я использую в основном (90%) AkelPad, поэтому предлагаю вариант с F4 - AkelPad и Shift+F4 - notepad:

Код:

Код: Выделить всё

#NoTrayIcon
#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=icon.ico
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Run_Obfuscator=y
#Obfuscator_Parameters=/striponly
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
#Obfuscator_Ignore_Funcs= _OpenWith, _WindowsExplorer_ExtractSelectedFiles, _Exit, _RegRun, _RegRunDel, _ScriptDestroy
#include ;Yashied, http://autoit-script.ru/index.php.htm/topic,296.0.html
#include ;Yashied, http://autoit-script.ru/index.php.htm/topic,47.0.html
#include 
Opt('MustDeclareVars', 1)
Global Const $VK_ESCAPE = 0x1B
Global Const $VK_F4 = 0x73
Global $sTitleScript = @ScriptName & '{[/@$@\]}'
If WinExists($sTitleScript) Then Exit
AutoItWinSetTitle($sTitleScript)
;ключи:
If $CmdLine[0] Then
    Switch $CmdLine[1]
        Case '-RunYes' ;поместить в автозагрузку текущего пользователя
            _RegRun()
        Case '-RunNo' ;удалить из автозагрузки текущего пользователя
            _RegRunDel()
        Case '-Del' ;удалить утилиту
            _RegRunDel()
            _ScriptDestroy()
    EndSwitch
EndIf
_HotKeyAssign($VK_F4, '_OpenWith', BitOR($HK_FLAG_DEFAULT, $HK_FLAG_EXTENDEDCALL), _
        '[REGEXPCLASS:(Explore|Cabinet)WClass]');F4 - AkelPad.exe
_HotKeyAssign(BitOR($CK_SHIFT, $VK_F4), '_OpenWith', BitOR($HK_FLAG_DEFAULT, $HK_FLAG_EXTENDEDCALL), _
        '[REGEXPCLASS:(Explore|Cabinet)WClass]');Shift+F4 - notepad.exe
_HotKeyAssign(BitOR($CK_CONTROL, $CK_SHIFT, $VK_ESCAPE), '_Exit');Ctrl+Shift+Esc - выход
_WinAPI_EmptyWorkingSet()
While 1
    Sleep(10)
WEnd
Func _Exit()
    Exit
EndFunc   ;==>_Exit
Func _OpenWith($iKey)
    Local $a_List_Active, $s_Program
    If BitAND($iKey, $CK_SHIFT) Then
        $s_Program = '"' & @WindowsDir & '\notepad.exe"'
    Else
        $s_Program = '"' & @ProgramFilesDir & '\AkelPad\AkelPad.exe"'
    EndIf
    $a_List_Active = _WindowsExplorer_ExtractSelectedFiles()
    If Not @error And $a_List_Active[0] Then
        For $i = 1 To $a_List_Active[0]
            Run($s_Program & ' "' & $a_List_Active[$i] & '"')
        Next
    Else
        _WinAPI_MessageBeep(2)
    EndIf
    _WinAPI_EmptyWorkingSet()
EndFunc   ;==>_OpenWith
;trancexx, http://www.autoitscript.com/forum/topic/89833-windows-explorer-current-folder/page__view__findpost__p__875866
Func _WindowsExplorer_ExtractSelectedFiles($o_Error = 0)
    Local $a_ExplorerSelectedFiles[1] = [0], $h_Wnd, $a_WinList, $f_ErrorHandling, $o_ShellApp, $o_ShellApp_Windows, _
            $i_ShellApp_Inst_SelectedItems_Count, $o_ShellApp_Inst_SelectedItems, $i_Counter, $s_Path_Selected, _
            $s_Attrib_Selected
    $a_WinList = WinList('[REGEXPCLASS:(Explore|Cabinet)WClass]')
    While 1
        For $i = 1 To UBound($a_WinList) - 1
            If WinActive($a_WinList[$i][1]) Then
                $h_Wnd = $a_WinList[$i][1]
                ExitLoop 2
            EndIf
        Next
        Return SetError(1)
    WEnd
    If Not IsObj($o_Error) And Not ObjEvent('AutoIt.Error') Then $o_Error = ObjEvent('AutoIt.Error', '_WindowsExplorer_ExtractSelectedFiles')
    If IsObj($o_Error) Then $f_ErrorHandling = True
    $o_ShellApp = ObjCreate('Shell.Application')
    If Not IsObj($o_ShellApp) Then Return SetError(1)
    $o_ShellApp_Windows = $o_ShellApp.Windows()
    If Not IsObj($o_ShellApp_Windows) Then Return SetError(1)
    For $o_ShellApp_Inst In $o_ShellApp_Windows
        If $o_ShellApp_Inst.hwnd = $h_Wnd Then ExitLoop
        If $f_ErrorHandling And $o_Error.number Then Return SetError(1)
    Next
    $i_ShellApp_Inst_SelectedItems_Count = $o_ShellApp_Inst.Document.SelectedItems.Count
    If $f_ErrorHandling And $o_Error.number Then Return SetError(1)
    ReDim $a_ExplorerSelectedFiles[$i_ShellApp_Inst_SelectedItems_Count + 1]
    $o_ShellApp_Inst_SelectedItems = $o_ShellApp_Inst.Document.SelectedItems
    If $f_ErrorHandling And $o_Error.number Then Return SetError(1)
    For $o_ShellApp_Inst_SelectedItem In $o_ShellApp_Inst_SelectedItems
        $s_Path_Selected = $o_ShellApp_Inst_SelectedItem.path
        If $f_ErrorHandling And $o_Error.number Then Return SetError(1)
        $s_Attrib_Selected = FileGetAttrib($s_Path_Selected)
        If Not StringInStr($s_Attrib_Selected, 'D') Then
            $i_Counter += 1
            $a_ExplorerSelectedFiles[$i_Counter] = $s_Path_Selected
        EndIf
    Next
    ReDim $a_ExplorerSelectedFiles[$i_Counter + 1]
    $a_ExplorerSelectedFiles[0] = $i_Counter
    Return SetError(0, 0, $a_ExplorerSelectedFiles)
EndFunc   ;==>_WindowsExplorer_ExtractSelectedFiles
Func _RegRun()
    Local $s_RegRun = 'HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
    If RegRead($s_RegRun, @ScriptName) = '' Or RegRead($s_RegRun, @ScriptName)  '"' & @ScriptFullPath & '"' Then
        RegWrite($s_RegRun, @ScriptName, 'REG_SZ', '"' & @ScriptFullPath & '"')
    EndIf
EndFunc   ;==>_RegRun
Func _RegRunDel()
    Local $s_RegRun = 'HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
    RegDelete($s_RegRun, @ScriptName)
EndFunc   ;==>_RegRunDel
Func _ScriptDestroy()
    Local $s_Temp, $s_Path, $s_Temp, $s_Text_Del, $h_File
    $s_Temp = _TempFile(@TempDir, '~', '.bat')
    $s_Path = FileGetShortName(@ScriptFullPath)
    $s_Text_Del = '@echo off' & @CRLF & ':loop' & @CRLF & 'del ' & $s_Path & @CRLF & 'if exist ' & _
            $s_Path & ' goto loop' & @CRLF & 'del %0'
    $h_File = FileOpen($s_Temp, 2)
    FileWrite($h_File, $s_Text_Del)
    FileClose($h_File)
    Run($s_Temp, '', @SW_HIDE)
    Exit
EndFunc   ;==>_ScriptDestroy

В принципе, можно добавить редакторы еще и на Ctrl + F4[/i], и на Win + F4, и на Alt + F4, и т.д.
Аватара пользователя
Vadikan

Re: [решено] Перехват F4 в проводнике Windows для открытия выделенного файла в заданном редакторе

Сообщение Vadikan »

О, а я-то поначалу подумал, что тишина в теме намекает на то, что мне надо сначала самому кривой скрипт написать хоть какой-нибудь Изображение Я, кстати, нагугливал HotKey на русском форуме autoit, но мне все равно не осилить такую задачу.



Yashied, madmasles, спасибо большое за варианты! Все работает!





madmasles, вы правильно ответили на все свои вопросы своим кодом Изображение Впрочем, насчет #4 я не очень понял - подразумевается открытие всех файлов в выделенной папке? Честно говоря, мне такое и не нужно даже.



Отдельное спасибо за вариант с SHIFT+F4! А Блокнот я привел для примера, у меня Notepad++ основной.
Аватара пользователя
Vadikan

Re: [решено] Перехват F4 в проводнике Windows для открытия выделенного файла в заданном редакторе

Сообщение Vadikan »

madmasles, а как можно открыть папку в редакторе? Или просто открыть в проводнике - типа, не тупи, я тебе тут папку открыл уже? Изображение



Не, это не нужно. Я и так доволен!
Ответить

Вернуться в «AutoIt»