View previous topic :: View next topic |
Author |
Message |
Avada
Joined: 01 Aug 2008 Posts: 10364 Location: Россия, Саратов
|
(Separately) Posted: Wed Jan 08, 2025 13:23 Post subject: |
|
|
AkulaBig
Я это всё видел и знаю. Для полной поддержки многоязычности надо капитально переделывать интерфейс TC. Не наблюдаю ни энтузиазма со стороны автора, ни массовой поддержки этой идеи со стороны участников форумов. Тем более, что список отнюдь не исчерпывается пользовательскими меню. Как минимум, есть, например, заголовки вкладок. ИМХО, не будет он с этим связываться. _________________ Даже самая богатая фантазия
Не представит себе наши безобразия. |
|
Back to top |
|
|
AkulaBig
Joined: 03 Dec 2008 Posts: 150
|
(Separately) Posted: Wed Jan 08, 2025 14:18 Post subject: |
|
|
Avada wrote: | ИМХО, не будет он с этим связываться. |
Поэтому я все сам Потихоньку получается. Autorun очень сильно помогает. |
|
Back to top |
|
|
Orion9
Joined: 01 Jan 2024 Posts: 583
|
(Separately) Posted: Wed Jan 08, 2025 17:41 Post subject: |
|
|
Avada wrote: | ИМХО, не будет он с этим связываться. |
Не знаю на счет остального интерфейса (я не сильно в этой теме), но что касается секций [user] и [DirMenu], то не вижу здесь больших препятствий. Что мешает, например, создать еще один языковой файл, скажем WCMD_ENG.CFG [WCMD_RUS.CFG, WCMD_CHN.CFG, ...] и хранить в нем все, что было упущено, включая эти секции? И логики никакой менять не надо: если пользователь самостоятельно не создаст этот файл и не укажет в нем своих секций, они по-прежнему будут браться из wincmd.ini. Но как только пользователь создает этот файл, предподчение должно сразу отдаваться именно ему (этому файлу) и все изменения должны сораняться именно туда, а не в wincmd.ini или его редирект. |
|
Back to top |
|
|
Orion9
Joined: 01 Jan 2024 Posts: 583
|
(Separately) Posted: Wed Jan 08, 2025 23:25 Post subject: |
|
|
AkulaBig
Ну вот, использовал ваш скрипт для переключения внутренних ассоциаций в Autorun Говорил же: добавьте названия секций в параметры и сделайте небольшую документацию в шапке - получится отличный универсальный скрипт для обмена секциями в ini.
ChangeAssoc.vbs Code: | Dim objArgs
Dim objShell
Dim arrLang
arrLang = Array("[+Associations]", "[-Associations]")
Set objShell = WScript.CreateObject("WScript.Shell")
INI = objShell.ExpandEnvironmentStrings("%COMMANDER_PATH%\Ini\Associations.ini")
Text = CreateObject("Scripting.FileSystemObject").OpenTextFile(INI, 1).ReadAll
for i = 0 to UBound(arrLang)
If InStr(1, Text, arrLang(i), 1) = 0 Then
Text = Replace(Text, "[Associations]", arrLang(i), 1, 1, 1)
exit for
End If
next
Set objArgs = WScript.Arguments
If InStr(1, Text, objArgs(0), 1) Then
Text = Replace(Text, objArgs(0), "[Associations]", 1, 1, 1)
With CreateObject("Scripting.FileSystemObject")
.OpenTextFile(INI, 2).Write Text
.OpenTextFile(INI, 1).Close
End With
End If
With CreateObject("Scripting.FileSystemObject")
.OpenTextFile(INI, 2).Write Text
.OpenTextFile(INI, 1).Close
End With
Set objShell = Nothing
WScript.Quit |
autorun.cfg Code: | RegisterCommand 61003 "SwitchAssocState"
# первое выполнение при запуске
AssocState()
Func AssocState()
Local f1, res
IniRead /R f1 %COMMANDER_INI% "Associations" "Filter1" ""
# если в секции что-то есть, значит она включена
If f1 <> "" Then
SetEnv TEST_ICON "%COMMANDER_PATH%\Icons\Clsw\2.ico"
res = true
Else
SetEnv TEST_ICON "%COMMANDER_PATH%\Icons\Clsw\6.ico"
res = false
Endif
Return res
EndFunc
Func SwitchAssocState(lParam)
Local script = %COMMANDER_PATH% & "\Scripts\Vbs\ChangeAssoc.vbs", sect
If AssocState() Then
# отключение секции
sect = '[-Associations]'
Else
# включение секции
sect = '[+Associations]'
Endif
ShellExec /SW_HIDE /WAIT:3000 '%windir%\system32\cscript.exe' '"%script%" "%sect%"'
AssocState()
SendMessage(AUTORUN_TCHANDLE, 11, 0, 0)
CommandExec cm_ReloadFileIcons
CommandExec cm_ReloadBarIcons
sleep(10)
SendMessage(AUTORUN_TCHANDLE, 11, 1, 0)
WinRedraw(1)
EndFunc
|
Hidden text Code: | TOTALCMD#BAR#DATA
61003
%TEST_ICON%
Внутренние ассоциации
1
-1
|
Все четко и гладко работает, но, блин... кажется, нашел баг в ТС (если это баг, конечно).
Жалею теперь, что потратил полчаса, пытаясь понять, где я накосячил, а оказывается в TCASwitcher.exe всё то же самое было.
Если при запуске ТС внутренние ассоциации включены, то никаких проблем нет - все работает как часы. Но если при запуске ассоциации выключены, то переключение не работает. Вернее оно работает с багом: значок переключается, а ассоциации нет. Только перезагрузка помогает. Как я понял, причина здесь в команде cm_ReloadFileIcons, которая не перечитывает значки (хотя должна), если при старте ТС секция ассоциаций была пустая. Но если секция была наполнена, то все работает.
Avada, вам вопрос (или, может быть, еще кто-то ответит, кто знает): как ТС определяет, что включены или выключены внутренние ассоциации? И баг ли это с cm_ReloadFileIcons, а то может Гислеру надо сообщить? |
|
Back to top |
|
|
Avada
Joined: 01 Aug 2008 Posts: 10364 Location: Россия, Саратов
|
(Separately) Posted: Thu Jan 09, 2025 07:26 Post subject: |
|
|
Orion9
Тотал определяет наличие внутренних ассоциаций по содержимому секции [Associations]. На чём и основана работа TCASwitcher. Но команда cm_ReloadFileIcons о трюке с подменой секций не имеет никакого понятия. Если у вас сторонним образом (потому что другого нет) выключены внутренние ассоциации, т.е. секция с ними снабжена таким заголовком, по которому Тотал не обращается, а секция с правильным именем пустая, то их значки для перечитывании этой команде взять неоткуда. Это не баг, а вполне естественное и предсказуемое поведение. _________________ Даже самая богатая фантазия
Не представит себе наши безобразия. |
|
Back to top |
|
|
AkulaBig
Joined: 03 Dec 2008 Posts: 150
|
(Separately) Posted: Thu Jan 09, 2025 12:21 Post subject: |
|
|
Orion9 wrote: | AkulaBig
Ну вот, использовал ваш скрипт для переключения внутренних ассоциаций в Autorun |
Дак мне переключение ассоциаций не надо, поэтому я и не делал
Для переключения ассоциаций есть готовые скрипты, программа. Вроде достаточно инструментов. А мой скрипт все-же для другого. Он заточен чтобы более двух названий переключать. И причем определяет, какой язык используется. |
|
Back to top |
|
|
Orion9
Joined: 01 Jan 2024 Posts: 583
|
(Separately) Posted: Thu Jan 09, 2025 13:26 Post subject: |
|
|
Avada, Спасибо за ответ. В чём-то могу согласиться, но все-таки это больше похоже на недоработку. Возможно, Гислеру об этом не говорили, но команда cm_ReloadFileIcons должна перечитывать секцию прежде, чем перечитывать иконки, тогда она будет работать правильно. Вообще, давно заметил, что Тоталу не хватает команды, которая будет сохранять и перечитывать всю кофигурацию, как это происходит при начальной загрузке, это бы во многом облегчило жизнь. А что касается внутренних ассоциаций, то теперь остается только одно - вызывать окно командой cm_InternalAssociate и "прожимать" ОК, как это и было сделано в старых версиях TCASwitcher. Окно, конечно, мелькает, но зато работает все как надо.
В принципе, я так и сделал, но немного оптимизировал алгоритм: если при запуске ассоциации включены (секция наполнена), то cm_InternalAssociate не посылается, и все работает сверх-гладко, просто глаз радуется. Если же секция была пустой (ассоциации были отключены), то сначала вызывается окно внутренних ассоциаций, нажимается ОК, и только потом обновляется значок на панели. Окно при этом мелькает, но это мелочи.
autorun.cfg Code: | Global IniAssocState
# первое выполнение при запуске
IniAssocState = AssocState()
Func AssocState()
Local f1, res
IniRead /R f1 %COMMANDER_INI% "Associations" "Filter1" ""
# если в секции что-то есть, значит она включена
If f1 <> "" Then
SetEnv TEST_ICON "%COMMANDER_PATH%\Icons\Clsw\2.ico"
res = true
Else
SetEnv TEST_ICON "%COMMANDER_PATH%\Icons\Clsw\6.ico"
res = false
Endif
Return res
EndFunc
Func SwitchAssocState(lParam)
Local script = %COMMANDER_PATH% & "\Scripts\Vbs\ChangeAssoc.vbs", sect
If AssocState() Then
# отключение секции
sect = '[-Associations]'
Else
# включение секции
sect = '[+Associations]'
Endif
ShellExec /SW_HIDE /WAIT:3000 '%windir%\system32\cscript.exe' '"%script%" "%sect%"'
AssocState()
If IniAssocState Then
AssocUpdateWin(true)
Else
RunThread AssocWinSynс
EndIf
EndFunc
Func AssocWinSynс()
Local h = 0, i
PostMessage(AUTORUN_TCHANDLE, 0x433, 519)
# ожидание появления окна
For i = 1 To 75
h = WinFind(0, "TDlgCustomColors")
If h > 0 Then Break
Sleep(25)
#OutputDebugString(h)
Next
If h > 0 Then
b = WinFind(h, "TButton", 3)
SendMessage(b, 0xF5, 0, 0)
Else
ShowHint("Окно не найдено")
Return
Endif
AssocUpdateWin(false)
EndFunc
Func AssocUpdateWin(lReload)
SendMessage(AUTORUN_TCHANDLE, 11, 0, 0)
If lReload Then SendCommand cm_ReloadFileIcons
SendCommand cm_ReloadBarIcons
sleep(10)
SendMessage(AUTORUN_TCHANDLE, 11, 1, 0)
WinRedraw(1)
EndFunc
|
AkulaBig wrote: | Дак мне переключение ассоциаций не надо, поэтому я и не делал |
Так ведь дело не только в ассоциациях: ваш скрипт к чему угодно можно применить, вы только добавьте ему универсальности, чтобы можно было управлять именем файла и секциями через параметры, а не созданием повторных экземпляров. Вам же самому пригодится, если будете делать [DirMenu] по тому же принципу.
AkulaBig wrote: | Для переключения ассоциаций есть готовые скрипты, программа. Вроде достаточно инструментов. |
Это да. Но на Autorun-то еще не было, да еще и в таком коллабе |
|
Back to top |
|
|
AkulaBig
Joined: 03 Dec 2008 Posts: 150
|
(Separately) Posted: Thu Jan 09, 2025 14:30 Post subject: |
|
|
Orion9 wrote: | чтобы можно было управлять именем файла и секциями через параметры, а не созданием повторных экземпляров. |
Ну вы представляете, сколько параметров придется передавать. ТС поддерживает вроде 18 языков. Плюс внутренний. Плюс название устанавливаемого языка. Получается 20 параметров. А сейчас один параметр и понятный массив внутри с названиями языков. Ну а уж размер скрипта крошечный, можно и 100 копий сделать.
Добавлено спустя 1 час 30 минут:
Кстати, немного увеличить универсальность можно за счет изменения обозначения массива языков. Ведь по сути набор языков - это константа, которая будет в любой операции. Но тогда надо будет передавать наименование файла. Тоже не очень приятно, но осуществимо. |
|
Back to top |
|
|
Orion9
Joined: 01 Jan 2024 Posts: 583
|
(Separately) Posted: Thu Jan 09, 2025 19:16 Post subject: |
|
|
AkulaBig
Согласен. Для вашей задачи такое вряд ли подойдет. Но как я писал выше, универсальность вашего скрипта хорошо может проявиться на ограниченном числе параметров, что и нужно большенству пользователей, имхо.
Да и вашей задаче большое число параметров не помеха
Попробуйте, например, кнопку:
Code: | RegisterCommand 63001 "TestVbsArgs"
Func TestVbsArgs(lParam)
Local txt, pipe
Local VbsPath = %COMMANDER_PATH% & "\Scripts\Vbs\"
Local LangPath = %COMMANDER_PATH% & "\LANGUAGE\"
ProcessExecGetOutput pipe %COMSPEC% "/c dir /b *.*" %LangPath%
pipe = StrReplace(pipe, auCRLF, " ")
ProcessExecGetOutput txt "cscript.exe" "/nologo Args.vbs %pipe%" %VbsPath%
ShowHint(txt)
EndFunc |
Args.vbs
Code: | Set objArgs = Wscript.Arguments
WScript.Echo objArgs.Count
For i = 0 to objArgs.Count -1
Wscript.Echo "Arg" & i & " = " & objArgs.Item(i)
Next |
Code: | TOTALCMD#BAR#DATA
63001
%COMMANDER_EXE%
Тест параметров Vbs
1
-1
|
Скрипт Autorun перечисляет все файлы в папке Language (которых по умолчанию 53) и передает их в качестве параметров vbs-скрипту. Скрипт принимает все параметры, перечисляет и возвращает результат в Autorun.
Но все-равно я думаю, вам не стоит таким заморачиваться. А если и нужен универсальный скрипт для смены языковых секций [user] и [DirMnu], то, наверно, лучше другой алгоритм для этого использовать. |
|
Back to top |
|
|
AkulaBig
Joined: 03 Dec 2008 Posts: 150
|
(Separately) Posted: Thu Jan 09, 2025 20:05 Post subject: |
|
|
Orion9 wrote: | Code: | ProcessExecGetOutput txt "cscript.exe" "/nologo Args.vbs %pipe%" %VbsPath%
|
|
А вы с какой-то целью cscript.exe прописываете? Просто я попробовал, прекрасно без этого работает.
Добавлено спустя 1 час 8 минут:
Orion9 wrote: |
Скрипт Autorun перечисляет все файлы в папке Language (которых по умолчанию 53) и передает их в качестве параметров vbs-скрипту. Скрипт принимает все параметры, перечисляет и возвращает результат в Autorun.
Но все-равно я думаю, вам не стоит таким заморачиваться. |
Дак мой скрипт и не сможет обработать все языки. В моем скрипте очень важно, чтобы в файле User.ini были прописаны все секции, которые упоминаются в массиве. И берется первая, где не прописан язык. Иначе как я узнаю, какой язык используется перед подключением. Ведь ТС узнает только секцию User. |
|
Back to top |
|
|
Orion9
Joined: 01 Jan 2024 Posts: 583
|
(Separately) Posted: Thu Jan 09, 2025 23:36 Post subject: |
|
|
AkulaBig wrote: | А вы с какой-то целью cscript.exe прописываете? Просто я попробовал, прекрасно без этого работает. |
Как это работает? Для ProcessExecGetOutput имя исполняемого файла должно быть обязательно указано, разве нет?
Может быть, вы путаете с ShellExec? Там такой вызов вполне допустим:
Code: | ShellExec "Args.vbs" %params% %VbsPath% |
Но тогда скрипт Args.vbs не сможет вернуть в Autorun данные через stdout.
AkulaBig wrote: | Дак мой скрипт и не сможет обработать все языки. |
А ведь Тотал, похоже, в окне для смены языка просто считывает *.lng из каталога LANGUAGE и предлагает их пользователю для переключения. Если изменить команду на %COMSPEC% "/c dir /b *.lng" %LangPath%, то скрипт получит все 18 языков в качестве своих параметров (или другое количество из каталога), которые будут соответствовать макросу AUTORUN_TCLANGFILE - другие языки пользователь просто не может выбрать через интерфейс. Может быть, из этого что-то и получилось бы, но мне кажется:
AkulaBig wrote: | Иначе как я узнаю, какой язык используется перед подключением. Ведь ТС узнает только секцию User. |
Вам, вероятно, нужен другой алгоритм, который будет запоминать с какого языка на какой происходило переключение и менять секции местами. |
|
Back to top |
|
|
sa
Joined: 29 Apr 2009 Posts: 2676
|
(Separately) Posted: Fri Jan 10, 2025 12:33 Post subject: |
|
|
Orion9 wrote: | Блин, я офигел, как гладко работает! |
По-моему, тут всё дело в добавлении паузы sleep(10) после cm_ReloadBarIcons (2945) и WinRedraw(1).
Переделал подобным же образом обновление панели инструментов при изменении количества строк в ней:
Code: | SendMessage(AUTORUN_TCHANDLE, 11, 0, 0)
SendCommand 2901
SendCommand 2901
sleep(10)
SendMessage(AUTORUN_TCHANDLE, 11, 1, 0)
WinRedraw(1) |
|
|
Back to top |
|
|
AkulaBig
Joined: 03 Dec 2008 Posts: 150
|
(Separately) Posted: Fri Jan 10, 2025 12:45 Post subject: |
|
|
Orion9 wrote: |
Может быть, вы путаете с ShellExec? |
Ну да, у меня через него сделано.
Orion9 wrote: |
Но тогда скрипт Args.vbs не сможет вернуть в Autorun данные через stdout.
|
Мне это и не надо, но вы немного по другому хотите сделать.
Orion9 wrote: |
скрипт получит все 18 языков в качестве своих параметров |
И как вы потом определите:
AkulaBig wrote: | Иначе как я узнаю, какой язык используется перед подключением. Ведь ТС узнает только секцию User. |
У меня это решается просто. Все необходимые секции должны быть прописаны. И с помощью массива я узнаю, какой язык используется в настоящее время. Поэтому я не могу читать весь список языков. Тогда только нейросеть может определить текущий язык
Пытаюсь сейчас сделать скрипт несколько универсальнее. Когда у меня было прописано конкретно название секции InStr нормально отрабатывал.А сейчас склеенные данные не понимает. Сравнивает не по полному соответствию. Похоже вместо [User_lng] надо писать [lng_User]. Так как [User] считается подстрокой. |
|
Back to top |
|
|
Orion9
Joined: 01 Jan 2024 Posts: 583
|
(Separately) Posted: Fri Jan 10, 2025 18:19 Post subject: |
|
|
sa wrote: | По-моему, тут всё дело в добавлении паузы sleep(10) после cm_ReloadBarIcons (2945) и WinRedraw(1). |
Похоже, да. Иначе команда разрешения перерисовки окна выполняется раньше, чем панель перерисовывается. Но, видимо, это сейчас и самое слабое место, т.к. на разных машинах, особенно слабых, эта цифра наверняка будет разной, и sleep(10) может попросту не хватить. Но работает не хуже чем в TCFS2, хотя в справке написано, что функция WinRedraw находится в тестовой стадии и перерисовка методом RedrawWindow отключена по умолчанию, хотя только именно этот метод почему-то и работает.
AkulaBig wrote: | И как вы потом определите: |
Не берите в голову, это просто были творческие изыскания: интересно же посмотреть на что способен Autorun и как он гоняет параметры туда-сюда через stdout |
|
Back to top |
|
|
AkulaBig
Joined: 03 Dec 2008 Posts: 150
|
(Separately) Posted: Fri Jan 10, 2025 22:51 Post subject: |
|
|
Вот, вроде и получился универсальный скрипт. Даже комменты написал
ChangeLang.vbs
Code: |
' Смена текущей секции ini-файлов в зависимости от выбранного языка
Dim objShell
Dim arrLang
Dim ini, sect, lng
' Поддерживаемые языки. В ini-файле должны быть секции, название которых
' создано по шаблону [sect_lng]. Количество секций должно соответствовать
' количеству поддерживаемых языков
arrLang = Array("eng", "rus")
Set objShell = WScript.CreateObject("WScript.Shell")
' Имя ini-файла, в котором необходимо менять названия секций, в зависимости
' от выбранного языка
ini = objShell.ExpandEnvironmentStrings(WScript.Arguments(0))
' Название оригинальной секции, которая используется программой
sect = WScript.Arguments(1)
' Язык, который будет использоваться текущим. Оригинальная секция будет без
' дополнения названия языка и соответствовать шаблону [sect_lng]. Все остальные
' секции будут соответствовать шаблону [sect_lng]
lng = WScript.Arguments(2)
Text = CreateObject("Scripting.FileSystemObject").OpenTextFile(ini, 1).ReadAll
' Переименовываем все секции по шаблону [sect_lng]
for i = 0 to UBound(arrLang)
If InStr(1, Text, "[" & sect & "_" & arrLang(i) & "]", 1) = 0 Then
Text = Replace(Text, "[" & sect & "]", "[" & sect & "_" & arrLang(i) & "]", 1, 1, 1)
exit for
End If
next
' Переименовываем оригинальную секции по шаблону [sect]
If InStr(1, Text, "[" & sect & "_" & lng & "]", 1) Then
Text = Replace(Text, "[" & sect & "_" & lng & "]", "[" & sect & "]", 1, 1, 1)
End If
With CreateObject("Scripting.FileSystemObject")
.OpenTextFile(ini, 2).Write Text
.OpenTextFile(ini, 1).Close
End With
Set objShell = Nothing
WScript.Quit
|
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|