Я думал просто сменить три параметра в ini и перезапустить тотал.
Да и я [AllResolutions] использую.
Модераторы: Avada, CaptainFlint, Nik, d-view, Моторокер
[/cut]
[/cut]Код: Выделить всё
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
If FileGetTime(gHBarFile) <> gHBarFileTs Then
ShowDragHint("Операция невозможна. Файл панели изменился.")
Return DllCall("CallWindowProcW", _
"ptr", gHBarWndProc, "hwnd", hWnd, "uint", uMsg, "wparam", wParam, "lparam", lParam)
Endif
#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)
Local dark = IniRead(COMMANDER_INI, "Configuration", "DarkMode", 0)
SetHintParam("ShowHint", "Font", 13, "Tahoma")
SetHintParam("ShowHint", "BackColor", 0x0F0F0F)
SetHintParam("ShowHint", "Text", 0xFFFFFF)
SetHintParam("ShowHint", "DarkBackColor", 0xFF0000)
SetHintParam("ShowHint", "DarkText", 0xFFFFFF)
ShowHint(auCRLF & " " & DragHint & " " & auCRLF, 0, 0, 1000, 1)
WinAlign(LAST_HINT_WINDOW)
If Not dark Then
WinSetStyle(0x80000, 3, LAST_HINT_WINDOW)
DllCall("SetLayeredWindowAttributes", _
"hwnd", LAST_HINT_WINDOW, "ptr", 0, "byte", 192, "dword", 2)
EndIf
Sleep(100)
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
#{
поиск индекса по ключу и значению:
bar = COMMANDER_PATH & "\Bars\Main.bar"
idx = FindButtonIdx(bar, "cmd", "61007")
idx = FindButtonIdx(bar, "menu", "Auto_bars")
idx = FindButtonIdx(bar, "button", "WCMICONS.dll,72")
MsgBox(FindButtonIdx(bar, "param", '/ef "tcm(60011,1)"'))
#}
Func FindButtonIdx(ButtonBar, ButtonKey, ButtonVal)
Local txt, pos, len, sub, idx = 0
If Not FileExist(ButtonBar) Then
ShowDragHint("Панель не найдена " & ButtonBar)
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)
If sub = ButtonKey Then
idx = StrMid(txt, pos-i, i)
If IsInt(idx) Then Break
Endif
Next
# перепроверка индекса
If idx > 0 Then
IniRead txt %ButtonBar% "Buttonbar" %"ButtonKey & idx"
If StrPos(txt, ButtonVal) > 0 Then Return idx
EndIf
Return 0
EndFuncКод: Выделить всё
DllCall("RegisterRawInputDevices", "Ptr", Buff.Ptr, "UInt", 1, "UInt", 8 + auPtrSize)
# WM_INPUT
SetMessageAction /P 0x00FF "OnRawInput" Код: Выделить всё
[Buttonbar]
Buttonheight=30 (37)
SmallIconSize=default (24)
[AllResolutions]
Iconsize32=16 (24)Код: Выделить всё
#Requires AutoHotkey v2.0
Persistent
; 1. Регистрация устройства (Мышь)
; RAWINPUTDEVICE структура
UsagePage := 1
Usage := 2
Flags := 0x00000100 ; RIDEV_INPUTSINK (получать ввод даже если окно не в фокусе)
hTarget := A_ScriptHwnd
RAWINPUTDEVICE := Buffer(8 + A_PtrSize, 0)
NumPut("UShort", UsagePage, RAWINPUTDEVICE, 0)
NumPut("UShort", Usage, RAWINPUTDEVICE, 2)
NumPut("UInt", Flags, RAWINPUTDEVICE, 4)
NumPut("Ptr", hTarget, RAWINPUTDEVICE, 8)
if !DllCall("RegisterRawInputDevices", "Ptr", RAWINPUTDEVICE, "UInt", 1, "UInt", 8 + A_PtrSize)
MsgBox "Ошибка регистрации Raw Input"
; 2. Подписка на сообщение WM_INPUT (0x00FF)
OnMessage(0x00FF, OnRawInput)
OnRawInput(wParam, lParam, msg, hwnd) {
; Определяем размер данных
size := 0
DllCall("GetRawInputData", "Ptr", lParam, "UInt", 0x10000003, "Ptr", 0, "UInt*", &size, "UInt", 8 + A_PtrSize * 2)
if (size > 0) {
rawBuffer := Buffer(size)
DllCall("GetRawInputData", "Ptr", lParam, "UInt", 0x10000003, "Ptr", rawBuffer, "UInt*", &size, "UInt", 8 + A_PtrSize * 2)
; Проверяем, что это мышь (тип 0)
type := NumGet(rawBuffer, 0, "UInt")
if (type == 0) {
; Смещение для данных мыши в структуре RAWINPUT
; header (16 байт на x86, 24 на x64) + данные мыши
headerSize := (A_PtrSize == 8) ? 24 : 16
flags := NumGet(rawBuffer, headerSize, "UShort")
lastX := NumGet(rawBuffer, headerSize + 8, "Int")
lastY := NumGet(rawBuffer, headerSize + 12, "Int")
ToolTip "Raw Delta X: " lastX " | Y: " lastY
}
}
}Код: Выделить всё
#Requires AutoHotkey v2.0
Persistent
; Регистрация Raw Input для мыши
RAWINPUTDEVICE := Buffer(8 + A_PtrSize, 0)
NumPut("UShort", 1, RAWINPUTDEVICE, 0)
NumPut("UShort", 2, RAWINPUTDEVICE, 2)
NumPut("UInt", 0x00000100, RAWINPUTDEVICE, 4) ; RIDEV_INPUTSINK
NumPut("Ptr", A_ScriptHwnd, RAWINPUTDEVICE, 8)
if !DllCall("RegisterRawInputDevices", "Ptr", RAWINPUTDEVICE, "UInt", 1, "UInt", 8 + A_PtrSize)
MsgBox "Ошибка регистрации"
OnMessage(0x00FF, OnRawInput)
OnRawInput(wParam, lParam, *) {
size := 0
DllCall("GetRawInputData", "Ptr", lParam, "UInt", 0x10000003, "Ptr", 0, "UInt*", &size, "UInt", 8 + A_PtrSize * 2)
if (size > 0) {
raw := Buffer(size)
DllCall("GetRawInputData", "Ptr", lParam, "UInt", 0x10000003, "Ptr", raw, "UInt*", &size, "UInt", 8 + A_PtrSize * 2)
headerSize := (A_PtrSize == 8) ? 24 : 16
; Извлекаем флаги кнопок мыши
btnFlags := NumGet(raw, headerSize + 4, "UShort")
; 0x0001 — это флаг RI_MOUSE_LEFT_BUTTON_DOWN
if (btnFlags & 0x0001) {
; Проверяем, зажат ли Shift (логическое состояние)
if GetKeyState("Shift", "P") {
HandleShiftClick()
}
}
}
}
HandleShiftClick() {
; Получаем окно под курсором
DllCall("GetCursorPos", "Ptr", pt := Buffer(8))
hWnd := DllCall("WindowFromPoint", "Int64", NumGet(pt, 0, "Int64"), "Ptr")
if (hWnd) {
classBuffer := Buffer(512)
DllCall("GetClassName", "Ptr", hWnd, "Ptr", classBuffer, "Int", 256)
className := StrGet(classBuffer)
ToolTip "Shift + Click на окне класса: " className
SetTimer () => ToolTip(), -2000
}
}Код: Выделить всё
#Requires AutoHotkey v2.0
Persistent
; Константы WinAPI
WM_NCHITTEST := 0x84
HTCAPTION := 2
; Регистрация Raw Input
RAWINPUTDEVICE := Buffer(8 + A_PtrSize, 0)
NumPut("UShort", 1, RAWINPUTDEVICE, 0)
NumPut("UShort", 2, RAWINPUTDEVICE, 2)
NumPut("UInt", 0x00000100, RAWINPUTDEVICE, 4)
NumPut("Ptr", A_ScriptHwnd, RAWINPUTDEVICE, 8)
if !DllCall("RegisterRawInputDevices", "Ptr", RAWINPUTDEVICE, "UInt", 1, "UInt", 8 + A_PtrSize)
MsgBox "Ошибка регистрации"
OnMessage(0x00FF, OnRawInput)
OnRawInput(wParam, lParam, *) {
size := 0
DllCall("GetRawInputData", "Ptr", lParam, "UInt", 0x10000003, "Ptr", 0, "UInt*", &size, "UInt", 8 + A_PtrSize * 2)
if (size > 0) {
raw := Buffer(size)
DllCall("GetRawInputData", "Ptr", lParam, "UInt", 0x10000003, "Ptr", raw, "UInt*", &size, "UInt", 8 + A_PtrSize * 2)
headerSize := (A_PtrSize == 8) ? 24 : 16
btnFlags := NumGet(raw, headerSize + 4, "UShort")
; Проверяем нажатие левой кнопки мыши + Shift
if (btnFlags & 0x0001) && GetKeyState("Shift", "P") {
HandleShiftClick()
}
}
}
HandleShiftClick() {
; 1. Получаем текущие координаты курсора
DllCall("GetCursorPos", "Ptr", pt := Buffer(8))
x := NumGet(pt, 0, "Int")
y := NumGet(pt, 4, "Int")
; 2. Находим окно под курсором
hWnd := DllCall("WindowFromPoint", "Int64", NumGet(pt, 0, "Int64"), "Ptr")
if (hWnd) {
; Поднимаемся к главному родительскому окну (если кликнули по дочернему элементу)
rootHWnd := DllCall("GetAncestor", "Ptr", hWnd, "UInt", 2, "Ptr") ; GA_ROOT
; 3. Получаем класс окна
classBuffer := Buffer(512)
DllCall("GetClassName", "Ptr", rootHWnd, "Ptr", classBuffer, "Int", 256)
className := StrGet(classBuffer)
; 4. Проверяем, заголовок ли это (WM_NCHITTEST)
; Передаем координаты в формате (y << 16) | (x & 0xFFFF)
hitTest := DllCall("SendMessage", "Ptr", rootHWnd, "UInt", WM_NCHITTEST, "Ptr", 0, "Ptr", (y << 16) | (x & 0xFFFF))
isTitleBar := (hitTest == HTCAPTION)
; Вывод результата
msg := "Class: " className "`n"
msg .= "Is Title Bar: " (isTitleBar ? "✅ ДА" : "❌ НЕТ")
ToolTip msg
SetTimer () => ToolTip(), -3000
}
}
Код: Выделить всё
#Requires AutoHotkey v2.0
Persistent
; Константы для читаемости
RI_MOUSE_LEFT_BUTTON_DOWN := 0x0001
WM_INPUT := 0xFF
RID_INPUT := 0x10000003
; Регистрация устройства
RAWINPUTDEVICE := Buffer(8 + A_PtrSize, 0)
NumPut("UShort", 1, RAWINPUTDEVICE, 0)
NumPut("UShort", 2, RAWINPUTDEVICE, 2)
NumPut("UInt", 0x00000100, RAWINPUTDEVICE, 4) ; RIDEV_INPUTSINK
NumPut("Ptr", A_ScriptHwnd, RAWINPUTDEVICE, 8)
DllCall("RegisterRawInputDevices", "Ptr", RAWINPUTDEVICE, "UInt", 1, "UInt", 8 + A_PtrSize)
OnMessage(WM_INPUT, OnRawInput)
OnRawInput(wParam, lParam, *) {
; 1. БЫСТРАЯ ПРОВЕРКА: Если нет нажатия кнопок, мгновенно выходим.
; Это отсекает 99% вызовов, связанных с простым движением мыши.
; Сначала получаем размер данных
size := 0
DllCall("GetRawInputData", "Ptr", lParam, "UInt", RID_INPUT, "Ptr", 0, "UInt*", &size, "UInt", 8 + A_PtrSize * 2)
if (size <= 0)
return
raw := Buffer(size)
DllCall("GetRawInputData", "Ptr", lParam, "UInt", RID_INPUT, "Ptr", raw, "UInt*", &size, "UInt", 8 + A_PtrSize * 2)
headerSize := (A_PtrSize == 8) ? 24 : 16
btnFlags := NumGet(raw, headerSize + 4, "UShort")
; 2. ПРОВЕРКА СОБЫТИЯ: Нас интересует только момент НАЖАТИЯ левой кнопки (0x0001)
if !(btnFlags & RI_MOUSE_LEFT_BUTTON_DOWN)
return
; 3. ПРОВЕРКА МОДИФИКАТОРА: Зажат ли Shift?
if !GetKeyState("Shift", "P")
return
; Если мы дошли сюда, значит произошло ровно то, что нужно: Shift + Left Down
HandleAction()
}
HandleAction() {
; Вся тяжелая логика (WinAPI, ToolTip и т.д.) теперь вызывается
; ТОЛЬКО в момент клика, а не при каждом движении.
DllCall("GetCursorPos", "Ptr", pt := Buffer(8))
x := NumGet(pt, 0, "Int"), y := NumGet(pt, 4, "Int")
hWnd := DllCall("WindowFromPoint", "Int64", NumGet(pt, 0, "Int64"), "Ptr")
if (hWnd) {
rootHWnd := DllCall("GetAncestor", "Ptr", hWnd, "UInt", 2)
classBuffer := Buffer(512)
DllCall("GetClassName", "Ptr", rootHWnd, "Ptr", classBuffer, "Int", 256)
hitTest := DllCall("SendMessage", "Ptr", rootHWnd, "UInt", 0x84, "Ptr", 0, "Ptr", (y << 16) | (x & 0xFFFF))
isTitleBar := (hitTest == 2) ; HTCAPTION
MsgBox "Класс: " . StrGet(classBuffer) . "`nЗаголовок: " . (isTitleBar ? "Да" : "Нет")
}
}
Код: Выделить всё
#Requires AutoHotkey v2.0
; --- 1. Регистрация класса окна ---
className := "MyInvisibleReceiver"
wndClass := Buffer(120, 0) ; Структура WNDCLASSEX
NumPut("UInt", 80, wndClass, 0) ; cbSize
NumPut("Ptr", CallbackCreate(WndProc), wndClass, 8) ; lpfnWndProc
NumPut("Ptr", StrPtr(className), wndClass, 64) ; lpszClassName
if !DllCall("RegisterClassEx", "Ptr", wndClass) {
MsgBox "Ошибка регистрации класса"
ExitApp
}
; --- 2. Создание Message-Only окна ---
; HWND_MESSAGE = -3
hwnd := DllCall("CreateWindowEx",
"UInt", 0,
"Str", className,
"Str", "HiddenWindow",
"UInt", 0,
"Int", 0, "Int", 0, "Int", 0, "Int", 0,
"Ptr", -3, ; ПЕРЕМЕННАЯ HWND_MESSAGE
"Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr")
if !hwnd {
MsgBox "Ошибка создания окна"
ExitApp
}
MsgBox("Окно создано. HWND: " hwnd)
; --- 3. Обработчик событий (Window Procedure) ---
WndProc(hwnd, msg, wParam, lParam) {
; Пример: ловим кастомное сообщение 0x5555
if (msg == 0x5555) {
MsgBox "Событие перехвачено через WinAPI! wParam: " wParam
return 0
}
; Обязательно вызываем стандартный обработчик для остальных сообщений
return DllCall("DefWindowProc", "Ptr", hwnd, "UInt", msg, "Ptr", wParam, "Ptr", lParam, "Ptr")
}
; Тест: отправить сообщение самому себе
F2::DllCall("PostMessage", "Ptr", hwnd, "UInt", 0x5555, "Ptr", 1, "Ptr", 2)
Код: Выделить всё
RunThread("InvisibleReceiver")
Func InvisibleReceiver()
Local text = "InvisibleReceiver"
Local proc = Callback("ReceiverWndProc", "hwnd;uint;wparam;lparam")
Local name = Buffer(StrLen(text) + 2)
name.Zero()
name.SetStr(text, 0, StrLen(text), "ANSI")
Local wndClass = Buffer(auX64 ? 80 : 48) # Структура WNDCLASSEX
wndClass.Zero()
wndClass.SetNum(0, "UInt", wndClass.Size) # cbSize
wndClass.SetNum(8, "Ptr", proc.ptr) # lpfnWndProc
wndClass.SetNum(auX64 ? 64 : 40, "Ptr", name.ptr) # lpszClassName
If Not DllCall("RegisterClassExA", "Ptr", wndClass.Ptr) Then
MsgBox('Ошибка регистрации класса "MyInvisibleReceiver"')
Return 0
EndIf
Free(wndClass)
# Message-Only window
Static HWND_MESSAGE = -3
Local hwnd = DllCall("CreateWindowExA", _
"Dword", 0, _
"Str", text, _
"Str", "HiddenWindow", _
"Dword", 0, _
"Int", 0, "Int", 0, "Int", 0, "Int", 0, _
"Ptr", HWND_MESSAGE, _
"Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr")
If Not hwnd Then
MsgBox 'Ошибка создания окна "HiddenWindow"'
Return 0
EndIf
Static RIDEV_INPUTSINK = 0x00000100
Local rid, buf
rid = Buffer(8 + auPtrSize, 0)
rid.Zero()
rid.SetNum(0, "UShort", 1, "UShort", 2, "UInt", RIDEV_INPUTSINK, "Ptr", hwnd)
# Регистрация устройства
If Not DllCall("RegisterRawInputDevices", "Ptr", rid.Ptr, "UInt", 1, "UInt", 8 + auPtrSize) Then
MsgBox("Ошибка регистрации Raw Input")
Return 0
EndIf
buf = Buffer(auX64 ? 56 : 28)
While 1
DllCall("GetMessage", "ptr", buf.ptr, "hwnd", hwnd, "uint", 0, "uint", 0)
DllCall("TranslateMessage", "ptr", buf.ptr)
DllCall("DispatchMessage", "ptr", buf.ptr)
Wend
Free(rid, buf)
Return 1
EndFunc
Func ReceiverWndProc(hwnd, uMsg, wParam, lParam)
If uMsg = 0x00FF Then
OnRawInput(hWnd, uMsg, wParam, lParam)
EndIf
Return DllCall("DefWindowProc", _
"hwnd", hWnd, "uint", uMsg, "wparam", wParam, "lparam", lParam, "ptr")
EndFunc
Func OnRawInput(hWnd, uMsg, wParam, lParam)
Static RID_INPUT = 0x10000003, _
RI_MOUSE_LEFT_BUTTON_DOWN = 0x0001
# Получение размера данных
Local size = 0
DllCall("GetRawInputData", "Ptr", lParam, "UInt", RID_INPUT, "Ptr", 0, "UInt*", @size, "UInt", 8 + auPtrSize * 2)
If size <= 0 Then Return
Local raw = Buffer(size)
DllCall("GetRawInputData", "Ptr", lParam, "UInt", RID_INPUT, "Ptr", raw.ptr, "UInt*", @size, "UInt", 8 + auPtrSize * 2)
# Извлечение флагов кнопок мыши
Local headerSize = auX64 ? 24 : 16
Local btnFlags = raw.GetNum(headerSize + 4, "UShort")
Free(raw)
# Проверка левого клика
If Not BitAND(btnFlags, RI_MOUSE_LEFT_BUTTON_DOWN) Then Return
# Проверка состояния Shift
If Not IsPressed(0x10) Then Return
# Произошло нажатие Shift + Left Down
HandleAction()
EndFunc
Func HandleAction()
Local x, y
MouseGetPos("x","y")
# Дескриптор окна под курсором
Local hWnd = DllCall("WindowFromPoint", "Int64", MakeInt(x, y, 2), "Ptr")
If Not hWnd Then Return
# Переход к главному родительскому окну
Local rootHWnd = DllCall("GetAncestor", "Ptr", hWnd, "UInt", 2)
# Буфер для получения имени класса
Static classBuffer = Buffer(512)
classBuffer.Zero()
# Получение имени класса
Static WM_NCHITTEST = 0x0084
DllCall("GetClassName", "Ptr", rootHWnd, "Ptr", classBuffer.Ptr, "Int", 256)
Local hitTest = DllCall("SendMessage", _
"Ptr", rootHWnd, "UInt", WM_NCHITTEST, "Ptr", 0, "Ptr", MakeInt(x, y, 0))
# Проверка области клика
Static HTCAPTION = 2
Local isTitleBar = (hitTest = HTCAPTION)
If isTitleBar And classBuffer.GetStr() = "TLister" Then
AlignListerWindow()
EndIf
# MsgBox("Класс: " & classBuffer.GetStr() & auCRLF & "Заголовок: " & (isTitleBar ? "Да" : "Нет"))
EndFuncНу попробуйте, никто ведь не мешает. Может я и перегнул палку, вдруг у вас все заработает.FallenAngel писал(а):Я все равно не понимаю, почему просто не сменить:
Код: Выделить всё
Func Notebook
If IniRead(COMMANDER_INI, "AllResolutions", "Iconsize32") = 16 Then
IniWrite %COMMANDER_INI% "AllResolutions" "Iconsize32" "24"
Else
IniWrite %COMMANDER_INI% "AllResolutions" "Iconsize32" "16"
EndIf
If IniRead(COMMANDER_INI, "Buttonbar", "Buttonheight") = 30 Then
IniWrite %COMMANDER_INI% "Buttonbar" "Buttonheight" "37"
Else
IniWrite %COMMANDER_INI% "Buttonbar" "Buttonheight" "30"
EndIf
If IniRead(COMMANDER_INI, "Buttonbar", "SmallIconSize") = 16 Then
IniWrite %COMMANDER_INI% "Buttonbar" "SmallIconSize" "24"
Else
IniWrite %COMMANDER_INI% "Buttonbar" "SmallIconSize" "16"
EndIf
SendCommand cm_Exit 9
EndFunc Добавить еще один параметр <default>FallenAngel писал(а):Как мне обыграть что у SmallIconSize может отсутствовать знание, но по-умолчанию считаем что 16 ?
Код: Выделить всё
IniRead(["~[/R]",] <ini>, <section, <key>[, <default>])
IniRead [/R] <VAR> <ini> <section> <key>[ <default>]Код: Выделить всё
If IniRead(COMMANDER_INI, "AllResolutions", "Iconsize32", 16) = 16 ThenКод: Выделить всё
SendMessage(AUTORUN_TCHANDLE, 11, 0, 0)
...
команды
команды
...
Sleep(50)
SendMessage(AUTORUN_TCHANDLE, 11, 1, 0)
WinRedraw(1)Наконец-то дошли руки до тестирования. Идея стала понятна. Только воплотить пока не удается. Вот накропал код на основе вашего:Orion9 писал(а):Скорость - космос.
Код: Выделить всё
Func ET1(FileName, FieldIndex, UnitIndex)
Local ExifToolPID = 0, ExifToolOut = TEMP & "\exiftool_out.txt", ExifToolArgs = TEMP & "\exiftool_args.txt"
If StrPos(FileGetAttr(FileName), "D") Then Return
ExifToolPID = ProcessGetId("exiftool.exe")
If ExifToolPID = 0 Then
FileWrite(ExifToolArgs, "", "UTF-8 NOBOM")
ShellExec /TT /SW_HIDE %util_ET% "-stay_open True -@ ""%ExifToolArgs%"""
EndIf
If FileExist(ExifToolOut) Then
ShellExec /SW_HIDE %COMSPEC% '/c del /f /q "%gExifOut%"'
EndIf
Local sArgs = "-f" & auCRLF & _
"-s3" & auCRLF & _
"-m" & auCRLF & _
"-q" & auCRLF & _
"-q" & auCRLF & _
"-Title" & auCRLF & _
"-W+!" & auCRLF & ExifToolOut & auCRLF & FileName & auCRLF & "-execute" & auCRLF
Local obj = BinaryFile(ExifToolArgs, "a")
obj.WriteStr(sArgs, "", "UTF-8")
Free(obj)
ansi = "<time-out>"
For i = 1 To 50
If FileExist(ExifToolOut) Then
ansi = FileRead(ExifToolOut)
ShellExec /SW_HIDE %COMSPEC% '/c del /f /q "%ExifToolOut%"'
Break
EndIf
Sleep(20) # time-out
Next
Return ansi
EndFunc
Так и есть. Для этого там и стоит задержка. ExifTool в режиме -stay_open тупо дергает файл с параметрами каждые 10 миллисекунд и проверяет не появились ли там новые команды. Когда новые команды появляются, результат их выполнения сохраняется в другой файл. Заранее не известно, когда этот файл появится, поэтому приходится ждать его появления. Если в течении 1 секунды файл не появляется, скрипт вернет текст "<time-out>", который и попадет в поле.AkulaBig писал(а): Сначала я подумал, что кривой код. Но похоже код не успевает отработать.
Не стоит это сейчас обсуждать. У вас еще приведено решение задержки от ИИ через While. У себя я его тестил и мне больше понравилось. Давайте лучше разберемся, почему код не работает. Я уже написал выше. У вас выводится подсказка для одного файла. Как видите, ваш код для пользовательских колонок работает неправильно (или я что-то неправильно пишу, хотя вроде практически один в один ваш код). И я про задержки в этом варианте имею ввиду. То-есть есть подозрение, что функция не годится для обработки множества файлов.Orion9 писал(а):Но это никак не должно влиять на скорость.
Код: Выделить всё
Widths32=80,30,30,30,30,30,30,30,30,30,30,30,30
Headers32=C1\nC2\nC3\nC4\nC5\nC6\nC7\nC8\nC9\nC10\nC11
Contents32=[=autorun.C1]\n[=autorun.C2]\n[=autorun.C3]\n[=autorun.C4]\n[=autorun.C5]\n[=autorun.C6]\n[=autorun.C7]\n[=autorun.C8]\n[=autorun.C9]\n[=autorun.C10]\n[=autorun.C11]
Options32=-1|0|96Код: Выделить всё
ShellExec /SW_HIDE %COMSPEC% '/c del /f /q "%gExifOut%"'Код: Выделить всё
ShellExec /SW_HIDE /WAIT:500 %COMSPEC% '/c del /f /q "%gExifOut%"'Вот-вот. Я выше писал про это в другом случае. Там тоже без задержки работало быстро, но неправильно, а с задержкой очень медленно. Это при выводе самих данных. Из-за этого я перешел на буфер обмена. Но данные можно обрабатывать без ShellExec, а удалить файл пока никак.Orion9 писал(а):/WAIT
Код: Выделить всё
# ждем, пока ExifTool создаст файл (цикл ожидания)
Local WaitCount = 0
While Not FileExist("%gExifOut%")
Sleep 50
WaitCount = WaitCount + 1
if WaitCount > 20 then Break # Таймаут 1 сек
Wend