Orion9

|
Posted: Wed Jan 15, 2025 19:21 Post subject: |
|
|
AkulaBig
Кажется, я понял, в чём была сложность той задачи: склеенные панели имеют один серьёзный недостаток - изменения, сделанные на склеенных панелях, не применяются к панелям-источникам и не синхронизируются с ними, а значит, и смысла в такой склейке практически никакого.
Но всё-равно я пересмотрел и доработал код. Теперь панели можно выбирать из меню, открывать на главной панеле, объединять с главной панелью и закреплять для последующих быстрых вызовов.
В меню действуют модификаторы: Ctrl - выбрать и объединить, Shift - закрепить, Ctrl+Shift - перейти к файлу. Вызов без модификаторов загружает выбранную панель на главную панель инструментов.
У самой кнопки тоже есть модификаторы: Ctrl - объединить панель и открыть, Shift - открыть закрепленную панель, Ctrl+Shift - выбор типа меню, Alt - открыть объединенную панель, Win - пересоздать меню из *.bar файлов.
Под "закреплением" подразумевается выбор панели в качестве текущей для дальнейших операций. Информация о выбранной панеле записывается в секцию [Autorun] файла wincmd.ini, ключ AutoBars (например: AutoBars=Vertical.bar). Если ключа нет, то "Vertical.bar" считается умолчанием. Панели ищутся в папке, указанной в переменной BarsPath (у меня, наверное, как и у большинства, это %COMMANDER_PATH% & "\Bars\").
Выбор типа меню происходит между тремя вариантами: "ShowPopupMenu", "em_bars_panel", "DisplayOpenBar". Меню сохраняется в файле "Auto_bars.bar": ShowPopupMenu открывает этот файл встроенной функцией, "em_bars_panel" вызывает пользовательскую команду, "DisplayOpenBar" то же, что и "em_bars_panel", только с позиционированем (на основе примера от Loopback). Команда в usercmd.ini:
Code: | [em_bars_panel]
cmd=OPENBARMENU
param=%|COMMANDER_PATH|\Bars\Auto_bars.bar |
Еще одна команда, которую нужно добавить в usercmd.ini:
Code: | [em_open_bar]
cmd=OPENBAR
param=%|COMMANDER_PATH|\Bars\%A0 |
Используется для загрузки панели на главную панель инструментов. Поскольку загруженная панель может не содержать кнопки возврата, не лишним будет сделать пользовательскую команду, которая будет загружать главную панель инструментов, и посадить ее на хоткей. Например, у меня это:
Code: | [em_open_main_bar]
cmd=OPENBAR
param=%|COMMANDER_PATH|\Bars\Main.bar |
В общем, пока все это только в режиме тестирования, но некоторые удобства уже есть. Да и сам код пригодится для повторного использования в качестве наработок. Путь к Clip.vbs нужно указать в скрипте.
 Clip.vbs Code: | If WScript.Arguments.Count = 0 Then
FileName = "Clip.txt"
Else
FileName = WScript.Arguments(0)
End If
Set objHTML = CreateObject("htmlfile")
ClipboardText = objHTML.ParentWindow.ClipboardData.GetData("text")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(FileName, 2, true)
objFile.WriteLine ClipboardText
objFile.Close |
 Functions.aucfg Code: | # модуль дополнительных функций
Func SaveClipToFile(Filename)
Local vbsp = %COMMANDER_PATH% & "\Scripts\Vbs\"
Local vbsf = vbsp & "Clip.vbs"
If Not FileExist(vbsf) Then
ShowDarkHint("Скрипт не найден " & vbsf, 0)
Return 0
EndIf
ShellExec /SW_HIDE /WAIT:2000 %vbsf% '"%Filename%"' %vbsp%
Return 1
EndFunc
Func ShowDarkHint(DarkHint, HintSleep = 1000)
SetHintParam("ShowHint", "Font", 10, "Arial")
SetHintParam("ShowHint", "BackColor", 0x001C1C1C)
SetHintParam("ShowHint", "Text", 0xFFFFFF)
ShowHint(DarkHint)
If HintSleep > 0 Then
Sleep(HintSleep)
WinSetState(23)
Else
Sleep(100)
Endif
SetHintParam("ShowHint", "Reload")
EndFunc
Func CreateNewBar(BarPath, BarName, BackButton = true)
Local bar, br2, def
bar = BarPath & BarName & ".bar"
br2 = BarPath & BarName & ".br2"
ShellExec /SW_HIDE /WAIT:2000 %COMSPEC% "/c del /f /q ""%bar%"""
ShellExec /SW_HIDE /WAIT:2000 %COMSPEC% "/c del /f /q ""%br2%"""
If FileExist(bar) Then
ShowDarkHint("Ошибка удаления " & bar, 0)
Return false
Endif
IniWrite %bar% "Buttonbar" "Buttoncount" "0"
If ERROR = 1 Then
ShowDarkHint("Ошибка создания " & bar, 0)
Return false
EndIf
IniRead def %COMMANDER_INI% "Buttonbar" "Buttonbar" "%COMMANDER_PATH%\DEFAULT.BAR"
If BackButton Then
IniWrite %bar% "Buttonbar" "Button1" "wcmicons.dll,15"
IniWrite %bar% "Buttonbar" "Cmd1" %def%
IniWrite %bar% "Buttonbar" "Menu1" "Вернуться"
Endif
Return true
EndFunc
Func DisplayOpenBar(UsercmdName)
Local i, h
MouseGetPos("x", "y")
CommandExec(UsercmdName)
Sleep(20)
# ожидание панели
For i = 1 To 150
h = WinFind(0, "#32768")
If h > 0 Then Break
Sleep(10)
Next
If h = 0 Then
ShowHint("Панель не найдена")
Return
Endif
WinSetPos(x, y,"","","", h)
EndFunc
# поиск индекса кнопки на панели
# примеры вызова:
#{
BarsPath = %COMMANDER_PATH% & "\Bars\"
idx = FindButtonIdx(BarsPath & "Main.bar", "cmd", "61007")
idx = FindButtonIdx(BarsPath & "Main.bar", "menu", "Auto_bars")
idx = FindButtonIdx(BarsPath & "Main.bar", "button", "WCMICONS.dll,72")
MsgBox(FindButtonIdx(BarsPath & "Main.bar", "param", '/ef "tcm(60011,1)"'))
#}
Func FindButtonIdx(ButtonBar, ButtonKey, ButtonVal)
Local txt, pos, len, sub, idx = 0
If Not FileExist(ButtonBar) Then
ShowDarkHint("Панель не найдена " & ButtonBar, 0)
Return 0
EndIf
len = StrLen(ButtonKey)
ProcessExecGetOutput txt %COMSPEC% '/c type "%ButtonBar%"'
pos = StrPos(txt, "=" & ButtonVal)
If pos = 0 Then Return 0
For i = 0 To 3
sub = StrMid(txt, pos-len-i, len)
#OutputDebugString("Autorun: " & sub)
If sub = ButtonKey Then
idx = StrMid(txt, pos-i, i)
#OutputDebugString("Autorun: idx = " & idx)
If IsInt(idx) Then Break
Endif
Next
# перепроверка индекса
If idx > 0 Then
IniRead txt %ButtonBar% "Buttonbar" %"%ButtonKey% & %idx%"
#OutputDebugString("Autorun: Key = " & txt)
If StrPos(txt, ButtonVal) > 0 Then Return idx
#OutputDebugString("Autorun: Idx = " & idx)
EndIf
Return 0
EndFunc |
 Buttons.aucfg Code: | Pragma IncludeOnce
Global BarsPath = %COMMANDER_PATH% & "\Bars\"
RegisterCommand 61007 "TwoBars"
RegisterCommand 61008 "SpliceBarItem"
Func SpliceBarItem(lParam)
Local b_Ctrl = IsPressed(0x11), b_Shift = IsPressed(0x10)
Local bar = BarsPath & "Auto_bars.bar", def, b, c = 0, mnu, idx, txt, pos, str
IniRead b %bar% "Buttonbar" %"'Menu' & lParam"
bar = BarsPath & b
If Not FileExist(bar) Then
ShowHint("Панель не найдена " & bar)
Return
EndIf
If Not b_Ctrl And Not b_Shift Then
CommandExec("em_open_bar", b)
Return
Endif
If b_Ctrl And b_Shift Then
CommandExec /CD:S %bar%
Return
Endif
IniWrite /R %COMMANDER_INI% "Autorun" "AutoBars" %b%
IniRead c %bar% "Buttonbar" "Buttoncount"
# обновление подсказки на главной панели
IniRead def %COMMANDER_INI% "Buttonbar" "Buttonbar" "%COMMANDER_PATH%\DEFAULT.BAR"
If StrPos(def, "%COMMANDER_PATH%") Then
def = %COMMANDER_PATH% & StrReplace(def, "%COMMANDER_PATH%")
Endif
idx = FindButtonIdx(def, "cmd", "61007")
If idx > 0 Then
mnu = "menu" & idx
IniRead txt %def% "Buttonbar" %"%mnu%"
#OutputDebugString("Autorun: txt = " & txt)
pos = StrPos(txt, "Объединить панели")
If pos > 0 Then
str = StrMid(txt, pos)
IniWrite %def% "Buttonbar" %"%mnu%" %"%b% & '|' & %str%"
EndIf
EndIf
ShowDarkHint(b & auCRLF & "Панель закреплена." & auCRLF & "Кнопок = " & c, 0)
If b_Ctrl Then
TwoBars(1)
Return
Endif
EndFunc
Func Bars2PickMenu(AutoBars)
Local menu_type = 2
If Not FileExist(AutoBars) Then
ShowHint("Не найден " & AutoBars)
Return
Endif
IniRead /R menu_type %COMMANDER_INI% "Autorun" "AutoBarsMenu" %"%menu_type%"
Switch menu_type
Case 1
ShowPopupMenu /D %AutoBars%
Case 2
CommandExec("em_bars_panel")
Else
#DisplayOpenBar("em_bars_panel")
RunThread("DisplayOpenBar", "em_bars_panel")
EndSwitch
EndFunc
Func TwoBars(lParam)
Local b_Ctrl = IsPressed(0x11), b_Shift = IsPressed(0x10), b_Alt = IsPressed(0x12), b_Win = IsPressed(0x5B)
Local bar = "Vertical.bar", usr, usr1 = "Auto_user.bar", bar1, def, brs, op = 0
Static m = 0, _
aMenuType = List("ShowPopupMenu","em_bars_panel","DisplayOpenBar")
usr = BarsPath & usr1
brs = BarsPath & "Auto_bars.bar"
If b_Ctrl And b_Shift Then
m += 1
m = (m > 3 ? 1 : m)
IniWrite /R %COMMANDER_INI% "Autorun" "AutoBarsMenu" %m%
ShowHint("Тип меню: " & m & " : "& aMenuType[m-1])
Return
EndIf
If lParam = 1 Then b_Ctrl = true
If Not (b_Ctrl Or b_Shift Or b_Alt Or b_Win) Then
If FileExist(brs) Then
Bars2PickMenu(brs)
Return
Else
b_Win = true
EndIf
EndIf
If b_Win Then
Local aBars = List(), txt, pipe, j
ProcessExecGetOutput pipe %COMSPEC% "/c dir /b *.bar" %BarsPath%
aBars.Text = pipe
txt = "[Buttonbar]"
txt &= auCRLF & "Buttoncount=" & aBars.Count
For j = 0 To aBars.Count - 1
txt &= auCRLF & "Cmd" & j+1 & "=cm_SpliceBarItem " & j+1
#txt &= auCRLF & "Param" & j+1 & "=" & j+1
txt &= auCRLF & "Menu" & j+1 & "=" & aBars[j]
txt &= auCRLF & "Button" & j+1 & "=wcmicons.dll,14"
Next
Free(aBars)
ClipPut(txt)
If SaveClipToFile(brs) Then Bars2PickMenu(brs)
Return
EndIf
If b_Alt Then
If Not FileExist(usr) Then
ShowHint("Панель не найдена " & usr)
Else
CommandExec("em_open_bar", usr1)
EndIf
Return
EndIf
IniRead /R bar1 %COMMANDER_INI% "Autorun" "AutoBars" %"%bar%"
bar = BarsPath & bar1
If Not FileExist(bar) Then
ShowHint("Панель не найдена " & bar)
Return
EndIf
If b_Shift Then
CommandExec("em_open_bar", bar1)
Return
EndIf
ShowDarkHint("Объединение c " & bar1, 0)
Local aBar = List(), _
aItems = List("cmd","param","button","menu","path","iconic"), _
offset, out, b, i, j, k, old, new, found
IniRead def %COMMANDER_INI% "Buttonbar" "Buttonbar" "%COMMANDER_PATH%\DEFAULT.BAR"
If StrPos(def, "%COMMANDER_PATH%") Then
def = %COMMANDER_PATH% & StrReplace(def, "%COMMANDER_PATH%")
Endif
If Not FileExist(def) Then
ShowDarkHint("Главная панель не найдена " & def, 0)
Return
EndIf
IniRead offset %def% "Buttonbar" "Buttoncount" 0
ProcessExecGetOutput def %COMSPEC% '/c type "%def%"'
ProcessExecGetOutput out %COMSPEC% '/c type "%bar%"'
IniRead b %bar% "Buttonbar" "Buttoncount" 0
aBar.Text = out
For j = 0 To aBar.Count - 1
found = false
For i = 1 To b
For k = 0 To aItems.Count - 1
old = aItems[k] & i & "="
new = aItems[k] & i + offset + 1 & "="
If StrPos(aBar[j], old) Then
aBar[j] = StrReplace(aBar[j], old, new)
found = true
break
EndIf
Next
if found then break
Next
Next
#aBar.Remove(0, 2)
aBar[0] = "button" & offset + 1 & "="
aBar[1] = "iconic" & offset + 1 & "="
out = def & auCRLF & aBar.Text
Free(aBar)
Free(aItems)
ClipPut(out)
op = SaveClipToFile(usr)
IniWrite %usr% "Buttonbar" "Buttoncount" %"%offset%+1+%b%"
If op = 1 Then ShowDarkHint("Панели объединены", 0)
If IsPressed(0x12) Then Return
If IsPressed(0x10) Then
CommandExec /CD:S %usr%
Return
EndIf
CommandExec("em_open_bar", usr1)
EndFunc
|
 Кнопка Code: | TOTALCMD#BAR#DATA
61007
totalcmd.exe
Объединить панели| |Ctrl - объединить и открыть|Shift - открыть закрепленную|Ctrl+Shift - выбор типа меню| |Alt - открыть объединенную|Win - пересоздать меню *.bar
-1 |
 TOTALCMD.INC Code: | [________Autorun_________]=0
cm_SpliceBarItem=61008;Splice Bar Menu
|
|
|