Orion9

|
Posted: Sat Mar 07, 2026 12:57 Post subject: |
|
|
Решение от AkulaBig рабочее, у меня этот код проблем не вызывает. Тем не менее, решил сделать альтернативный код, использующий другой алгоритм поиска кнопки.
Делал из интереса, поэтому некоторые моменты не учтены (например, работа с ключем в реестре), но разделение на блоки позволяет легко внести нужные изменения, если они потребуется.
Пример хорошо демонстрирует всю мощь и великолепие скриптового языка, которым стал современный Autorun. Тут вам и запуск в отдельном потоке, и чтение ключей из ini, и проверка существования файлов и каталогов, и раскрытие переменных окружения, и создание массивов, и выполнение операций в цикле, и работа со строками, и вызовы DllCall... Матерь божья! Чувак сделал целый скриптовый движок!
 Hidden text | Code: | LoadLibrary Plugins\Autorun_Tweaks.dll
LoadLibrary Plugins\Autorun_Sysinfo.dll
LoadLibrary Plugins\Autorun_Runtime.dll
LoadLibrary Plugins\Autorun_Process.dll
LoadLibrary Plugins\Autorun_RegExp.dll
RunThread("NagScreen")
Func NagScreen()
Global gNagPush = 0, gNagCtrl = List()
If WincmdKeyExist() Then Return
Local ewp = Callback("EnumChilProc", "hwnd;lparam"), dbg = 1
Local hWnd, nTimeOut = 2000, nSleep = 0
While nTimeOut > 0
hWnd = WinFind(0, "TNASTYNAGSCREEN")
If hWnd > 0 Then
DllCall("EnumChildWindows", "hwnd", hWnd, "ptr", ewp.Ptr, "lparam", 0)
If gNagPush Then Break
EndIf
Sleep(50)
nTimeOut -= 50
Wend
If hWnd = 0 Then Return
If nSleep > 0 Then Sleep(nSleep)
If dbg And IsPressed(0x11) Then ShowHint(gNagCtrl.Text)
Free(gNagCtrl, ewp)
EndFunc
Func WincmdKeyExist()
Local lst = gNagCtrl
Local sKeyPath = IniRead("~/R", COMMANDER_INI, "Configuration", "KeyPath")
If sKeyPath = "$" Then Return 1
If sKeyPath <> "" Then
sKeyPath = JoinPath(Set(sKeyPath))
If FileExist(sKeyPath) Then lst.Add(sKeyPath)
EndIf
lst.Add(COMMANDER_PATH)
lst.Add(FileGetDir(COMMANDER_INI))
If FileExist("c:\totalcmd") Then lst.Add("c:\totalcmd")
For i = 0 To lst.Count - 1
If FileExist(lst[i] & "\wincmd.key") Then Return 1
If FileExist(lst[i] & "\tcmdkey.zip") Then Return 1
Next
Return 0
EndFunc
Func EnumChilProc(hwnd, lparam)
Local Text = WinGetText(hwnd)
gNagCtrl.Add(WinGetClass(hwnd) & " - " & Text)
If StrLen(Text) = 1 Then
gNagPush = Text
Return 1
EndIf
If StrLen(Text) = 2 Then
Text = StrReplace(Text, "&", "")
If Text = gNagPush Then
SendMessage(hwnd, 245, 0, 0)
Return 0
EndIf
EndIf
Return 1
EndFunc |
Что касается алгоритма, принцип примерно такой же. Каждые 50 миллисекунд после старта ТС происходит поиск окна триала. Если окно найдено, перечисляются все элементы управления через вызов EnumChildWindows. Далее сравнивается текст и класс каждого элемента, при совпадении посылается SendMessage.
Пример перечисления есть в справке (объект Callback), он был взят за основу.
Код можно вставить в любое место, но первый вызов "RunThread" должен обязательно идти после "LoadLibrary Plugins", поскольку используются дополнительные функции из модулей такие, как WinFind и ShowHint.
Если dbg = 1, то при запуске с удержанием CTRL отобразится отладочная информация в окне подсказки.
Возможно, запуск в отдельном потоке поможет избавится от конфликта с другими приложениями и плагинами, если таковой конфликт имелся. |
|