Orion9

|
Posted: Sat Sep 27, 2025 20:12 Post subject: |
|
|
Loopback
Я недавно запрашивал фичу, чтобы у подсказки можно было менять текст без вызова другой подсказки, но если полезете в код, то хотелось бы задавать максимальную ширину подсказки. Сейчас это динамическая величина, зависящая от длины строки. Но если строка слишком длинная, то и подсказка может получиться на весь экран, хочется как-то ограничивать этот размер.
Сейчас столкнулся с такой проблемой. Назначил вызов функции на Ctrl+1..Ctrl+5, но в окне листера клавиши не перехватываются. То есть если у меня открыто окно плагина TCMediaInfo, то смена режимов не срабатывает, хотя я поставил Return -1 в ShowPipeEx.
 Hidden text SetHotkeyAction /K:C /H:1 /DM /S ShowPipeEx 0 1
SetHotkeyAction /K:C /H:2 /DM /S ShowPipeEx 0 2
SetHotkeyAction /K:C /H:3 /DM /S ShowPipeEx 0 3
SetHotkeyAction /K:C /H:4 /DM /S ShowPipeEx 0 4
SetHotkeyAction /K:C /H:5 /DM /S ChangeLeftsideHint
Конечно, можно сменить на Alt или на Ctrl+Alt, но мне хотелось бы именно Ctrl использовать. Пока сменил на Alt, чтобы не было проблем, полный код чуть ниже.
A55555
Я вчера не сразу понял, какая у вас проблема с именами. Да, шаблоны не работают, если в них использовать кириллицу (в лучшем случае теряется секция, а в худшем шаблон не загружается). Но у вас другая проблема. Сверху попадает подсказка от проводника или самого ТС (поэтому поле дублируется), так работает подсказка на Autorun - оригинальная подсказка сливается с дополнительной подсказкой, с этим ничего не поделаешь. Дополнительная подсказка только добавляет новые поля, но не заменяет существующие.
С главами действительно есть баг, который за пять лет так и не был исправлен.
Я взял стандартный шаблон, который идет с GUI-версией библиотеки:
 Example.csv General;General : %CompleteName%\r\nFormat : %Format%$if(%OverallBitRate%, at %OverallBitRate/String%)\r\nLength : %FileSize/String%[ for %Duration/String1%]\r\n\r\n
Video;Video #%StreamKindID% : %Format%$if(%BitRate%, at %BitRate/String%)\r\nAspect : %Width% x %Height% (%AspectRatio%)$if(%FrameRate%, at %FrameRate% fps)\r\n\r\n
Audio;Audio #%StreamKindID% : %Format%$if(%BitRate%, at %BitRate/String%)\r\nInfos : %Channel(s)/String%, %SamplingRate/String%\r\n$if(%Language%,Language : %Language%\r\n)\r\n
Text;Text #%StreamKindID% : %Format%\r\n$if(%Language%,Language : %Language%\r\n)\r\n
Chapters;Chapters #%StreamKindID% : %Total% chapters\r\n\r\n
File_Begin
File_End
Page_Begin
Page_Middle
Page_End
General_Begin
General_End
Video_Begin
Video_Middle
Video_End
Audio_Begin
Audio_Middle
Audio_End
Text_Begin
Text_Middle
Text_End
Chapters_Begin
Chapters_Middle
Chapters_End
Но даже в нем Chapters не работает. Такой вот неприятный сюрприз.
Все-равно оставил эту строку в hint.txt. Последняя версия шаблона:
 hint.txt General;"Name: %FileName%.%FileExtension%\nSize: %FileSize/String4%\n[Duration: %Duration%]\n[Duration: %Duration/String1%]\n[Duration: %Duration/String5%]\n
[General: %BitRate/String%][(%BitRate_Mode%)][, %Format%]$if(%Cover%,\, Cover)$if(%IsStreamable%,\, Streamable)[, %FrameRate/String%]"\n
Video;Video #%StreamKindID%: [%Width%x%Height%][, %Format%][(%Format/Family%)][, %Language%][, %AspectRatio/String% (%AspectRatio%)][, %Resolution/String%][, %FrameRate/String%][, %BitRate/String%][(%BitRate_Mode%)]\n
Video_Begin;
Video_Middle;
Video_End;\n
Audio;Audio #%StreamKindID%: [%Channel(s)%ch][, %SamplingRate/String%][, %BitRate/String%][ (%BitRate_Mode%)][, %Format%][, %Format_Profile%][, %Language%][, %FrameRate/String%]\n
Audio_Begin;
Audio_Middle;
Audio_End;\n
Text;Text #%StreamKindID%: %Format%[, %Language/String3%][, %StreamSize/String3%][, %BitRate/String%][, %FrameRate/String%][, %SamplingRate/String%]\n
Text_End;\n
Chapters;Chapters #%StreamKindID%: %Total% chapters\n
Image;Image #%StreamKindID%: [%Width%x%Height%pix][, %Format%][, %StreamSize/String5%][, %ColorSpace% (%ChromaSubsampling%)][, %BitDepth/String%][, %ColorSpace_ICC%]\n
Menu;Menu #%StreamKindID%: [%MenuID/String%][, Format:%Format/String%][ Chapters: \[%Chapters_Pos_Begin%-%Chapters_Pos_End%\]]
Еще два шаблона, которые понадобятся для новой подсказки:
 size.txt General;Name: %FileName%.%FileExtension%\r\nSize: %FileSize/String4%\r\nGeneral: [%StreamSize/String%]\r\n
Video;Video #%StreamKindID%: [%StreamSize/String%]\r\n
Audio;Audio #%StreamKindID%: %StreamSize/String%\r\n
 duration.txt General;Name: %FileName%.%FileExtension%\r\nSize: %FileSize/String4%\r\nGeneral:\r\n [Duration: %Duration%]\r\n [Duration: %Duration/String1%]\r\n [Duration: %Duration/String5%]\r\n
Video;Video #%StreamKindID%: \r\n [Duration: %Duration%]\r\n [Duration: %Duration/String1%]\r\n [Duration: %Duration/String5%]\r\n
Audio;Audio #%StreamKindID%: \r\n [Duration: %Duration%]\r\n [Duration: %Duration/String1%]\r\n [Duration: %Duration/String5%]\r\n
Скинул еще раз, чтобы не приходилось отматывать назад.
Обновленный код подсказки.
 Hidden text Code: | SetHotkeyAction /K:A /H:1 /DM /S ShowPipeEx 0 1
SetHotkeyAction /K:A /H:2 /DM /S ShowPipeEx 0 2
SetHotkeyAction /K:A /H:3 /DM /S ShowPipeEx 0 3
SetHotkeyAction /K:A /H:4 /DM /S ShowPipeEx 0 4
SetHotkeyAction /K:A /H:5 /DM /S ChangeLeftsideHint
Global gHintPipe = "", _
gHintClipb = true, _
gHintLines = 60, _
gHintWait = 50, _
gHintShift = "duration.txt", _
gHintCaps = true
Global gHintLayout = List(10, 75, 15), _
gHintContent = List("size.txt", "Inform", "hint.txt"), _
gHintSleep = List(0, 250, 0)
If SYSINFO_DESKTOPHEIGHT < 1080 Then gHintLines = 50
If SYSINFO_DESKTOPHEIGHT < 720 Then gHintLines = 40
Func MagicHint(FileName, FieldIndex, UnitIndex)
If FieldIndex > gHintLines Then Return
If StrPos(FileGetAttr(FileName), "D") Then Return ""
Local bCaps = DllCall("GetKeyState", "int", 0x14, "short")
Local b_CTRL = BitAND(bCaps, 1), b_Shift = IsPressed(0x10)
If Not b_CTRL then b_CTRL = IsPressed (0x11)
If gHintCaps And Not b_CTRL Then Return
Static sLib
If auX64 Then
sLib = "MediaInfo.dll" # 64-bit
Else
sLib = "MediaInfo_i386.dll" # 32-bit
EndIf
Static sPath = COMMANDER_PATH & "\Ini\Tools\Libs\", _
sLang ="file://" & sPath & "ru.csv", _
sHint ="file://" & sPath & "hint.txt", _
sSize ="file://" & sPath & "size.txt", _
hLib = DllCall("LoadLibrary", "Wstr", sPath & sLib, "Ptr")
Static Idx = 0, bLang = true, nWait = 0, _
pNew, pOpen, pDel, pOpt, pInfo
If hLib = 0 And FieldIndex > 1 Then Return
If FieldIndex = 1 Then
If hLib = 0 Then Return "Error LoadLibrary " & sLib
Idx = 0
pNew = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_New", "Ptr")
pOpen = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_Open", "Ptr")
pDel = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_Delete", "Ptr")
pOpt = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_Option", "Ptr")
pInfo = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_Inform", "Ptr")
nWait = 0
bLang = true
sMode = "Inform"
If gHintWait > 0 Then Sleep(gHintWait)
Local x, y, w, nCase = 0
Local hWnd = RequestInfo(ItemAtCursor("panel"))
WinGetPos("", "", "w", "", hWnd)
If w > 0 Then
MouseGetPos("x","y")
Static buf = Buffer(8) # POINT
buf.Zero()
buf.SetNum(0, "long", x, "long", y)
DllCall("ScreenToClient", "hwnd", hWnd, "ptr", buf.ptr)
x = buf.GetNum(0)
Switch Round(x/w*100,0)
Case 0 To gHintLayout[0]-1
nCase = 0
Case gHintLayout[0] To gHintLayout[0]+gHintLayout[1]-1
nCase = 1
Case 100-gHintLayout[2] To 100
nCase = 2
EndSwitch
nWait = gHintSleep[nCase]
sMode = gHintContent[nCase]
EndIf
If nWait > 0 Then Sleep(nWait)
If sMode = "" Then
gHintPipe = ""
Return
ElseIf sMode <> "Inform" Then
bLang = false
sMode ="file://" & sPath & sMode
EndIf
Local hMI = DllCall(pNew, "Ptr")
If hMI = 0 Then Return "MediaInfo.dll couldn't create new object"
If DllCall(pOpen, 'Ptr', hMI, "Wstr", FileName, "Uint") <> 1 Then
DllCall(pDel, "Ptr", hMI)
Return "MediaInfo.dll couldn't open file " & FileName
EndIf
If b_Shift Then
DllCall(pOpt, 'Ptr', hMI, "Wstr", "Complete", "Wstr", "1", "Wstr")
Else
DllCall(pOpt, 'Ptr', hMI, "Wstr", "Complete", "Wstr", "0", "Wstr")
EndIf
DllCall(pOpt, "Ptr", hMI, "Wstr", "Output", "Wstr", sMode, "Wstr")
DllCall(pOpt, 'Ptr', hMI, "Wstr", "Language", "Wstr", (Not bLang ? "" : sLang), "Wstr")
gHintPipe = DllCall(pInfo, 'Ptr', hMI, "Uint", 0, "Wstr")
If Not bLang Then gHintPipe = StrReplace(gHintPipe, Chr(32), Chr(160))
DllCall(pOpt, 'Ptr', hMI, "Wstr", "Language", "Wstr", "", "Wstr")
DllCall(pDel, "Ptr", hMI)
If IsPressed(0x5B) Then Idx = gHintLines
Endif
If Not bLang Then Return StrPart(gHintPipe, auCRLF, FieldIndex)
Return FixSpaces(StrPart(gHintPipe, auCRLF, FieldIndex + Idx))
EndFunc
Func FixSpaces(String)
Local a, b
If Not StrPos(String, ":") Then Return String
a = StrPart(String, ":", 1)
b = StrPart(String, ":", 2) & StrPart(String, ":", 3)
Return StrTrim(a) & ": " & FixCodePage(StrTrim(b))
EndFunc
Func FixCodePage(String)
Local bUsedRepl
# iso-8859-1 = 28591
DllCall("WideCharToMultiByte", _
"uint", 28591, _
"dword", 0, _
"wstr", String, _
"int", -1, _
"ptr", 0, _
"int", 0, _
"ptr", 0, _
"bool*", @bUsedRepl)
If bUsedRepl Then Return String
Local nSize = StrLen(String)
Local buf = Buffer(nSize)
buf.Zero()
DllCall("WideCharToMultiByte", _
"uint", 28591, _
"dword", 0, _
"wstr", String, _
"int", -1, _
"ptr", buf.ptr, _
"int", nSize, _
"ptr", 0, _
"ptr", 0)
Local fixed = buf.GetStr(0, nSize, "ANSI")
Free(buf)
Return fixed
EndFunc
Func ShowPipeEx(lParam, nPage)
Local sPipe, nLines = gHintLines
Local aPipe = List(), j, nSect = 0
Local nEnd = nPage*nLines, nStart = nEnd - nLines
If gHintClipb Then ClipPut(gHintPipe)
aPipe.Text = gHintPipe
For j = 0 To aPipe.Count - 1
If aPipe[j] = "" Then nSect += 1
If (j + 1) >= nStart And (j + 1) <= nEnd Then
sPipe &= StrLeft(FixSpaces(aPipe[j]),84) & auCRLF
EndIf
Next
Free(aPipe)
If sPipe = "" Then sPipe = "Out of range"
ShowHint(StrTrim(sPipe))
Return -1
EndFunc
Func ChangeLeftsideHint()
Static init = gHintContent[0]
If gHintContent[0] = init Then
gHintContent[0] = gHintShift
Else
gHintContent[0] = init
EndIf
SetHintParam("ShowHint", "Font", 15, "Arial")
SetHintParam("ShowHint", "BackColor", 0xFF0000)
SetHintParam("ShowHint", "Text", 0xFFFFFF)
ShowHint("Left side is " & gHintContent[0], "", "", 1000, 1)
Sleep(50)
SetHintParam("ShowHint", "Reload")
EndFunc
|
Добавлена фича постраничного вывода подсказки, а также гибкость в управлении схемой расположения секций. Пока еще не полная гибкость, но уже лучше.
Переменные.
gHintClipb - копировать в буфер всю подсказку при отображении в страничном режиме
gHintLines - число строк подсказки, больше 60 быть не может
gHintWait - задержка для всех секций перед отображением
gHintShift - шаблон для смены "на лету", только для левой секции
gHintCaps - если false, подсказка будет отображаться без CapsLock или Ctrl
gHintLayout - размер каждой секции в процентах
gHintContent - шаблон для каждой секции; если пустой "", в секцию ничего не попадает, кроме самой подсказки ТС или проводника; если "Inform" - стандартный отчет MediaInfo; если имя файла, то шаблон из файла (файлы должны находиться в каталоге MediaInfo.dll, существование файла не проверяется, в случае отсутствия сообщений об ошибке не будет, отобразится сырой результат отчета MediaInfo).
gHintSleep - задержка для каждой секции.
Пара примеров.
Code: | gHintCaps = false
gHintLayout = List(15, 70, 15)
gHintContent = List("Inform", "", "duration.txt")
gHintSleep = List(500, 0, 0) |
Подсказка будет вызываться всегда (CapsLock отключен). Левая секция - 15%, Центр - 70%, Правая секция - 15%. В левой секции стандартный отчет MediaInfo с задержкой 500 млс, в центре ничего не выводится, в правой секции шаблон duration.txt.
Code: | gHintCaps = true
gHintLayout = List(10, 80, 10)
gHintContent = List("size.txt", "hint.txt", "Inform")
gHintSleep = List(0, 0, 0) |
Подсказка вызывается дополнительно (CapsLock включен). Левая секция - 10%, Центр - 80%, Правая секция - 10%. В левой секции шаблон size.txt, в центре шаблон hint.txt, в правой секции стандартный отчет MediaInfo. Отдельных задержек перед вызовом нет.
Дополнительно шаблон в левой секции может меняться "на лету" с тем, что указан в gHintShift. Комбинация для смены Alt+5.
Кроме Alt+5 действуют еще 4 комбинации: Alt+1..Alt+4. Каждая из этих комбинаций выводит одну страницу последней подсказки и опционально копирует ее в буфер. Такое применение удобно на очень больших подсказках, которые обрезаются на 60-и строках, оставляя одну страницу просмотра. Нажав Alt+2 можно переместиться на вторую страницу и так далее. Всего четыре страницы.
Получилась более универсальная подсказка, чем прежняя, но делал все буквально на лету, т.ч. могут быть какие-то ошибки или недочеты. Только дальнейшее использование покажет. |
|