| View previous topic :: View next topic |
| Author |
Message |
Orion9

Joined: 01 Jan 2024 Posts: 943
|
(Separately) Posted: Wed Nov 12, 2025 13:27 Post subject: |
|
|
Только не сбивайте мне вайб, у меня маза пошла, иду на рекорд
Титаник и Леон лежат ровно, чего не скажешь о бэкапах ТС - их словно пробили на перфокарте )
 Hidden text
Шутки шутками, а я нашёл серьёзный косяк. Не учёл, что панель может изменяться не только при перетаскивании кнопок, но и при обычных операциях копирования и вставки. Соответственно, индекс нарушался. Внёс небольшие изменения, а также добавил ключ "/R", который забыл в прошлый раз добавить.
 Bars.aucfg | Code: | Pragma IncludeOnce
# наведение на главную панель
ControlSetHint /F /D:50 28 "HBarShowHint"
# правый клик с удержанием Ctrl
ControlSetMouseAction /R /K:C 28 "HBarShowMenu"
Global gDragIndex, gDropIndex
Global gHBarButtons = 0, gHBarDivs = 0
Global gHBarName, gHBarFile, gHBarFileTs,
Global gHBarTxt, gHBarCP = "ANSI", gHBarWincmd = 0
Global gHBarHint = 0, gHBarVerb, gHBarCancel, gHBarCancelLoad, gHBarLoadError = 0
Global gHBarList = List(), gHBarMap = List(), gHBarUndo, gHBarUndoTs, gHBarUndoLoad
Global gHBarWndProc, hBarWnd = 0
Global gHBarWP = Callback("HBarWndProc", "hwnd;uint;wparam;lparam")
Func HBarWndProc(hWnd, uMsg, wParam, lParam)
Static IsDrag = 0, _
hTotal = DllCall("GetModuleHandleW", "Ptr", 0, "handle"), _
MK_SHIFT = 0x0004, _
MK_CONTROL = 0x0008, _
MK_LBUTTON = 0x0001, _
WM_MOUSEMOVE = 0x0200, _
WM_LBUTTONDOWN = 0x0201, _
WM_LBUTTONUP = 0x0202
Static drag_system = DllCall("LoadCursor", "Ptr", 0, "Ptr", 32646), _
stop_system = DllCall("LoadCursor", "Ptr", 0, "Ptr", 32648), _
drag_cursor = DllCall("LoadCursor", "Ptr", hTotal, "Ptr", 22), _
stop_cursor = DllCall("LoadCursor", "Ptr", hTotal, "Ptr", 21)
Static SM_CXDRAG = 68, SM_CYDRAG = 69, _
dragX = GetSystemMetrics(SM_CXDRAG), dragY = GetSystemMetrics(SM_CYDRAG), _
startX, startY
Local x, y, pos
If gHBarLoadError Then
Return DllCall("CallWindowProcW", _
"ptr", gHBarWndProc, "hwnd", hWnd, "uint", uMsg, "wparam", wParam, "lparam", lParam)
EndIf
Switch uMsg
Case WM_LBUTTONDOWN
If IsDrag = 0 And BitAND(wParam, MK_CONTROL) Then
#MouseGetPos("x","y")
Static buf = Buffer(8) # POINT
buf.Zero()
x = BitAND(lParam, 0xFFFF)
y = BitAND(BitShift(lParam,16), 0xFFFF)
startX = x
startY = y
buf.SetNum(0, "int", x, "int", y)
DllCall("ClientToScreen", "hwnd", hWnd, "ptr", buf.ptr)
pos = buf.GetNum(0, "int64")
#x = buf.GetNum(0)
#y = buf.GetNum(4)
#If DllCall("DragDetect", "hwnd", hWnd, "int64", MakeInt(y, x, 2)) Then
If DllCall("DragDetect", "hwnd", hWnd, "int64", pos) Then
IsDrag = 1
WinSetStyle(0x80000, 3, hWnd)
DllCall("SetLayeredWindowAttributes", "hwnd", hWnd, "ptr", 0, "byte", 128, "dword", 2)
gDragIndex = HBarGetIdx()
Else
IsDrag = 0
DllCall("CallWindowProcW", _
"ptr", gHBarWndProc, "hwnd", hWnd, "uint", uMsg, "wparam", wParam, "lparam", lParam)
DllCall("CallWindowProcW", _
"ptr", gHBarWndProc, "hwnd", hWnd, "uint", WM_LBUTTONUP, "wparam", wParam, "lparam", lParam)
Return 0
EndIf
EndIf
Case WM_LBUTTONUP
If IsDrag = 1 Then
DllCall("ReleaseCapture")
IsDrag = 0
If WinFromPoint() = hWnd Then
gDropIndex = HBarGetIdx()
If gDragIndex <> gDropIndex Then
If gHBarHint Then ShowDragHint("Index " & gDragIndex & " To Index: " & gDropIndex)
HBarDragnDrop(gDragIndex, gDropIndex)
EndIf
EndIf
WinSetStyle(0x80000, 5, hWnd)
#Return 0
#MouseGetPos("x","y")
#lParam = MakeInt(y, x + 200, 2)
lParam = 0
EndIf
Case WM_MOUSEMOVE
If IsDrag = 1 And BitAND(wParam, MK_LBUTTON) Then
If WinFromPoint() = hWnd Then
DllCall("SetCursor", "Ptr", drag_cursor)
Else
DllCall("SetCursor", "Ptr", stop_cursor)
EndIf
EndIf
EndSwitch
Return DllCall("CallWindowProcW", _
"ptr", gHBarWndProc, "hwnd", hWnd, "uint", uMsg, "wparam", wParam, "lparam", lParam)
EndFunc
Func HBarShowHint()
If WinHasStyle(0x80000, 1, hBarWnd) Then Return
# состояние Ctrl
Local bMap = IsPressed(0x11)
# состояние CapsLock и Shift
If Not bMap Then
If BitAND(DllCall("GetKeyState", "int", 0x14, "short"), 1) = 0 Then
If Not IsPressed(0x10) Then Return
EndIf
EndIf
# дескриптор горизонтальной панели
Local hWnd = RequestInfo(28)
If hWnd = 0 Then
Return "Окно панели не найдено " & hWnd
EndIf
# глобальные переменные дескриптора и оконной процедуры
If hBarWnd <> hWnd Then
hBarWnd = hWnd
gHBarWndProc = DllCall("SetWindowLong" & (auX64 ? "PtrW" : "W"), _
"hwnd", hBarWnd, "int", -4, "long_ptr", gHBarWP.Ptr, "ptr")
EndIf
# поиск файла панели
If gHBarName <> WinGetText(hBarWnd) Then
gHBarUndo = false
gHBarUndoLoad = ""
gHBarCancel = false
gHBarCancelLoad = ""
gHBarFile = HBarGetFile()
If Not FileExist(gHBarFile) Then
gHBarName = ""
Return "Файл панели не найден " & gHBarFile
EndIf
# метка времени
gHBarFileTs = FileGetTime(gHBarFile)
# загрузка панели
HBarLoad()
If gHBarLoadError Then Return HBarGetHint(bMap)
ElseIf FileGetTime(gHBarFile) <> gHBarFileTs Then
gHBarUndo = false
gHBarUndoLoad = ""
If Not FileExist(gHBarFile) Then
gHBarName = ""
Return "Файл панели не найден " & gHBarFile
EndIf
gHBarFileTs = FileGetTime(gHBarFile)
HBarLoad()
If gHBarLoadError Then Return HBarGetHint(bMap)
EndIf
# индекс кнопки под курсором
gDragIndex = HBarGetIdx()
If Not gDragIndex Then Return "Не удалось определить индекс кнопки"
Return HBarGetHint(bMap)
EndFunc
Func HBarGetFile()
Local bar, txt
# информация о файле панели в wincmd.ini
IniRead /R bar %COMMANDER_INI% "Buttonbar" "Buttonbar" "%COMMANDER_PATH%\DEFAULT.BAR"
# раскрытие переменной окружения
bar = Set(bar)
# в конфигурации указано только имя файла
If FileGetDir(bar) = "" Then bar = COMMANDER_PATH & "\" & bar
gHBarWincmd = bar
# чтение текста окна панели
txt = WinGetText(hBarWnd)
gHBarName = txt
# на панель загружен временный .bar файл
If Not StrPos(bar, txt) Then
bar = COMMANDER_PATH & "\Bars\" & txt
EndIf
If Not FileExist(bar) Then
bar = GetCurrentPath() & "\" & txt
EndIf
# проверка существования файла панели
If Not FileExist(bar) Then
bar = COMMANDER_PATH & "\" & txt
EndIf
Return bar
EndFunc
Func HBarLoad()
gHBarLoadError = 0
Local bar = FileRead(gHBarFile, 128, "RAW")
Local bom = "FFFE"
Local utf = "5B0042007500740074006F006E006200610072005D000D000A00"
If ERROR = 1 Then
gHBarLoadError = 1
gHBarCP = "Unknown"
Return
EndIf
If StrLeft(bar, 4) = "FFFE" Then
gHBarCP = "UTF-16 BOM"
Else
IF StrPos(bar, utf) Then
gHBarCP = "UTF-16 без BOM"
Else
gHBarCP = "ANSI"
EndIf
EndIf
# загрузка файла в массив
gHBarList.Count = 0
gHBarList.LoadFromFile(gHBarFile, gHBarCP)
# количество кнопок в файле
Local nCount = 0
IniRead /R nCount %gHBarFile% "Buttonbar" "Buttoncount" 0
# обнуление счетчиков
gHBarDivs = 0
gHBarButtons = 0
# локальные переменные
Local j, key, val, found, oButton = Map(), oCmd = Map()
# поиск кнопок и команд
For j = 0 To gHBarList.Count - 1
found = 0
If StrLeft(gHBarList[j], 6) = "button" Then
found = 1
ElseIf StrLeft(gHBarList[j], 3) = "cmd" Then
found = 2
EndIf
If found > 0 Then
key = StrLower(StrPart(gHBarList[j], "=", 1))
val = StrLen(StrPart(gHBarList[j], "=", 2))
If found = 1 Then
oButton.Set(key, val)
Else
oCmd.Set(key, val)
EndIf
EndIf
Next
gHBarMap.Count = 0
# подсчет кнопок и разделителей
For j = 1 To nCount
key = "button" & j
val = oButton.Get(key, 0)
If val > 0 Then
# количество кнопок
gHBarButtons += 1
gHBarMap.Add(1)
Else
# количество разделителей
gHBarDivs += 1
gHBarMap.Add(0)
EndIf
Next
Free(oButton, oCmd)
If gHBarButtons = 0 Then gHBarLoadError = 1
# карта панели
gHBarTxt = auCRLF & auCRLF & "Loaded" & ": " & gHBarFile & " > " & gHBarCP & " "
If gHBarLoadError Then gHBarTxt &= " -- ERROR LOADING"
gHBarTxt &= auCRLF
For j = 0 To gHBarMap.Count - 1
gHBarTxt &= gHBarMap[j] & " "
If j > 0 and Mod(j, 50) = 0 Then gHBarTxt &= auCRLF
Next
gHBarTxt &= auCRLF & "Wincmd.ini: " & gHBarWincmd
EndFunc
Func HBarGetIdx()
# дескриптор монитора окна ТС
Local hMon = DllCall("MonitorFromWindow", "hwnd", AUTORUN_TCHANDLE, "dword", 2)
# буфер для структуры MONITORINFOEX
Local buf = Buffer(104)
buf.Zero()
buf.SetNum(0, "dword", 104)
DllCall("GetMonitorInfoW", "ptr", hMon, "ptr", buf.ptr)
# имя монитора
Local sMon = buf.GetStr(40)
# информация о масштабировании экрана
Local DC = DllCall("GetDC", "int", 0)
Local nDPI = DllCall("GetDeviceCaps", "handle", DC, "int", 88) # LOGPIXELSX
Local nScale = DllCall("MulDiv", "int", 100, "int", nDPI, "int", 96)
DllCall("ReleaseDC", "int", 0, "handle", DC)
# локальные переменные
Local x, y, w, h, mx, my, idx, row, rows, rowh, dpi, b, extra
# координаты и размеры окна панели
WinGetPos("x", "y", "w", "h", hBarWnd)
# координаты указателя мыши
MouseGetPos("mx", "my")
# чтение информации о высоте кнопок
IniRead /R b %COMMANDER_INI% "Buttonbar" "Buttonheight"
IniRead /R dpi %COMMANDER_INI% "Buttonbar" "DefaultDpi" %'nDPI'
Local b_ini = b, b_calc
# масштабирование экрана
If dpi <> nDPI Then
IniRead /R d %COMMANDER_INI% "Buttonbar" %'"Buttonheight" & nDPI' 0
If d <> 0 Then
b = d
Else
b = Round(b / (dpi / nDPI), 0)
b_calc = "*"
EndIf
EndIf
# количество рядов кнопок на панели
rows = Floor(h/b)
If rows = 0 Then Return HBarShowHint("Error number of rows can't be zero")
# количество дополнительных пикселей
extra = Mod(h,b)
# ширина разделителя
Local div = Floor(b/3)
# высота одного ряда
rowh = b + 3
# номер ряда под указателем
row = Ceil((my - y)/rowh)
# абстрактные координаты по оси х
Local tx = (mx - x + 1) + ((row - 1) * w), cx = 0
# индекс кнопки в ряду
If gHBarDivs = 0 Then
idx = (Floor((mx - x)/b) + 1) + (row-1)*(Floor(w/b))
Else
j = 1
idx = 0
For i = 0 To gHBarMap.Count - 1
cx += (gHBarMap[i] = 0 ? div : b)
ex = j*w - cx
If i + 1 <= gHBarMap.Count - 1 Then
If ex < (gHBarMap[i+1] = 0 ? div : b) Then
cx += ex
j += 1
EndIf
Else
cx += ex
EndIf
If cx >= tx Then
idx = i + 1
Break
EndIf
Next
EndIf
# дополнительная информация
gHBarVerb = "mouse=" & mx & ", " & my & auCRLF & _
"bar=" & x & ", " & y & ", " & w & ", " & h & auCRLF & _
"map=" & tx & ", " & cx & auCRLF & _
"row=" & row & " of " & rows & auCRLF & _
"height=" & rowh & " (" & extra & ")" & " b=" & b & b_calc & " (" & b_ini & ")" & auCRLF & _
"buttons=" & gHBarButtons & " + " & gHBarDivs & " divs" & auCRLF & _
"width=" & b & ", " & div & auCRLF & _
"mon=" & HMon & " dpi=" & nDPI & " scale=" & nScale & "%"
Return idx
EndFunc
Func HBarGetHint(bMap)
# чтение информации о кнопке из .bar фйла
Local sMenu, sButton, sCmd, sParam, sPath, sIcon
IniRead sMenu %gHBarFile% "Buttonbar" %'"menu" & gDragIndex' ""
IniRead sButton %gHBarFile% "Buttonbar" %'"button" & gDragIndex' ""
IniRead sCmd %gHBarFile% "Buttonbar" %'"cmd" & gDragIndex' ""
IniRead sParam %gHBarFile% "Buttonbar" %'"param" & gDragIndex' ""
IniRead sPath %gHBarFile% "Buttonbar" %'"path" & gDragIndex' ""
IniRead sIcon %gHBarFile% "Buttonbar" %'"iconic" & gDragIndex' ""
# удаление подсказки тотала
Local hTip = WinFind(0, "TToolTip")
If hTip > 0 Then DllCall("DestroyWindow", "handle", hTip)
# возврат текста
Return gHBarVerb & auCRLF & _
"" & auCRLF & _
"index=" & gDragIndex & " of " & gHBarButtons+gHBarDivs & auCRLF & _
"menu=" & sMenu & auCRLF & _
"button=" & sButton & auCRLF & _
"cmd=" & sCmd & auCRLF & _
"param=" & sParam & auCRLF & _
"path=" & sPath & auCRLF & _
"iconic=" & sIcon & (bMap ? gHBarTxt : "")
EndFunc
Func HBarDragnDrop(DragIdx, DropIdx)
Static aItems = List("button","cmd","param","path","menu","iconic")
Local T1, T2, bTL = 0
If bTL Then T1 = GetUptime()
Local i, j, k, txt, key, new
txt = gHBarList.Text
gHBarUndoLoad = txt
If Not gHBarCancel Then
gHBarCancel = true
gHBarCancelLoad = txt
EndIf
# временная замена индекса
For j = 0 To aItems.Count - 1
key = aItems[j] & DragIdx & "="
new = aItems[j] & 9999 & "="
txt = StrReplace(txt, key, new)
Next
If bTL Then
T2 = Round(GetUptime() - T1, 0) / 1000
OutputDebugString("Время операции 1: " & StrFormat("%.3f", T2) & " sec")
EndIf
If DragIdx < DropIdx Then
For i = DragIdx + 1 To DropIdx
For k = 0 To aItems.Count - 1
key = aItems[k] & i & "="
new = aItems[k] & i - 1 & "="
txt = StrReplace(txt, key, new)
If bTL Then OutputDebugString("DragIdx < " & key & " -> " & new)
Next
Next
Else
For i = DragIdx - 1 TO DropIdx Step -1
For k = 0 To aItems.Count - 1
key = aItems[k] & i & "="
new = aItems[k] & i + 1 & "="
txt = StrReplace(txt, key, new)
If bTL Then OutputDebugString("DragIdx > " & key & " -> " & new)
Next
Next
EndIf
If bTL Then
T2 = Round(GetUptime() - T1, 0) / 1000
OutputDebugString("Время операции 2: " & StrFormat("%.3f", T2) & " sec")
EndIf
For j = 0 To aItems.Count - 1
key = aItems[j] & 9999 & "="
new = aItems[j] & DropIdx & "="
txt = StrReplace(txt, key, new)
Next
gHBarList.Text = txt
gHBarList.SaveToFile(gHBarFile, gHBarCP)
gHBarUndoTs = FileGetTime(gHBarFile)
gHBarFileTs = FileGetTime(gHBarFile)
If gHBarUndoTs Then
gHBarUndo = true
Else
gHBarUndo = false
gHBarUndoLoad = ""
EndIf
HBarLoad()
If bTL Then
T2 = Round(GetUptime() - T1, 0) / 1000
OutputDebugString("Время операции 3: " & StrFormat("%.3f", T2) & " sec")
EndIf
SendCommand(2945) # cm_ReloadBarIcons
EndFunc
Func ShowDragHint(DragHint)
SetHintParam("ShowHint", "Font", 14, "Arial")
SetHintParam("ShowHint", "BackColor", 0x000000)
SetHintParam("ShowHint", "Text", 0xFFFFFF)
SetHintParam("ShowHint", "DarkBackColor", 0xFF0000)
SetHintParam("ShowHint", "DarkText", 0xFFFFFF)
ShowHint(DragHint, "", "", 3000, 1)
WinAlign(LAST_HINT_WINDOW)
Sleep(10)
SetHintParam("ShowHint", "Reload")
EndFunc
Func HBarShowMenu()
Local hWnd = RequestInfo(28)
If hWnd = 0 Then
ShowDragHint("Окно панели не найдено")
Return
EndIf
If gHBarName <> WinGetText(hWnd) Then
ShowDragHint("Нет сведений о файле панели")
Return
EndIf
ShowPopupMenu /D /F /I:0 "HBarMenu"
EndFunc
Func HBarMenu()
Local txt
Local bak1 = FileChangeExt(gHBarFile, "bak1")
Local bak2 = FileChangeExt(gHBarFile, "bak2")
txt &= 'MENUITEM "' & gHBarName & '", em_aucmd /D' & auCRLF
txt &= 'MENUITEM SEPARATOR' & auCRLF
txt &= 'MENUITEM "Загружена как ANSI", em_aucmd ' & (gHBarCP = "ANSI" ? "/C" : "") & ' -1' & auCRLF
txt &= 'MENUITEM "Загружена как UTF-16", em_aucmd ' & (StrPos(gHBarCP, "UTF-16") ? "/C" : "") & ' -1' & auCRLF
txt &= 'MENUITEM SEPARATOR' & auCRLF
txt &= 'MENUITEM "Отменить действие", em_aucmd ' & (gHBarUndo ? "" : "/D") & ' -1 HBarUndo' & auCRLF
txt &= 'MENUITEM "Отменить последние действия", em_aucmd ' & (gHBarCancel ? "" : "/D") & ' -1 HBarCancel' & auCRLF
txt &= 'MENUITEM SEPARATOR' & auCRLF
txt &= 'MENUITEM "Резервная копия 1", em_aucmd ' & (FileExist(bak1) ? "" : "/D") & ' -1 HBarLoadBak 1' & auCRLF
txt &= 'MENUITEM "Резервная копия 2", em_aucmd ' & (FileExist(bak2) ? "" : "/D") & ' -1 HBarLoadBak 2' & auCRLF
txt &= 'MENUITEM SEPARATOR' & auCRLF
txt &= 'MENUITEM "Сделать резервную копию 1", em_aucmd -1 HBarSaveBak 1' & auCRLF
txt &= 'MENUITEM "Сделать резервную копию 2", em_aucmd -1 HBarSaveBak 2' & auCRLF
Return txt
EndFunc
Func HBarSetCodePage(nCodePage)
Local sCP = (nCodePage = 1 ? "ANSI" : "UTF-16")
Local bLoadQ = gHBarCP <> sCP
gHBarCP = sCP
If bLoadQ Then
MsgBox("Открыть панель в кодировке " & gHBarCP & "?", "Autorun", 3+64+0)
If EXTENDED = 6 Then
HBarLoad()
ShowDragHint("Панель открыта как " & gHBarCP)
SendCommand(2945)
EndIf
EndIf
EndFunc
Func HBarSaveBak(nBak)
Local bak = FileChangeExt(gHBarFile, "bak" & nBak)
If FileExist(bak) Then
MsgBox("Файл существует" & auCRLF & auCRLF & _
bak & auCRLF & auCRLF & "Перезаписать?", "Autorun", 3+32+0)
If EXTENDED <> 6 Then Return
EndIf
FileCopy(gHBarFile, bak, 1)
ShowDragHint("Файл сохранен " & bak)
EndFunc
Func HBarLoadBak(nBak)
Local bak = FileChangeExt(gHBarFile, "bak" & nBak)
If Not FileExist(bak) Then
MsgBox("Файл не существует " & bak, "Autorun")
Return
EndIf
If Not FileExist(gHBarFile) Then
MsgBox("Файл не существует " & gHBarFile, "Autorun")
Return
EndIf
MsgBox("Файл " & gHBarFile & " будет перезаписан файлом " & _
bak & auCRLF & auCRLF & "Продолжить?", "Autorun", 3+32+0)
If EXTENDED <> 6 Then Return
FileCopy(bak, gHBarFile, 1)
HBarLoad()
ShowDragHint("Файл загружен " & bak)
SendCommand(2945)
EndFunc
Func HBarUndo()
If Not gHBarUndo Then Return
If FileGetTime(gHBarFile) <> gHBarUndoTs Then
MsgBox("Файл " & gHBarFile & " изменился на диске" & auCRLF & auCRLF & _
"Отмена действия невозможна", "Autorun", 64)
Return
EndIf
FileWrite(gHBarFile, gHBarUndoLoad, gHBarCP)
If ERROR = 1 Then
MsgBox("Ошибка записи " & gHBarFile, "Autorun", 64)
Else
gHBarUndo = false
gHBarUndoLoad = ""
#gHBarFileTs = FileGetTime(gHBarFile)
HBarLoad()
ShowDragHint("Действие отменено")
SendCommand(2945)
EndIf
EndFunc
Func HBarCancel()
If Not gHBarCancel Then Return
If gHBarCancelLoad = "" Then Return MsgBox("Пустое значение CancelLoad")
MsgBox("Файл будет перезаписан" & auCRLF & auCRLF & _
gHBarFile & auCRLF & auCRLF & "Продолжить?", "Autorun", 3+32+0)
If EXTENDED <> 6 Then Return
FileWrite(gHBarFile, gHBarCancelLoad, gHBarCP)
If ERROR = 1 Then
MsgBox("Ошибка записи " & gHBarFile, "Autorun", 64)
Else
gHBarCancel = false
gHBarCancelLoad = ""
#gHBarFileTs = FileGetTime(gHBarFile)
HBarLoad()
ShowDragHint("Первоначальная панель загружена")
SendCommand(2945)
EndIf
EndFunc |
И хотя всё работает, от глюков по-прежнему гарантий нет. Так что делайте резервные копии, если будете пользоваться. А мы тем временем еще раз продемонстрируем Гислеру как происходит "случайное" перетаскивание кнопок на главной панели инструментов:
 Hidden text
Ладно, пора заканчивать этот кордебалет. Осталось только бандл завернуть, и в общем-то для этого всё уже почти готово. |
|
| Back to top |
|
 |
Loopback
Joined: 07 Sep 2009 Posts: 1646
|
(Separately) Posted: Wed Nov 12, 2025 13:28 Post subject: |
|
|
| Orion9 wrote: | | Касаемо Autorun, не совсем понятно, что именно происходит при запуске длительных операций из нескольких кнопок. Как осуществляется многозадачность? Тоталу отсылается номер зарегистрированной команды и адрес привязанной функции, а он уже сам дальше ее крутит? Крутит в своем отдельно созданном для этого потоке? |
Многозадачности тут нет. Когда тотал выполняет команду из кнопки, он посылает сообщение WM_USER + 51 с помощью PostMessage, которое перехватывает хук, устанавливаемый Autorun. Если переданный номер команды зарегистрирован, то управление передается скриптовой функции, если нет - передается дальше тоталу.
Всё это происходит в основном потоке тотала, поэтому надолго блокировать его не стоит. Длительные задачи лучше запускать отдельным потоком с помощью RunThread. |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 943
|
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 943
|
(Separately) Posted: Wed Nov 12, 2025 20:10 Post subject: |
|
|
Если Autorun не скриптовый язык, то на чём тогда 11,000 строк написано?
https://www.upload.ee/files/18792409/TC.11.51.7z.html
P.S. Описания на последний функционал, к сожалению, нет. Всё есть на последних страницах темы и чуть далее, если кому-то будет нужно. |
|
| Back to top |
|
 |
AkulaBig
Joined: 03 Dec 2008 Posts: 457
|
(Separately) Posted: Wed Nov 12, 2025 20:35 Post subject: |
|
|
Orion9
ТС хотелось-бы последней версии увидеть. Вдруг от этого будет что-то зависеть. |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 943
|
(Separately) Posted: Thu Nov 13, 2025 00:38 Post subject: |
|
|
AkulaBig
А что там может зависеть? Последние версии ТС это тупо обновления rar, 7z и кодеков.
Ну ладно, про кодеки шучу, но у маэстро реальный авторский блок и застой идей. Я уже писал об этом год назад. А потому спасение утопающих - дело рук самих утопающих. Autorun дает всю полноту спектра действий, что говорится Гислеру и не снилось. Это ж надо было так положить всю Виндузу к ногам ТС, на такое способен только настощий мастер - Loopback.
В сборке последняя версия Autorun и практически все скрипты, которые у меня есть. Понятно, что Autorun не для всех и некоторые скрипты довольно сложные, я старался в последнее время делать все модульно - подключил модуль и забыл. Но, к сожалению, не всегда так получается, иногда нужно еще в ini файлы настройки вносить, и не в один. Но кого заинтересует функционал, думаю, разберется. Никаких ограничений нет, можете пользоваться всем как сочтете нужным. |
|
| Back to top |
|
 |
AkulaBig
Joined: 03 Dec 2008 Posts: 457
|
(Separately) Posted: Thu Nov 13, 2025 07:35 Post subject: |
|
|
| Orion9 wrote: | | А что там может зависеть? |
Например, проблема, которую мы долго и тщательно обсуждали с Loopback. Улет сообщения об ошибки за пределы экрана в х64. Она исчезла, хотя Loopback ее не устранил. А у вас вроде много кода, где используются окна. |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 943
|
(Separately) Posted: Thu Nov 13, 2025 11:29 Post subject: |
|
|
AkulaBig
ТС х64 в конексте Autorun это отдельная песня, вы же знаете. Поэтому могут быть косяки, и наверняка они есть.
Я, если честно, даже не проверил (не успел просто) работоспособность сборки в х64, и, видимо, напрасно. Сейчас запустил и сразу же заметил, что функционал CapsLock сломан. Поскольку конфиг autorun.cfg остался в сборке старый, в нем отсутствует последние мелкие изменения, но одно из них критичное - ключ /S на CapsLock и возврат кода -1 в привязанной функции:
| Code: | SetHotkeyAction /S /V:20 JoinHintLock 1
SetHotkeyAction /V:20 /K:S JoinHintLock 2
SetHotkeyAction /V:20 /K:C JoinHintLock 3
SetHotkeyAction /V:20 /K:A JoinHintLock 4
Func JoinHintLock(lParam)
If MediaInfoLock > 0 Then
MediaInfoLock = 0
Else
MediaInfoLock = 1
Endif
If lParam = 2 Then MediaInfoLock = 2
If lParam = 3 Then MediaInfoLock = 3
If lParam = 4 Then MediaInfoLock = 4
Return -1
EndFunc |
В секцию финализации, пожалуй, тоже можно добавить
| Code: | If gHBarWndProc > 0 Then
DllCall("SetWindowLong" & (auX64 ? "PtrW" : "W"), _
"hwnd", hBarWnd, "int", -4, "long_ptr", gHBarWndProc, "ptr")
EndIf |
чтобы х64 не крашился при закрытии (хоть и через раз, но помогает).
Забыл еще путь к exiftool поменять в модуле MediaInfo. Без него переключение подсказки по Alt+F12 не срабатывает, и непонятно сразу в чем проблема.
| Code: | Global gMediaExifX32 = COMMANDER_PATH & "\Tools\ExifTool\exiftool.exe" |
В общем, признаю - фиговенько бандл завернул Многие интересные вещи забыл, например добавить монитор каталога в планировщик, которым я в действительности пользуюсь:
 Title\Config.ini [Schedule]
em_update_wdx_menu=1800,10,2,Updating Wdx Array
81000=3600,30,50,Directory Monitor
Хайлайтер от yozhik забыл обновить. Да там копни - много чего можно обнаружить, но перезаливать из-за этого пока не буду. Основная цель ведь не предоставить готовый функционал как таковой, а обменяться идеями. |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 943
|
(Separately) Posted: Thu Nov 13, 2025 21:21 Post subject: |
|
|
AkulaBig
Все-таки перезалил с последней версией ТС.
Может и будет что-то не рвботать, но главное, что все скрипты собраны в одном месте.
Хотел было и другие компоненты обновить, типа ExifTool и MediaInfo.dll, но подумал что нет смысла. |
|
| Back to top |
|
 |
AkulaBig
Joined: 03 Dec 2008 Posts: 457
|
(Separately) Posted: Sun Nov 16, 2025 13:55 Post subject: |
|
|
| Orion9 wrote: | AkulaBig
Все-таки перезалил с последней версией ТС.
|
Ну и правильно. А то кто-нибудь да напишет, что у него не работает, что работает у вас. |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 943
|
(Separately) Posted: Mon Nov 17, 2025 00:42 Post subject: |
|
|
AkulaBig
Сломанный Capslock был реальныи зашкваром, оставлять в таком виде было нельзя. А так, мне кажется, большой разницы между ТС 11.51 и ТС 11.56 нет, всё работает и там, и там.
Loopback
Вызов работает
| Code: | DllCall("GetVolumeInformationW", _
"wstr", sDrive, "wstr:256", @sName, "dword", 512, "ptr", 0, "ptr", 0, "ptr", 0, "wstr:256", @sFS, "dword", 512) |
Если сравнивать эти два вызова
| Code: | Static nam = Buffer(512), fs = Buffer(512)
nam.Zero()
fs.Zero()
DllCall("GetVolumeInformationW", _
"wstr", sDrive, "ptr", nam.ptr, "dword", 512, "ptr", 0, "ptr", 0, "ptr", 0, "ptr", fs.ptr, "dword", 512)
sName = nam.GetStr()
sFS = fs.GetStr() |
они полностью эквивалентны? |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 943
|
(Separately) Posted: Fri Nov 28, 2025 14:08 Post subject: |
|
|
Autorun большая плюшка
Раз, два, три и есть менюшка )
 Drives.aucfg | Code: | Pragma IncludeOnce
Global hDiskWnd, gDiskWndProc, gBindDiskWnd = true
Global gDriveList = List()
ControlSetMouseAction /R 15 DrivesMenu
ControlSetMouseAction /K:S /R 15 DrivesMenu
ControlSetMouseAction /K:C /R 15 DrivesMenu
If gBindDiskWnd Then
Global gDiskWP = Callback("DiskWndProc", "hwnd;uint;wparam;lparam")
hDiskWnd = WinFind(AUTORUN_TCHANDLE, _
AUTORUN_TCARCH = 32 ? "TMyPanel" : "Window", AUTORUN_TCARCH = 32 ? 6 : 10)
If hDiskWnd > 0 Then
gDiskWndProc = DllCall("SetWindowLong" & (auX64 ? "PtrW" : "W"), _
"hwnd", hDiskWnd, "int", -4, "long_ptr", gDiskWP.Ptr, "ptr")
EndIf
EndIf
Func DiskWndProc(hWnd, uMsg, wParam, lParam)
Static WM_LBUTTONDOWN = 0x0201, _
WM_RBUTTONDOWN = 0x0204
Switch uMsg
Case WM_RBUTTONDOWN
DrivesMenu
EndSwitch
Return DllCall("CallWindowProcW", _
"ptr", gDiskWndProc, "hwnd", hWnd, "uint", uMsg, "wparam", wParam, "lparam", lParam)
EndFunc
Func DrivesMenu()
ShowPopupMenu /D /F "CreateDrivesMenu"
#ShowPopupMenu /D /F /I:24 "CreateDrivesMenu"
EndFunc
Func CreateDrivesMenu()
Local txt, bBuffer, bLine, bExtra
Local bRecInfo = IsPressed(0x10) ? false : true
If IsPressed(0x11) Then
bBuffer = true
bLine = true
bExtra = true
EndIf
Static buf = Buffer(256)
buf.Zero()
Local nSymb = DllCall("GetLogicalDriveStringsW", "dword", buf.size, "ptr", buf.ptr)
If Not nSymb Then
MsgBox("Не удалось получить список дисков" & auCRLF "SYSERROR: " & SYSERROR, "Autorun")
Return
EndIf
Local i = 0, sz, sDrive
gDriveList.Count = 0
While 1
sDrive = buf.GetStr(i)
sz = StrLen(sDrive)
If sz = 0 Then break
gDriveList.add(sDrive)
i = i + sz*2 + 2
Wend
Local sVolume, nCluster, nSector, nFree, nTotal, sName, sFS
txt = 'MENUITEM "Этот компьютер", em_aucmd Shell32.dll,15 CommandExec cm_OpenDesktop' & auCRLF
txt &= 'MENUITEM SEPARATOR' & auCRLF
For i = 0 To gDriveList.Count - 1
sDrive = gDriveList[i]
Local nDriveIco
Local nDriveType = DllCall("GetDriveType", "wstr", sDrive, "uint")
Switch nDriveType
Case 0 To 1
nDriveIco = 53 # DRIVE_UNKNOWN
Case 2
nDriveIco = 6 # DRIVE_REMOVABLE
Case 3
nDriveIco = 8 # DRIVE_FIXED
Case 4
nDriveIco = 9 # DRIVE_REMOTE
Case 5
nDriveIco = 11 # DRIVE_CDROM
Case 6
nDriveIco = 12 # DRIVE_RAMDISK
Else
nDriveIco = 7 # DEFAULT
EndSwitch
If sDrive = SystemDrive & "\" Then
sDriveIco = "imageres.dll,31"
Else
sDriveIco = "shell32.dll," & nDriveIco
EndIf
nFree = 0
nTotal = 0
DllCall("GetDiskFreeSpaceW", "wstr", sDrive, _
"dword*", @nCluster, "dword*", @nSector, _
"dword*", @nFree, "dword*", @nTotal)
If nTotal = 0 Then
IF nDriveIco = 11 Then sDrive = "CD-ROM (" & StrReplace(sDrive, "\", "") & ")"
txt &= 'MENUITEM "' & sDrive & '\t' & '", em_aucmd /D ' & sDriveIco & " DrivesMenuGoto " & i & auCRLF
If bLine Then
txt &= 'MENUITEM "' & Chr(9620) & '\t' & "" & '"'& auCRLF
EndIf
Continue
EndIf
Local nLine = 25 - Ceil(nFree/nTotal*25)
Local sLine = StrRepeat(Chr(9620), nLine)
Local nBytes = nCluster*nSector
Local nPrc = Round(100 - nFree/nTotal*100,0) & "%"
Local nSize = SizeFormat(nFree*nBytes, 1, "T", 1, 3) & " / " & SizeFormat(nTotal*nBytes, 1, "T", 1, 3) & " "
DllCall("GetVolumeInformationW", _
"wstr", sDrive, "wstr:256", @sName, "dword", 512, "ptr", 0, "ptr", 0, "ptr", 0, "wstr:256", @sFS, "dword", 512)
If bBuffer Then
Static nam = Buffer(512), fs = Buffer(512)
nam.Zero()
fs.Zero()
DllCall("GetVolumeInformationW", _
"wstr", sDrive, "ptr", nam.ptr, "dword", 512, "ptr", 0, "ptr", 0, "ptr", 0, "ptr", fs.ptr, "dword", 512)
sName = nam.GetStr()
sFS = fs.GetStr()
EndIf
nSize = SizeFormat(nFree*nBytes, 1, "T", 1, 3) & " из " & SizeFormat(nTotal*nBytes, 1, "T", 1, 3) & " свободно"
sDrive = sName & " (" & StrReplace(gDriveList[i], "\", "") & ")"
txt &= 'MENUITEM "' & sDrive & " " & nSize & '\t' & nPrc & '", em_aucmd ' & sDriveIco & " DrivesMenuGoto " & i & auCRLF
If bLine Then
txt &= 'MENUITEM "' & sLine & '\t' & "" & '", em_aucmd ' & "-1" & " DrivesMenuGoto " & i & auCRLF
EndIf
Next
Local rbSize, rbNumber, sRecInfo
If bRecInfo Then
RecycleBinInfo(rbSize, rbNumber)
sRecInfo = SizeFormat(rbSize, 1, "T", 1, 3) & ", " & rbNumber & " элементов"
EndIf
txt &= 'MENUITEM SEPARATOR' & auCRLF
txt &= 'MENUITEM "Корзина: ' & sRecInfo &'" , cm_OpenRecycled' & auCRLF
If bExtra Then
txt &= 'MENUITEM SEPARATOR' & auCRLF
txt &= 'MENUITEM "Сеть", cm_OpenNetwork' & auCRLF
txt &= 'MENUITEM "Панель управления", cm_OpenControls' & auCRLF
EndIf
Return txt
EndFunc
Func DrivesMenuGoto(nItem)
If IsPressed(0x11) Then
SendCommand("cm_OpenDriveByIndex", nItem+1)
Return
EndIf
Local Target = gDriveList[nItem]
If RequestInfo(1000) = 1 Then
CommandExec /CD %'Target'
Else
CommandExec /CD '' %'Target'
Endif
EndFunc
Func RecycleBinInfo(ByRef nSize, ByRef nNumber)
Static buf = Buffer(auX64 ? 24 : 20)
buf.Zero()
buf.SetNum(0, "dword", buf.size)
DllCall("Shell32.dll\SHQueryRecycleBinW", "ptr", 0, "ptr", buf.ptr)
If auX64 Then
nSize = buf.GetNum(8, "int64")
nNumber = buf.GetNum(16, "int64")
Else
nSize = buf.GetNum(4, "int64")
nNumber = buf.GetNum(12, "int64")
EndIf
EndFunc |
Функция перечисления дисков была реализована еще в модуле Torrents.aucfg, но не пропадать же добру напрасно? Решил, что можно развить эту тему и придать функции вторую жизнь.
Меню отображает логические диски с расширенной информацией о размере и занятом пространстве. Вызов с CTRL добавляет полосу для графического представления, но полоса не является графическим объектом (обычный юникодный символ), поэтому смотрится так себе.
Меня больше привлекла возможность использовать это меню в полноэкранном режиме, вызывая его, например, кликом рядом с вкладками или горячей клавишей, но можно использовать и по-другому. Выбор пункта открывает корень диска. Удержание CTRL - текущий каталог на диске.
Есть у меня террабайтный диск, которому больше 10 лет. Большую часть времени он просто спит. Но в последнее время стал просыпаться медленно, и если вызвать меню в этот момент, то оно может не сразу появиться.
Похоже, это происходит из-за подсчета места в корзине, пришлось добавить еще один модификатор Shift. Вызов меню с Shift не вызывает функцию RecycleBinInfo, которая получает сведения о корзине.
В общем, меню пока очень и очень эксперементальное. Над новыми пунктами и функционалом еще можно подумать.
Loopback
Пока я оставил оба варианта в коде, как вы можете видеть. Вопрос больше связан с примером в справке:
| Code: | Local sysdir
DllCall("GetSystemDirectoryW", "wstr:256", @sysdir, "int", 255) |
Почему используется int 255 и какой размер буфера создает wstr:256?
Еще вопрос. ControlSetMouseAction /R 15 DrivesMenu, получается, кликает по кнопкам [\] и [..], можно сделать, чтобы эти кнопки не попадали в индекс 15?
P.S.
Лень все-таки была побеждена, и сводка по зарегистрированным командам родилась.
 Hidden text | Code: | # Alt + "\"
SetHotkeyAction /K:A /V:220 ModuleRegInfo
Global aModuleName = List()
Func ModuleRegInfo()
AutorunModules()
Global gRegCmdCount = 0, gRegCmdName
ShowPopupMenu /D /F /I:0 "ModuleRegInfoMenu"
EndFunc
Func AutorunModules()
Local j = 1, s = ""
Static p = GetState("paths")
aModuleName.Count = 0
While 1
s = StrPart(p, auCRLF, j)
If ERROR = 1 then break
If StrPos(s , '#') And StrRight(s, 3) ="cfg" Then
s = StrPart(StrTrim(s), ": ", 2)
aModuleName.Add(s)
Endif
j += 1
Wend
EndFunc
Func ModuleRegInfoMenu()
Local mnu, txt, text, rex, reg, nRegs, name, i, cmd
Static lst = List("RegisterCommand", "SetHotkeyAction", "ControlSetMouseAction")
Static c = 0
c += 1
If c > lst.Count Then c = 1
cmd = lst[c-1]
For i = 0 To aModuleName.Count - 1
text = FileRead(aModuleName[i])
rex = RegExp("(.)(" & cmd & ".*?)\r\n", text)
txt = ""
reg = 0
If rex.Exec() Then
Do
reg += 1
mark = rex.Match[1] = Chr(10) ? "" : "/D"
txt &= 'MENUITEM "' & StrReplace(rex.Match[2],'"',"") & '", em_aucmd ' & mark & auCRLF
Until not rex.ExecNext()
gRegCmdCount += reg
name = FileGetBaseName(aModuleName[i])
mnu &= 'POPUP "' & name & ' (' & reg & ')"' & auCRLF
mnu &= txt & auCRLF
mnu &= 'END_POPUP' & auCRLF
EndIf
Free(rex)
Next
gRegCmdName = cmd
mnu = 'MENUITEM "' & cmd & '", em_aucmd -1 ClipPut %"gRegCmdName"' & auCRLF & _
'MENUITEM SEPARATOR' & auCRLF & mnu & auCRLF & _
'MENUITEM SEPARATOR' & auCRLF & _
'MENUITEM "Total commands: ' & gRegCmdCount & '", em_aucmd'
Return mnu
EndFunc |
Регулярные выражения, конечно, значительно упростили задачу, спасибо за функционал. Само меню выглядит так:
 Hidden text
Неактивные пункты значит команда находится не в начале строки и скорее всего закомментирована или ее имя просто упоминается где-то в переменных или функциях. |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 943
|
(Separately) Posted: Sat Nov 29, 2025 00:41 Post subject: |
|
|
Loopback
После внесения последних изменений заметил косяк неприятный. Вот так в ТС х64 не работает:
 Hidden text | Code: | Global hDiskWnd, gDiskWndProc, gBindDiskWnd = true
Global gDriveList = List()
ControlSetMouseAction /R 15 DrivesMenu
ControlSetMouseAction /K:S /R 15 DrivesMenu
ControlSetMouseAction /K:C /R 15 DrivesMenu
If gBindDiskWnd Then
Global gDiskWP = Callback("DiskWndProc", "hwnd;uint;wparam;lparam")
hDiskWnd = WinFind(AUTORUN_TCHANDLE, _
AUTORUN_TCARCH = 32 ? "TMyPanel" : "Window", AUTORUN_TCARCH = 32 ? 6 : 10)
If hDiskWnd > 0 Then
gDiskWndProc = DllCall("SetWindowLong" & (auX64 ? "PtrW" : "W"), _
"hwnd", hDiskWnd, "int", -4, "long_ptr", gDiskWP.Ptr, "ptr")
EndIf
EndIf |
А вот так работает:
 Hidden text | Code: | Global hDiskWnd, gDiskWndProc, gBindDiskWnd = true
Global gDriveList = List()
#ControlSetMouseAction /R 15 DrivesMenu
#ControlSetMouseAction /K:S /R 15 DrivesMenu
ControlSetMouseAction /K:C /R 15 DrivesMenu
If gBindDiskWnd Then
Global gDiskWP = Callback("DiskWndProc", "hwnd;uint;wparam;lparam")
hDiskWnd = WinFind(AUTORUN_TCHANDLE, _
AUTORUN_TCARCH = 32 ? "TMyPanel" : "Window", AUTORUN_TCARCH = 32 ? 6 : 10)
If hDiskWnd > 0 Then
gDiskWndProc = DllCall("SetWindowLong" & (auX64 ? "PtrW" : "W"), _
"hwnd", hDiskWnd, "int", -4, "long_ptr", gDiskWP.Ptr, "ptr")
EndIf
EndIf |
Но не просто работает или не работает (если бы так), все, что идет за директивой Pragma Include %COMMANDER_PATH%\Ini\Scripts\Drives.aucfg в основном конфиге не загружается и не обрабатывается. Так я и заметил сначала - нажал на кнопку, а в ответ сообщение, что функция с кодом не зарегистрирована. Такое может прозойти только, если модуль не был подключен, а значит Autorun его не подключил. При выходе мелькает какое-то окно, возможно окно Autorun с ошибкой.
Вообше-то, я хотел повесить оконную функцию на контрол с классом Window:10 для удобства, чтобы не только на строке вкладок можно было вызыввать меню. Есть шанс исправить?
Ранее забыл написать. Если использовать ключ /D в расширенно меню, то ShowPopupMenu без /I:0 создает серый квадрат у неактивных пунктов, если у них нет значка. С этим можно что-то сделать?
А еще в такой записи | Code: | mnu = 'MENUITEM "' & cmd & '", em_aucmd -1 ClipPut %"gRegCmdName"' | ClipPut работает только с глобальной переменной, так и задумано? Кстати, и глобальную переменную с большим текстом такая запись, кажется, режет.
P.S.
Регулярные выражения безусловно добавили прыти. Недавно yozhik писал, что возникаект задача скачать и обработать несколько файлов с интернета, и теперь когда регулярные выражения есть, остается закачать файлы. Самый простой способ сделать всего один вызов к Urlmon.dll\URLDownloadToFileW. Метод имеет недостатки, но для небольших файлов вполне подходит. Простой пример на загрузке и парсинге rss-ленты
 Hidden text | Code: | RegisterCommand 60033 "RSSCheck"
Func RSSCheck()
Local hr, txt, rex, out, i
Local url = "https://totalcmd.net/rss.xml"
Local file = TEMP & "\rss.xml"
hr = DllCall("Urlmon.dll\URLDownloadToFileW", _
"ptr", 0, "wstr", url, "wstr", file, "dword", 0, "ptr", 0, "hresult")
If hr <> 0 Then
txt = "An error occured." & auCRLF & url & auCRLF & _
"Error code: " & hr & auCRLF & GetINetECode(hr)
Return MsgBox(txt, "Autorun", 16)
EndIf
txt = FileRead(file)
rex = RegExp('<item>\R<title>(.*?)</title>(?:.*?)<link>(.*?)</link>\R<pubDate>(.*?)</pubDate>(?:.*?)</item>', txt)
If rex.Exec() Then
Do
i += 1
out &= rex.Match[1] & auCRLF
out &= rex.Match[2] & auCRLF
out &= rex.Match[3] & auCRLF & auCRLF
Until not rex.ExecNext()
EndIf
Free(rex)
MsgBox(out, "RSS " & i, 64)
EndFunc
Func GetINetECode(nCode)
Local sCode
Switch nCode
Case 0x800C0002 # INET_E_INVALID_URL
sCode = "The URL could not be parsed."
Case 0x800C0003 # INET_E_NO_SESSION
sCode = "No Internet session was established."
Case 0x800C0004 # INET_E_CANNOT_CONNECT
sCode = "The attempt to connect to the Internet has failed."
Case 0x800C0005 # INET_E_RESOURCE_NOT_FOUND
sCode = "The Internet resource was not found."
Case 0x800C0007 # INET_E_DATA_NOT_AVAILABLE
sCode = "An Internet connection was established, but the data cannot be retrieved."
Case 0x800C0008 # INET_E_DOWNLOAD_FAILURE
sCode = "The download has failed (the connection was interrupted)."
Case 0x800C000B # INET_E_CONNECTION_TIMEOUT
sCode = "The Internet connection has timed out."
Case 0x800C000C # INET_E_INVALID_REQUEST
sCode = "The request was invalid."
Case 0x800C000D # INET_E_UNKNOWN_PROTOCOL
sCode = "The protocol is not known and no pluggable protocols have been entered that match."
Case 0x800C000E # INET_E_SECURITY_PROBLEM
sCode = "A security problem was encountered (certificate problems, client authentication, etc.)"
Case 0x800C0019 # INET_E_INVALID_CERTIFICATE
sCode = "The SSL certificate is invalid."
Else
sCode = "No error code description"
EndSwitch
Return sCode
EndFunc |
Функция при всей простоте имеет недостатки: не все адреса могут открыться, а также отсутствует гибкая обработка ошибок. К тому же, если файл довольно большой, будет заметное зависание.
Поэтому пришлось сделать еще одну функцию на основе Wininet.dll. В принципе, она уже готова, осталось только оформить все с примерами. Вероятно завтра доделаю. |
|
| Back to top |
|
 |
Loopback
Joined: 07 Sep 2009 Posts: 1646
|
(Separately) Posted: Sat Nov 29, 2025 12:29 Post subject: |
|
|
| Orion9 wrote: | | они полностью эквивалентны |
Параметры размера принимают значение в TCHAR, а не байтах, т.е. должно тоже быть 256. В остальном вроде равноценны.
| Orion9 wrote: | | Почему используется int 255 и какой размер буфера создает wstr:256? |
Создаёт с указанным размером, 256. Размер 255 просто чтобы записанная строка гарантированно завершалось нулем.
| Orion9 wrote: | | чтобы эти кнопки не попадали в индекс 15? |
Нет.
| Orion9 wrote: | | сводка по зарегистрированным командам родилась |
Вот и хорошо, и не нужно обвес для статистики городить.
| Orion9 wrote: | | Есть шанс исправить? |
Не знаю, у меня сейчас нет возможности с этим разбираться.
| Orion9 wrote: | | С этим можно что-то сделать? |
Без кастомной отрисовки нет.
| Orion9 wrote: | | так и задумано? Кстати, и глобальную переменную с большим текстом такая запись, кажется, режет. |
Это ограничение, достаточно очевидное. В пунктах меню напрямую могут использоваться только глобальные переменные, доступные в момент вызова. По обрезке не знаю.
@All
В силу обстоятельств я не смогу отвечать на форуме какое-то время. Отвечу, когда появится такая возможность. |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 943
|
(Separately) Posted: Sat Nov 29, 2025 13:59 Post subject: |
|
|
Loopback
Мне стоило спросить это у "ЫЫ", обычно он хорошо отвечает на такие вопросы. Просто взялся сейчас за многое сразу, не хотел отвлекаться. В частности долго возился с winnet, даже устал как-то. Но в целом оно того стоило.
Сначала думал, что функции URLDownloadToFile хватит для потребностей, и её хватило бы, если бы не один серьёзный недостаток - не все адреса открывает.
Например, такой адрес она не открывает и пишет ошибку INET_E_DATA_NOT_AVAILABLE:
 Hidden text | Code: | https://api.open-meteo.com/v1/forecast?latitude=47.37&longitude=8.55&daily=temperature_2m_max,temperature_2m_min&models=meteoswiss_icon_ch1¤t=temperature_2m,relative_humidity_2m,cloud_cover&timezone=auto&forecast_days=1&format=csv |
Решения, как обойти проблему, мне найти не удалось. А ведь хочется узнать как там у маэстро погода в горах ) Поэтому и пришлось заморочиться Wininet.dll.
И всё работает. Я чуть позже сброшу код, но картинку уже отснял:
 Hidden text
 Hidden text |
|
| 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
|