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

Joined: 01 Jan 2024 Posts: 979
|
(Separately) Posted: Sun Jan 04, 2026 14:10 Post subject: |
|
|
FallenAngel
На комментарии просто времени не хватило, хотел сделать рабочий вариант, чтобы вы могли попробовать, и вроде даже успел )
А сам функционал был уже в модуле Title.aucfg, мне просто пришлось освежить немного память и взять кое-что оттуда. Там, конечно, всё сильно нагромождено переменными и раздутым телом цикла, но сам принцип тот же. Запуск заголовка происходит после считывания ключа ShowTitle, а выход из цикла при присвоении переменной gShowTitle значения false.
Есть менее громоздкая версия, состоящая всего из 200 строк. По сути это первая версия заголовка, где алгоритм предается более наглядно, и в нем нет ничего лишнего: только пинг, память и процессор. Если к этому добавить короткую дату и скорость передачи трафика, то и получится заголовок, которым я постоянно пользуюсь.
Вообще, считаю, что Гислер мог и сам сделать такой функционал — он точно не помешал бы и безусловно украсил бы его детище. Но к сожалению, лучшие годы маестро на танцполе уже позади, а включать мозг 8-летней девочки при подходе к проблемам пользователей больше не получается
Например, скорость передачи трафика в заголовке очень даже полезная фича при работе с сетевым диском, а про память и цпу и говорить не нечего.
На счет погоды. Может быть, город и не потребуется. Я сначала думал, что нет возможности указать координаты, но сейчас более внимательно посмотрел, оказыается есть в справке об этом. Соответственно, можно указывать в запросе нужные координаты, например:
https://wttr.in/55.75,37.62?format=3
Что эквивалентно:
https://wttr.in/Moscow?format=3
И наверное, так будет лучше, чем просто указание города или автоматическое определение местоположения по IP.
Но все-равно строку запроса пользователю придется формировать самостоятельно. Для этого нужно знать все ключи однострочного вывода, которые будут сохраняться в ini-файле и считываться оттуда при запуске заголовка.
Интервал обновления тоже будет сохраняться. В общем, завтра попробую что-то сделать. Может с первого наскока чего и получится )
ZiabrevLV
У вас всё почти есть. Нужно только считать ключ DriveBarHide для определения текущего состояния, и в зависимости от его значения, выполнить ту или иную функцию. То есть:
| Code: | Local sDriveBarHide
IniRead sDriveBarHide %COMMANDER_INI% "Configuration" "DriveBarHide" ""
If StrPos(sDriveBarHide, "-") Then
IniWrite %COMMANDER_INI% "Configuration" "DriveBarHide" ""
Else
IniWrite %COMMANDER_INI% "Configuration" "DriveBarHide" "-"
EndIf
CommandExec cm_VisTwoDriveButtons 2
CommandExec cm_VisTwoDriveButtons 1 |
Только я не проверял работоспособность, но кажется здесь нужно быть осторожным, т.к. ключ DriveBarHide может содержать подстроки, а значит их тоже нужно будет сохранять.
 Hidden text | Code: | [Configuration]
DriveBarHide=drive_list
Wincmd.ini Version: 7.03
Управляет скрытием кнопок дисков и других элементов, которые могут находиться в той же панели. Выборочно могут быть скрыты:
A..Z: кнопки с буквами дисков;
0..9: кнопки с активными FTP-подключениями;
\ (обратный слэш): кнопка "Сеть/FS-плагины" для открытия виртуальной папки 'Сеть';
. (точка): пара кнопок для перехода в корневой и родительский каталог;
- (чёрточка): метка текущего тома и сведения о дисковом пространстве;
; (точка с запятой): кнопки для USB-устройств без буквы диска (например, смартфонов).
Символы записываются подряд без разделителей, регистр букв значения не имеет. Пример: A\ (скрытие кнопок для дисковода А: и для сетевого окружения).
По умолчанию значение не задано (ничего не скрывается).
ПРИМЕЧАНИЯ:
В отличие от ключа Allowed, скрытые в этой панели диски остаются доступными в их выпадающем списке (ALT+F1/F2), в цепочках навигации, в дереве каталогов, при навигации с помощью команды "cd" или встроенных команд TC наподобие cm_GoToPreviousDrive/cm_GoToNextDrive. Эффект применения команды cm_OpenDriveByIndex (для переключения на диск с заданным в качестве параметра порядковым номером) зависит от того, отображается ли вообще панель дисков (если да, порядковый отсчёт идёт по ней с игнорированием скрытых кнопок, если нет — по всем пунктам списка дисков).
Метка текущего тома, сведения о дисковом пространстве и кнопки перехода в корневой/родительский каталог добавляются в панель дисков после основных кнопок ТОЛЬКО при отсутствии выпадающего меню дисков (DriveCombo=0), в противном случае они отображаются в строке с этим списком. Значения "." (точка) и "-" (чёрточка, символ дефиса/минуса) учитываются в ключе DriveBarHide ТОЛЬКО при размещении соответствующих элементов основного окна TC в одной панели с кнопками дисков.
Для скрытия дисков клиентского компьютера на терминальном сервере они перечисляются после символа доллара, а в сочетании с другими элементами указываются в последнюю очередь. Например, запись DriveBarHide=A$CDE означает скрытие кнопок для дисковода A: и для клиентских дисков C:, D:, E:.
Следует иметь в виду, что хотя кнопка "Сеть/FS-плагины" непосредственно открывает только список сетевых элементов и/или FS-плагинов, она отображается в панели дисков нажатой и при открытии в файловой панели TC ряда других виртуальных папок ('Рабочий стол', 'Мой компьютер', 'Корзина', 'Принтеры'). |
Т.е. возможно так будет правильнее:
| Code: | RegisterCommand 63003 "SwitchShowHide"
Func SwitchShowHide(lParam)
Local sDriveBarHide, sValue
IniRead sDriveBarHide %COMMANDER_INI% "Configuration" "DriveBarHide" ""
If StrPos(sDriveBarHide, "-") Then
# удаление "-" из значения ключа
sValue = StrReplace(sDriveBarHide, "-", "")
IniWrite %COMMANDER_INI% "Configuration" "DriveBarHide" sValue
Else
# добавление "-" к значению ключа
sValue = sDriveBarHide & "-"
IniWrite %COMMANDER_INI% "Configuration" "DriveBarHide" sValue
EndIf
CommandExec cm_VisTwoDriveButtons 2
CommandExec cm_VisTwoDriveButtons 1
EndFunc |
|
|
| Back to top |
|
 |
ZiabrevLV
Joined: 15 Sep 2022 Posts: 4
|
(Separately) Posted: Sun Jan 04, 2026 17:35 Post subject: |
|
|
Orion9
Да, первый вариант отлично работает.
Спасибо. |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 979
|
(Separately) Posted: Tue Jan 06, 2026 00:38 Post subject: |
|
|
FallenAngel
Мда. Как всегда легко и просто только на бумаге, а берешься делать сразу вслывает куча нюансов. С одними проверками загребешься: тут надо учесть, там надо учесть. Но все-таки доделал, раз уж взялся, тем более что кому-то тоже может пригодится.
Небольшой подвох с сервером: он очень плохо откликается, иногда погода вообще может не обновиться по таймауту. Пришлось немного по-другому сделать отображение процесса обновления, что по сути и отняло больше всего времени.
При наведении на заголовок всплывает посказка. Alt - добавляет информацию о файлах. Ctrl - отображает подсказку о погоде и прогнозе из дополнительно указанной ссылки. Правый клик вызывает меню.
Настройки должны храниться в файле Header.ini в подкаталоге Ini. Т.е. %COMMANDER_INI%\Ini\Header.ini
 Hidden text [Title]
ShowTitle=1
Wttr=1
[Wttr]
Name=Zurich
Interval=3600
Url=https://wttr.in/47.37,8.55?format=%C+%t
Hint=https://wttr.in/47.37,8.55?T
; Examples:
; wttr.in/London?format=3
; wttr.in/London?format="%l:+%c+%t\n"
; Refer to the link below for the details:
; https://github.com/chubin/wttr.in?tab=readme-ov-file#one-line-output
;
; c Weather condition,
; C Weather condition textual name,
; x Weather condition, plain-text symbol,
; h Humidity,
; t Temperature (Actual),
; f Temperature (Feels Like),
; w Wind,
; l Location,
; m Moon phase,
; M Moon day,
; p Precipitation (mm/3 hours),
; P Pressure (hPa),
; u UV index (1-12),
;
; D Dawn*,
; S Sunrise*,
; z Zenith*,
; s Sunset*,
; d Dusk*,
; T Current time*,
; Z Local timezone.
;
;(*times are shown in the local timezone)
Поскольку все эти "города, координаты и прочее" довольно приватная вещь, есть возможность сохранить информацию в дополнительном файле пользователя Wttr.ini, который расположен по умолчанию в LocalAppData\GHISLER\Wttr.ini.
Соответственно, если файл пользователя существует, настройки прежде всего будут считываться с него, кроме двух ключей секции [Title], т.е. ShowTitle и Wttr. Последний отключает погоду в заголоке при Wttr=0
 Пример Wttr.ini [Wttr]
Name=
Interval=1800
Url=https://wttr.in/47.37,8.55?format=%t
Hint=https://wttr.in/47.37,8.55?T
Строку запроса можно настроить по-разному, все зависит от ключей сайта wttr.in.
Ошибки, конечно, могут быть: все сделать и протестировать за один день невозможно. Но радует, что кроме самого Autorun с последним модулем RegExp, для работы больше ничего не требуется.
 InfoHeader.aucfg | Code: | Sleep(200)
# наведение на заголовок
ControlSetHint /F /D:350 /H:2 0 "InfoHeaderHint"
# правый клик
ControlSetMouseAction /R /H:2 0 "InfoHeaderMenu"
# Shift + клик по заголовку
ControlSetMouseAction /L /K:S /H:2 0 "ToggleInfoHeader"
Global gTitle = WinGetText(), gInfoHeader = gTitle, gShowTitle = 1, gTitleThread = 0
Global gWttr = 1, gWttrUrl, gWttrHint, gWttrName, gWttrInterval = 3600
Global gWttrSec = 0, gWttrData, gWttrTip = "", gWttrFile = TEMP & "\wttr.txt", gWttrDataUpdate = 0
Global gWttrIni = COMMANDER_PATH & "\Ini\Header.ini"
Global gWttrIniApp = GetKnownFolderPath("LocalAppData") & "\GHISLER\Wttr.ini"
# запуск
LaunchInfoHeader()
# WM_WINDOWPOSCHANGING
# реагирование заголовка на изменение позиции окна
SetMessageAction 70 "SetInfoHeader"
Func ToggleInfoHeader()
# переключение переменной
gShowTitle = Not gShowTitle
# запись нового значения в Header.ini
IniWrite %gWttrIni% "Title" "ShowTitle" %"gShowTitle"
Sleep(100)
LaunchInfoHeader()
EndFunc
Func SetInfoHeader()
WinSetText(gShowTitle ? gInfoHeader : gTitle)
EndFunc
Func LaunchInfoHeader()
# чтение ключа
IniRead gShowTitle %gWttrIni% "Title" "ShowTitle" 1
# запуск заголовка, если он еще не запущен
If gShowTitle And Not gTitleThread Then
gInfoHeader = gTitle & ' ' & "Booting..."
WinSetText(gInfoHeader)
# подготовка конфигурации
InfoHeaderReadIni()
Sleep(200)
RunThread InfoHeader
EndIf
EndFunc
Func InfoHeaderReadIni()
Local sWttrIni = gWttrIni, sUrl
# чтение из Header.ini
IniRead gWttr %gWttrIni% "Title" "Wttr" 1
IniRead sUrl %sWttrIni% "Wttr" "Url" ""
# чтение из AppData\Wttr.ini
If FileExist(gWttrIniApp) Then
sWttrIni = gWttrIniApp
EndIf
IniRead gWttrUrl %sWttrIni% "Wttr" "Url" ""
IniRead gWttrHint %sWttrIni% "Wttr" "Hint" ""
IniRead gWttrName %sWttrIni% "Wttr" "Name" ""
IniRead gWttrInterval %sWttrIni% "Wttr" "Interval" 3600
# нет данных в AppData
# откат к значению из Header.ini
If gWttrUrl = "" Then gWttrUrl = sUrl
# проверка корректности значения интервала
If Not IsInt(gWttrInterval) Then gWttrInterval = 0
if gWttrInterval < 900 Then gWttrInterval = 900
# по умолчанию интервал считается законченным
gWttrSec = gWttrInterval
# проверка существования локального файла
If FileExist(gWttrFile) Then
# количество секунд с последнего обновления
gWttrSec = Round((Now() - FileGetTime(gWttrFile)) / 10000000)
# прошло меньше секунд, чем отведенный интервал
If gWttrSec < gWttrInterval Then gWttrData = StrTrim(FileRead(gWttrFile))
If gWttrName <> "" Then gWttrData = gWttrName & " " & gWttrData
EndIf
EndFunc
Func InfoHeader
Local nRecvSpeed, nSendSpeed, T1, lst = List(" | "," / ","—"," \ ")
Static c = 0
# поток запущен
gTitleThread = 1
# выполнять пока gShowTitle = true
While gShowTitle
T1 = GetUptime()
# погода включена и требуется обновление
If gWttr And gWttrSec >= gWttrInterval Then
# сброс счетчика
gWttrSec = 0
# запуск обновления в отдельном потоке
RunThread "GetWttrData"
EndIf
GetNetSpeed(nRecvSpeed, nSendSpeed)
# идет процесс обновления
If gWttrDataUpdate Then
c += 1
If c > lst.Count Then c = 1
#gWttrData = Weather updating: " & lst[c-1]
gWttrData = "Weather updating: " & gWttrSec & ' sec.'
EndIf
gInfoHeader = gTitle & ' ' & (gWttr ? gWttrData & ' ' : '') & Date("d MMMM, ddd") & '. CPU: ' & StrFormat("%02d", GetCPUUsage()) & '% RAM: ' & GetMemStats() & '% NET: ↓ ' & Round(nRecvSpeed / 1000, 1) & ' ↑ ' & Round(nSendSpeed / 1000, 1) & ' mb/s'
WinSetText(gInfoHeader)
# разбитие секунды на более мелкие интервалы
# для лучшего отклика при изменении переменной
While GetUptime() < T1 + 1000
If Not gShowTitle Then Break
Sleep(50)
Wend
# увеличение счетчика до следующего обновления погоды
gWttrSec += 1
Wend
Free(lst)
# поток остановлен
gTitleThread = 0
# обновление заголовка
SetInfoHeader()
EndFunc
Func GetWttrData()
Local msg, sData
# флаг операции
gWttrDataUpdate = true
gWttrTip = "Соединение..."
# загрузка файла в тихом режиме
Local code = WinInetDownloadFile(gWttrUrl, gWttrFile, 1)
# снятие флага операции для заголовка
gWttrDataUpdate = false
If code = -1 Then
msg = "WinInet Error: " & code
ElseIf code > 0 Then
msg = "WinInet Error: " & code
gWttrTip = msg & auCRLF & GetWinInetError(code)
EndIf
If code = 0 Then
gWttrTip = "Обновлено"
msg = FileRead(gWttrFile)
If ERROR = 1 Then msg = "FileRead Error: "
EndIf
sData = StrTrim(msg)
gWttrData = sData
# добавление имени местоположения если указано
If code = 0 And gWttrName <> "" Then gWttrData = gWttrName & " " & sData
If code = 0 Then
gWttrSec = 0
Else
# повтор через 30 секунд
gWttrSec = gWttrInterval - 30
EndIf
# загрузка данных для подсказки в тихом режиме
code = WinInetDownloadFile(gWttrHint, TEMP & "\wttr.html", 1)
If code <> 0 Then
msg = "WinInet Error: " & code
gWttrTip &= auCRLF & "Хинт: " & msg & auCRLF & GetWinInetError(code)
EndIf
EndFunc
Func InfoHeaderHint()
Local txt, file = TEMP & "\wttr.html"
If Not IsPressed (0x11) Then
If Not gShowTitle Then Return "Заголовок выключен"
txt &= "Работает" & auCRLF
txt &= "Погода " & (gWttr? "включена" : "отключена") & auCRLF
txt &= "Интервал: " & gWttrInterval & " сек." & auCRLF
txt &= "Обновление через: " & gWttrInterval - gWttrSec & " сек." & auCRLF
If gWttrTip <> "" Then txt &= "Статус: " & gWttrTip & auCRLF
If IsPressed (0x12) Then
txt &= "Файлы конфигурации:" & auCRLF
txt &= gWttrIni & auCRLF
txt &= gWttrIniApp & auCRLF
txt &= "Временные файлы:" & auCRLF
txt &= gWttrFile & auCRLF
txt &= file & auCRLF
EndIf
Return StrTrim(txt)
Endif
txt = FileRead(file)
If ERROR = 1 Then Return "Ошибка чтения " & file
# стиль подсказки
SetHintParam("csh", "Font", 10, "Consolas")
SetHintParam("csh", "BackColor", 0x001C1C1C)
SetHintParam("csh", "Text", 0xF9F9F9)
# извлечение текста из html
txt = StrReplace(txt, '"', '"')
Static lst = List()
lst.Count = 0
lst.Text = RegExpGet(txt, '<pre>(.*?)</pre>', "$1")
For i = 0 To lst.Count - 1
If StrLen(lst[i]) > 125 Then lst[i] = StrLeft(lst[i], 122) & ".."
Next
# вернуть предыдущий стиль через 1 сек.
RunThread InfoHeaderHintReload
Return lst.Text
EndFunc
Func InfoHeaderHintReload()
Sleep(1000)
SetHintParam("sh", "Reload")
SetHintParam("csh", "Reload")
EndFunc
Func InfoHeaderMenu()
ShowPopupMenu /D /F "InfoHeaderCreateMenu"
EndFunc
Func InfoHeaderCreateMenu()
Local txt
txt &= 'MENUITEM "Включить", em_aucmd "%COMMANDER_EXE%,37" InfoHeaderStart' & auCRLF
txt &= 'MENUITEM "Выключить", em_aucmd "%COMMANDER_EXE%,36" InfoHeaderStop' & auCRLF
txt &= 'MENUITEM "Обновить погоду", em_aucmd "shell32.dll,13" InfoHeaderUpdate' & auCRLF
txt &= 'MENUITEM SEPARATOR' & auCRLF
txt &= 'MENUITEM "Настройки...", em_aucmd -1 InfoHeaderEditIni' & auCRLF
txt &= 'MENUITEM "Пользователь...", em_aucmd -1 InfoHeaderEditIniApp' & auCRLF
txt &= 'MENUITEM "Даты и время", em_aucmd "timedate.cpl,0" ShellExec rundll32.exe "shell32.dll,Control_RunDLL timedate.cpl"' & auCRLF
txt &= 'MENUITEM SEPARATOR' & auCRLF
txt &= 'MENUITEM "Перейти к Wttr.ini", em_aucmd "WCMICONS.DLL,19" InfoHeaderGotoIniApp' & auCRLF
txt &= 'MENUITEM "Перейти к Wttr.txt", em_aucmd -1 InfoHeaderGotoTemp "Wttr.txt"' & auCRLF
txt &= 'MENUITEM "Перейти к Wttr.html", em_aucmd -1 InfoHeaderGotoTemp "Wttr.html"' & auCRLF
txt &= 'MENUITEM SEPARATOR' & auCRLF
txt &= 'MENUITEM "Перейти к Header.ini", em_aucmd "WCMICONS.DLL,19" InfoHeaderGotoIni' & auCRLF
Return txt
EndFunc
Func InfoHeaderStart()
# запись значения в Header.ini
IniWrite %gWttrIni% "Title" "ShowTitle" 1
Sleep(100)
LaunchInfoHeader()
EndFunc
Func InfoHeaderStop()
IniWrite %gWttrIni% "Title" "ShowTitle" 0
Sleep(100)
LaunchInfoHeader()
EndFunc
Func InfoHeaderUpdate()
# обновление через 1 сек.
gWttrSec = gWttrInterval - 1
EndFunc
Func InfoHeaderEditIni()
If FileExist(gWttrIni) Then
ShellExec(gWttrIni)
Else
MsgBox("Файл не существует " & gWttrIni, "Autorun", 16)
EndIf
EndFunc
Func InfoHeaderGotoIni()
CommandExec("~/CD:S", gWttrIni)
EndFunc
Func InfoHeaderEditIniApp()
If FileExist(gWttrIniApp) Then
ShellExec(gWttrIniApp)
Else
MsgBox("Файл не существует " & gWttrIniApp, "Autorun", 16)
EndIf
EndFunc
Func InfoHeaderGotoIniApp()
CommandExec("~/CD:S", gWttrIniApp)
EndFunc
Func InfoHeaderGotoTemp(Filename)
Local sFile = TEMP & "\" & Filename
If FileExist(sFile) Then
CommandExec("~/CD:S", sFile)
Else
MsgBox("Файл не существует " & sFile, "Autorun", 16)
EndIf
EndFunc
Func GetNetSpeed(ByRef nRecvSpeed, ByRef nSendSpeed)
Static nIntfIdx = GetNetInterface()
If nIntfIdx = -1 Then Return
Static nPrevRecv = GetNetInterfaceInfo(nIntfIdx, 'Recv')
Static nPrevSend = GetNetInterfaceInfo(nIntfIdx, 'Sent')
Static nPrevTime = GetUptime()
Local nRecv = GetNetInterfaceInfo(nIntfIdx, 'Recv')
Local nSend = GetNetInterfaceInfo(nIntfIdx, 'Sent')
Local nTime = GetUptime()
Local nTimeDiff = nTime - nPrevTime
nRecvSpeed = Round(Abs(nRecv - nPrevRecv) / nTimeDiff)
nSendSpeed = Round(Abs(nSend - nPrevSend) / nTimeDiff)
nPrevRecv = nRecv
nPrevSend = nSend
nPrevTime = nTime
EndFunc |
Нужны только еще две дополнительные функции, которые можно найти 1-2 страницы назад, но я лучше их еще раз приложу.
 Hidden text | Code: | Func WinInetDownloadFile(URL, FileName, Silent = 0, Style = 0)
Static GENERIC_WRITE = 0x40000000, _
CREATE_ALWAYS = 2, FILE_ATTRIBUTE_NORMAL = 128
Static INTERNET_OPEN_TYPE_PRECONFIG = 0, _
INTERNET_FLAG_RELOAD = 0x80000000, _
INTERNET_FLAG_NO_CACHE_WRITE = 0x04000000
# Static INVALID_HANDLE_VALUE = auX64 ? 0xFFFFFFFFFFFFFFFF : 0xFFFFFFFF
Static INVALID_HANDLE_VALUE = auX64 ? 18446744073709551615 : 4294967295
Local hInt, hUrl, nSysErr, sAgent = "Autorun Downloader"
If Not Silent Then
tip("Internet connection.", 1, "Download", Style)
Sleep(200)
EndIf
hInt = DllCall("Wininet.dll\InternetOpenW", _
"wstr", sAgent, "dword", INTERNET_OPEN_TYPE_PRECONFIG, _
"ptr", 0, "ptr", 0, "ptr", 0, "handle")
nSysErr = SYSERROR
If Not (hInt > 0) Then
If Not Silent Then
tip("Error: " & nSysErr & auCRLF & _
"Message: " & GetWinInetError(nSysErr) & auCRLF & URL, 3, "Download", Style)
EndIf
Return nSysErr
EndIf
hUrl = DllCall("Wininet.dll\InternetOpenUrlW", _
"handle", hInt, "wstr", URL, "ptr", 0, _
"dword", 0, "dword", INTERNET_FLAG_RELOAD, _
"dword_ptr", 0, "handle")
nSysErr = SYSERROR
If Not (hUrl > 0) Then
DllCall("Wininet.dll\InternetCloseHandle", "handle", hInt)
If Not Silent Then
tip("Error: " & nSysErr & auCRLF & _
"Message: " & GetWinInetError(nSysErr) & auCRLF & URL, 3, "Download", Style)
EndIf
Return nSysErr
EndIf
# HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER
Local flags = BitOR(5, 0x20000000)
Local size, sz = 8
Local buf = Buffer(sz)
buf.Zero()
If DllCall("Wininet.dll\HttpQueryInfoW", _
"handle", hUrl, "dword", flags, "ptr", buf.ptr, "dword*", @sz, "ptr", 0) Then
size = buf.GetNum(0, "int64")
EndIf
Free(buf)
hFile = DllCall("CreateFileW", _
"wstr", FileName, "dword", GENERIC_WRITE, _
"dword", 0, "ptr", 0, "dword", CREATE_ALWAYS, _
"dword", FILE_ATTRIBUTE_NORMAL, "ptr", 0, "handle")
nSysErr = SYSERROR
If hFile <= 0 Or hFile = INVALID_HANDLE_VALUE Then
DllCall("Wininet.dll\InternetCloseHandle", "handle", hUrl)
DllCall("Wininet.dll\InternetCloseHandle", "handle", hInt)
If Not Silent Then
tip("File can't be created. Error: " & nSysErr & auCRLF & _
GetWinInetError(nSysErr) & auCRLF & FileName, 3, "Download", Style)
EndIf
Return nSysErr
EndIf
Local buf = Buffer(1024*2), bytes, written, total, prc
buf.Zero()
Local T1 = GetUptime(), T2 = T1, T3, nStyle = BitOR(Style, 1)
Do
bRes = DllCall("Wininet.dll\InternetReadFile", _
"handle", hUrl, "ptr", buf.ptr, "dword", buf.size, "dword*", @bytes)
If bRes And bytes > 0 Then
DllCall("WriteFile", "handle", hFile, _
"ptr", buf.ptr, "dword", bytes, "dword*", @written, "ptr", 0)
total += bytes
If Not Silent And size > buf.size Then
T3 = GetUptime()
If Round(T3 - T2, 0) > 500 Then
prc = "Download " & Round(total/size*100,0) & '%'
tip('Загружено: ' & SizeFormat(total, 1, 'M', 2) & ' ' & _
'из ' & SizeFormat(size, 1, 'M', 2), 1, prc, nStyle)
Sleep(10)
T2 = T3
EndIf
EndIf
EndIf
If IsPressed(0x1B) Then bRes = false
Until Not (bRes And bytes > 0)
DllCall("CloseHandle", "handle", hFile)
DllCall("Wininet.dll\InternetCloseHandle", "handle", hUrl)
DllCall("Wininet.dll\InternetCloseHandle", "handle", hInt)
T3 = Round(GetUptime() - T1, 0) / 1000
T3 = "Время операции: " & StrFormat("%.3f", T3) & " sec"
If Not Silent Then
If bRes Then
txt = "Download successful." & auCRLF & FileName & auCRLF & T3
tip(txt, 1, "Download", nStyle)
Else
txt = "Download failed or ended with an error." & auCRLF & T3
tip(txt, 3, "Download", nStyle)
EndIf
EndIf
Return (bRes ? 0 : -1)
EndFunc
Func GetWinInetError(nCode)
Local sMsg
Local hModule = DllCall("GetModuleHandleW", "Wstr", "wininet.dll", "handle")
If Not (hModule > 0) Then
Return "GetModuleHandle failed for wininet.dll. Error: " & SYSERROR
EndIf
Local FORMAT_MESSAGE_FROM_HMODULE = 0x00000800
Local FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100
Local FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200
Local FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
Local flags = BitOR(FORMAT_MESSAGE_FROM_HMODULE, _
FORMAT_MESSAGE_IGNORE_INSERTS, _
FORMAT_MESSAGE_FROM_SYSTEM)
Local buf = Buffer(1024)
buf.Zero()
If DllCall("FormatMessageW", "dword", flags, "ptr", hModule, _
"dword", nCode, "dword", 0, "ptr", buf.ptr, "dword", buf.size, "ptr", 0) Then
sMsg = StrTrim(buf.GetStr())
Else
sMsg = "Failed to find error description"
EndIf
Free(buf)
Return sMsg
EndFunc
Global gTipText, gTipX, gTipY, gTipMenuItems
Global gTipWndProc, gTipWP = Callback("tipwp", "hwnd;uint;wparam;lparam")
#{
nFlags:
1 - Previous window position
2 - Square tooltip window
4 - Inactive tooltip window
0 - Default
#}
Func tip(sText, nIcon = 0, sTitle = "Tip", nFlags = 0, sMenuItems = "")
Static TTM_TRACKACTIVATE = 1041, _
TTM_TRACKPOSITION = 1042, _
TTM_SETMAXTIPWIDTH = 1048, _
TTM_SETTITLE = 1057, _
TTM_ADDTOOL = 1074, _
TTM_UPDATETIPTEXT = 1081
Static txt = Buffer(1024*2)
Static hTip = 0, buf = Buffer(auX64 ? 56 : 40)
Local nMaxWidth = 200
If hTip = 0 Then
# TTS_BALLOON | TTS_CLOSE | TTS_NOPREFIX
hTip = DllCall("CreateWindowExW", _
"dword", 8, _
"wstr", "tooltips_class32", _
"wstr", "", "dword", 0x00000c2, _
"int", 0, "int", 0, "int", 0, "int", 0, _
"handle", 0, _
"handle", 0, "handle", 0, "ptr", 0, "handle")
If hTip = 0 Then
MsgBox("Не удалось создать окно подсказки")
Return 0
EndIf
gTipWndProc = DllCall("SetWindowLong" & (auX64 ? "PtrW" : "W"), _
"hwnd", hTip, "int", -4, "long_ptr", gTipWP.Ptr, "ptr")
txt.Zero()
txt.SetStr(sTitle & Chr(0))
SendMessage(hTip, TTM_SETTITLE, nIcon, txt.ptr)
buf.Zero()
# TTF_TRACK | TTF_ABSOLUTE | TTF_PARSELINKS
buf.SetNum(0, "uint", buf.size, "uint", 0x10a0, "hwnd", hTip)
buf.SetNum(auX64 ? 48 : 36, "ptr", txt.ptr)
SendMessage(hTip, TTM_ADDTOOL, 0, buf.ptr)
SendMessage(hTip, TTM_SETMAXTIPWIDTH, 0, nMaxWidth)
EndIf
If sText = "" Then
SendMessage(hTip, TTM_TRACKACTIVATE, 0, buf.ptr)
Return hTip
EndIf
# additional menu items
gTipMenuItems = sMenuItems
# cartoon or square
Local op = (BitAND(nFlags, 2) ? 4 : 2)
WinSetStyle(0x0000040, op, hTip)
txt.Zero()
txt.SetStr(sTitle & Chr(0))
SendMessage(hTip, TTM_SETTITLE, nIcon, txt.ptr)
txt.Zero()
txt.SetStr(sText & Chr(0))
# the next call won't fail if the tip is not visible
If WinGetState(2, hTip) = 0 Then
SendMessage(hTip, TTM_TRACKACTIVATE, 0, buf.ptr)
EndIf
SendMessage(hTip, TTM_UPDATETIPTEXT, 0, buf.ptr)
SendMessage(hTip, TTM_TRACKACTIVATE, 1, buf.ptr)
WinGetPos("x", "y", "w", "h", hTip)
# the tip will appear at the mouse pointer by default
If Not BitAND(nFlags, 1) Then MouseGetPos("x","y")
# preventing the tip from going off screen
If x + w > SYSINFO_DESKTOPWIDTH Then x = SYSINFO_DESKTOPWIDTH - w
If y + h > SYSINFO_DESKTOPHEIGHT Then y = SYSINFO_DESKTOPHEIGHT - h
SendMessage(hTip, TTM_TRACKPOSITION, 0, MakeInt(x, y, 0))
gTipX = x
gTipY = y
If Not BitAND(nFlags, 4) Then WinSetState(23, hTip)
Return hTip
EndFunc
Func tipwp(hWnd, uMsg, wParam, lParam)
Static MK_LBUTTON = 0x0001, TTM_TRACKPOSITION = 1042
Static DragWidth = GetSystemMetrics(68) #SM_CXDRAG
Static DragHeight = GetSystemMetrics(69) #SM_CYDRAG
Static IsDrag = 0, StartX = 0, StartY = 0
Local x, y
Static tx, ty, buf = Buffer(8)
#OutputDebugString("uMsg " & uMsg)
Switch uMsg
Case 0x004E # WM_NOTIFY
Static tag = 16 + _
48*2 + _
(2048 + 32 + 3)*2
hdr = Buffer(tag + (auX64 ? 24 : 12), lParam)
code = hdr.GetNum(auX64 ? 16 : 8, "uint")
If code = 0xFFFFFDF5 Then
link = hdr.GetStr(auX64 ? 136 : 124)
If StrPos(link, "://") Then
# MsgBox("Open the link?" & auCRLF & auCRLF & link, "Autorun", 3+32+0+262144)
# If EXTENDED <> 6 Then Return
ShellExec(link)
Else
Eval(link)
EndIf
EndIf
Case 0x0018 # WM_SHOWWINDOW
If wParam = 0 Then gTipMenuItems = ""
Case 0x0201 # WM_LBUTTONDOWN
If IsDrag = 0 Then
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)
tx = buf.GetNum(0)
ty = buf.GetNum(4)
IsDrag = 1
DllCall("SetCapture", "hwnd", hWnd, "hwnd")
EndIf
Case 0x0202 # WM_LBUTTONUP
If IsDrag = 1 Then
WinGetPos("gTipX", "gTipY", "", "", hWnd)
IsDrag = 0
DllCall("ReleaseCapture")
EndIf
Case 0x0200 # WM_MOUSEMOVE
If IsDrag = 1 And BitAND(wParam, MK_LBUTTON) Then
x = BitAND(lParam, 0xFFFF)
y = BitAND(BitShift(lParam,16), 0xFFFF)
If Abs(x - startX) > DragWidth Or Abs(y - startY) > DragHeight Then
buf.Zero()
buf.SetNum(0, "int", x, "int", y)
DllCall("ClientToScreen", "hwnd", hWnd, "ptr", buf.ptr)
x = buf.GetNum(0)
y = buf.GetNum(4)
SendMessage(hWnd, TTM_TRACKPOSITION, 0, MakeInt(gTipX+(x-tx), gTipY+(y-ty), 0))
EndIf
EndIf
Case 0x0205 # WM_RBUTTONUP
gTipText = WinGetText(hWnd)
ShowPopupMenu /D /F /I:0 "tipmnu"
Case 0x0100 # WM_KEYDOWN
If wParam = 0x1B Then WinSetState(0, hWnd)
EndSwitch
Return DllCall("CallWindowProcW", _
"ptr", gTipWndProc, "hwnd", hWnd, "uint", uMsg, "wparam", wParam, "lparam", lParam)
EndFunc
Func tipmnu()
Local txt
txt &= 'MENUITEM "Copy text", em_aucmd ' & (gTipText <> "" ? "" : "/D") & ' -1 tipcopy' & auCRLF
If gTipMenuItems <> "" Then
txt &= 'MENUITEM SEPARATOR' & auCRLF
txt &= gTipMenuItems
EndIf
Return txt
EndFunc
Func tipcopy()
#ClipPut %"gTipText"
ClipPut(gTipText)
EndFunc |
P.S.
Заголовок мне понравился, очень понравился. Даже завидую тем, кто первый раз его подключит ) |
|
| Back to top |
|
 |
FallenAngel
Joined: 30 Dec 2025 Posts: 7
|
(Separately) Posted: Wed Jan 07, 2026 11:59 Post subject: |
|
|
Orion9
Работает. Но я не разобрался как менять город.
Я думал, что достаточно в Wttr.ini (или Header.ini при отсутствии) указать свой город в Name=
...но ничего не поменялось.
Так же, Name должен отображаться и в заголовке. Вообще по выбору города - нужно упростить, сделать более юзер френдли. К примеру, в ПКМ меню добавить простую форму ввода города.
UPD. Поигрался с Url - но тоже безрезультатно.
Вообще в InfoHeader.aucfg сильно не хватает "шапки". Нужно написать версия, автор и т.д.
"Данный файл нужно подключать к плагину Autorun.wdx след. способом...
Настройка:
п1.
п2.
п3.
...
Обратная связь: ссылка на форум, почту, гитхаб
" |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 979
|
(Separately) Posted: Thu Jan 08, 2026 00:31 Post subject: |
|
|
| FallenAngel wrote: | | Работает. |
Это главное.
А подсказка с прогнозом на три дня у вас тоже работает? Cервер хорошо откликается?
| FallenAngel wrote: | | Но я не разобрался как менять город. |
В принципе город и координаты можно не указывать. Сервис попытается установить местоположение по ip, если в запросе не будет этих данных, например:
https://wttr.in/?T
https://wttr.in/?format=%l:+%C+%t
Первую ссылку можно добавить в "Hint" в качестве подсказки, а вторую использовать для однострочного вывода в заголовок.
Предполагается, что пользователь сам создаст и сохранит ссылку, которая ему нужна (температура, давление, влажность, ветер и т.д.) в Header.ini или Wttr.ini. Ключ "Name" нужен для вывода произвольного текста в заголовок, к примеру, если вы хотите вывести в заголовок не имя города, а что-то другое, типа "Погода:". Если ключ пуст, дополнительный текст не появится.
| FallenAngel wrote: | | Вообще по выбору города - нужно упростить, сделать более юзер френдли. К примеру, в ПКМ меню добавить простую форму ввода города. |
Это не реалистично сделать на Autorun. Даже при помощи специального объекта, упрощающего работу с GUI (если таковой бы имелся) и наличия базы данных городов (если таковая имелась бы), пришлось бы изрядно отвлечься на работу с этой базой, что далеко выходило бы за рамки простого скрипта. Да и зачем оно? Ведь город можно явно указать в запросе, или использовать более точные координаты для определения местоположения.
| FallenAngel wrote: | | Вообще в InfoHeader.aucfg сильно не хватает "шапки" |
Если скрипт пройдет проверку временем, можно будет над этим подумать. Да, нужно добавить туда хотя бы версию Autorun, которая требуется для его работы, с этим я согласен. |
|
| 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
|