| View previous topic :: View next topic |
| Author |
Message |
FallenAngel
Joined: 30 Dec 2025 Posts: 17
|
(Separately) Posted: Fri Feb 06, 2026 13:12 Post subject: |
|
|
Orion9
TCFS2, точно, спасибо.
Про CompareTool расскажу что хочу. Решение пока не могу придумать. Идея, условно:
if exist WinMergeU.exe then (выполняем как обычно CompareTool=WinMergeU.exe) else (предлагаем скачать перекинув на условный BAT-ник). |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 1002
|
(Separately) Posted: Fri Feb 06, 2026 19:13 Post subject: |
|
|
FallenAngel
А что тут думать? Нужно брать и делать, как вы написали )
Сначала считать ключ CompareTool и проверить путь в его значении: если путь существует, то выполнить cm_CompareFilesByContent, если не существует, то вывести MsgBox с вопросом, нужно ли скачивать WinMerge.
Опционально можно добавить возможность сравнения внутренним инструментом, если пользователь откажется от скачивания.
Небольшой пример:
| Code: | RegisterCommand 60050 "CompareTwoFiles"
Func CompareTwoFiles()
Local sTool
# чтение ключа
sTool = IniRead("~/R", COMMANDER_INI, "Configuration", "CompareTool", 0)
# раскрытие переменных окружения в значении ключа, если они есть
sTool = Set(sTool)
# проверка существования файла
If FileExist(sTool) Then
# файл существует
# послать команду сравнения и выйти
SendCommand(2022) # cm_CompareFilesByContent
Return
EndIf
# файл не существует
MsgBox("Инструмент сравнения не найден " & sTool & auCRLF & auCRLF & _
"Загрузить из Интернета?", "Autorun", 3+0+48)
# кнопка "Да" не была нажата, выйти из скрипта
If EXTENDED <> 6 Then Return
# запуск батника для загрузки
ShellExec(COMMANDER_PATH & "\Scripts\WinMergedownload.bat")
EndFunc |
Как у вас со скриптингом, можете дальше развить этот пример, а то я через неделю только освобожусь.
Кстати, вместо батника можно использовать функцию WinInetDownloadFile для загрузки файла прямо из Autorun
| Code: | Local url = "https://downloads.sourceforge.net/winmerge/winmerge-2.16.54-x64-exe.zip"
WinInetDownloadFile(url, TEMP & "\winmerge.zip") |
WinMerge загрузится во временный каталог в архиве winmerge.zip. Останется распаковать этот архив в нужное место и сообщить пользователю об окончании операции. |
|
| Back to top |
|
 |
FallenAngel
Joined: 30 Dec 2025 Posts: 17
|
(Separately) Posted: Sun Feb 08, 2026 11:03 Post subject: |
|
|
Orion9
Спасибо, работает отлично. Единственное, т.к. сейчас Нет и Отмена делают одно и тоже, то лучше чтобы Нет открывал внутренний инструмент.
| Orion9 wrote: |
Как у вас со скриптингом |
На bat\ps1 я неплохо пишу. Это не проблема.
| Orion9 wrote: |
Что касается Листера, если задача стоит добиться, чтобы его окно при открытии имело тот же размер и положение |
Может тогда лучше упростить? Просто повесить хоткей: нажал - и листер стал размером с окно ТС.
| Quote: | | Добавил переменную gTitleRound для указания количества знаков после точки у сетевого трафика. |
Может тогда и InfoHeader.aucfg обновите с учетом этой новинки? |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 1002
|
(Separately) Posted: Sun Feb 08, 2026 14:09 Post subject: |
|
|
FallenAngel
Если у вас со скриптами PowerShell получается работать, то уверен, что и с Autorun получится. Вопрос времени.
Чтобы добавить действие на кнопку "Нет", нужно обработать код с номером 7 в макросе EXTENDED. Из справки Autorun на функцию MsgBox:
| Code: | После закрытия диалога сообщения функция присвоит макросу EXTENDED числовой код, идентифицирующий нажатую кнопку:
1 «OK»
2 «Отмена»
3 «Прервать»
4 «Повтор»
5 «Пропустить»
6 «Да»
7 «Нет»
10 «Повторить»
11 «Продолжить»
Возможные сценарии при нажатии клавиши ESC:
Если есть кнопка «Отмена», функция присвоит 2 макросу EXTENDED.
Если нет кнопок «Отмена» и «OK», никакого эффекта не будет.
Если нет кнопки «Отмена», но есть «OK», функция присвоит 1 макросу EXTENDED.
Функция не всегда работает на 64-битной версии Total Commander. |
Т.е. нужно добавить:
| Code: | # кнопка "Нет"
If EXTENDED = 7 Then SendCommand(2040) #cm_IntCompareFilesByContent
# кнопка "Да" не была нажата, выйти из скрипта
If EXTENDED <> 6 Then Return |
Кстати, для этой задачи хорошо может подойти MsgBoxLinks, вместо стандартного MsgBox. Но там код чуть сложнее, пока не могу его написать и протестировать. Позднее попробую.
| Quote: | | Может тогда лучше упростить? Просто повесить хоткей: нажал - и листер стал размером с окно ТС. |
Можно так сделать. Нужно зарегистрировать отдельный код на функцию SyncListerPosition и создать для него em_команду или сразу повесить функцию на хоткей.
| Code: | RegisterCommand 60051 "SyncListerPosition"
# Alt + "["
SetHotkeyAction /K:A /V:219 SyncListerPosition
Func SyncListerPosition()
Static c = 0
If IniRead("~/R", COMMANDER_INI, "Lister", "Maximized", 0) = 0 Then
WinGetPos("x", "y", "w", "h")
IniWrite("~/R", COMMANDER_INI, "Lister", "x", x)
IniWrite("~/R", COMMANDER_INI, "Lister", "y", y)
IniWrite("~/R", COMMANDER_INI, "Lister", "dx", w)
IniWrite("~/R", COMMANDER_INI, "Lister", "dy", h)
c += 4
#ShowHint("Запись ключей: " & c, SYSINFO_DESKTOPWIDTH/2-50, SYSINFO_DESKTOPHEIGHT/2, 1000, 1)
EndIf
EndFunc
|
Посмотрите в справочнике SetHotkeyAction.
| Quote: | | Может тогда и InfoHeader.aucfg обновите с учетом этой новинки? |
Так он уже обновлен в последней версии на предыдущей странице, пропустили?  |
|
| Back to top |
|
 |
FallenAngel
Joined: 30 Dec 2025 Posts: 17
|
(Separately) Posted: Sun Feb 08, 2026 20:32 Post subject: |
|
|
Наверное, нужно обнулять, т.к. сейчас КАЖДЫЙ раз +4
| Orion9 wrote: | Так он уже обновлен в последней версии на предыдущей странице, пропустили?  |
Там он вместе с погодой (ну или я не туда смотрю). Речь про оригинал по моей ссылке в 68 строк. |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 1002
|
(Separately) Posted: Mon Feb 09, 2026 00:33 Post subject: |
|
|
FallenAngel
c += 4 не обнуляется, потому что цель была увидеть общее количество записей в ини-файл. Подключите последний модуль, захватите окно за заголовок и поводите им по экрану — количество записей быстро перевалит за сотни. Я боялся, что будет еще больше. Хотя в принципе все это не страшно.
| Quote: | | Там он вместе с погодой (ну или я не туда смотрю). |
Так вы и хотели вроде с погодой, даже ссылку давали на github Но если хотите совсем уж легковесный заголовок, то переменную для окруления десятичных можно и не вводить. Сразу лучше в строку вывода внести изменения:
| Code: | gInfoHeader = gTitle & ' ' & Date("d MMMM, ddd") & '. CPU: ' & StrFormat("%02d", GetCPUUsage()) & '% RAM: ' & GetMemStats() & '% NET: ↓ ' & Round(nRecvSpeed / 1000, 2) & ' ↑ ' & Round(nSendSpeed / 1000, 2) & ' mb/s' |
Т.е. вместо 1 теперь 2. Так реально лучше смотрится, на мой взгляд. |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 1002
|
(Separately) Posted: Mon Feb 09, 2026 12:17 Post subject: |
|
|
FallenAngel
Вчера спешил, не подумал, что окно листера надо искать. Должно быть примерно так:
| Code: | SetHotkeyAction /K:C /H:0 /DM /S "AlignListerWindow"
Func AlignListerWindow()
If IniRead("~/R", COMMANDER_INI, "Lister", "Maximized", 0) = 0 Then
WinGetPos("x", "y", "w", "h")
IniWrite("~/R", COMMANDER_INI, "Lister", "x", x)
IniWrite("~/R", COMMANDER_INI, "Lister", "y", y)
IniWrite("~/R", COMMANDER_INI, "Lister", "dx", w)
IniWrite("~/R", COMMANDER_INI, "Lister", "dy", h)
Local hWnd = WinFind(0, "TLister")
If hWnd = 0 Then Return ShowHint("Окно листера не найдено")
WinSetPos(x, y, w, h, "", hWnd)
EndIf
EndFunc |
CTRL+0 подстраивает окно листера под позицию окна тотала при условии, что окно листера не развернуто во весь экран. Так вы хотели? |
|
| Back to top |
|
 |
FallenAngel
Joined: 30 Dec 2025 Posts: 17
|
(Separately) Posted: Mon Feb 09, 2026 12:31 Post subject: |
|
|
| Orion9 wrote: |
Т.е. вместо 1 теперь 2. Так реально лучше смотрится, на мой взгляд. |
Хм... не уверен что лучше. Нужно подумать. Но вот навеяло другую идея походу: почему "в спокойствии" у нас "0" ? По идеи должно быть "0.0".
| Orion9 wrote: |
If hWnd = 0 Then Return ShowHint("Окно листера не найдено")
|
Это строка тут лишняя, ИМХО.
Да, круто что окно Листера теперь сразу подстраивается, единственное, теряет фокус (возможно, нужно просто передать его обратно). |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 1002
|
(Separately) Posted: Mon Feb 09, 2026 13:27 Post subject: |
|
|
FallenAngel
Нужно просто отформатировать строку через StrFormat. Т.е. вместо:
| Code: | Round(nRecvSpeed / 1000, 2) & ' ↑ ' & Round(nSendSpeed / 1000, 2) & ' mb/s' |
Должно быть:
| Code: | StrFormat("%02.2f", Round(nRecvSpeed / 1000, 2)) & ' ↑ ' & StrFormat("%02.2f", Round(nSendSpeed / 1000, 2)) & ' mb/s' |
Может вам так больше понравится.
| Quote: | | Это строка тут лишняя, ИМХО. |
Ну если лишняя, можно убрать )
А что на счет фокуса? У меня он не теряется. Но если у вас теряется, можно принудительно его вернуть через WinSetState:
| Code: | WinSetPos(x, y, w, h, "", hWnd)
WinSetState(23, hWnd) |
А вот и линксы, как обещал:
 Hidden text | Code: | RegisterCommand 60043 "CompareTwoFiles"
RegisterCommand 60044 "CompareTwoFilesDialog"
Func CompareTwoFiles()
Local sTool, nDialogMode = 1
# чтение ключа
sTool = IniRead("~/R", COMMANDER_INI, "Configuration", "CompareTool", "")
# раскрытие переменных окружения
sTool = Set(sTool)
# проверка существования файла
If FileExist(sTool) Then
# файл существует
# послать команду сравнения и выйти
SendCommand(2022) # cm_CompareFilesByContent
Return
EndIf
If nDialogMode = 1 Then Return CompareTwoFilesDialog(sTool)
# файл не существует
MsgBox("Инструмент сравнения не найден " & sTool & auCRLF & auCRLF & _
"Загрузить из Интернета?", "Autorun", 3+0+48)
# нажата кнопка "Нет"
If EXTENDED = 7 Then SendCommand(2040) # cm_IntCompareFilesByContent
# не нажата кнопка "Да", выйти из скрипта
If EXTENDED <> 6 Then Return
# запуск батника для загрузки
ShellExec(COMMANDER_PATH & "\Scripts\WinMergeDownload.bat")
EndFunc
Func CompareTwoFilesDialog(FilePath)
Local lst = List()
lst.Add("Сравнить внутренним" & auLF & "Будет использован внутренний инструмент сравнения Total Commander")
lst.Add("Загрузить из интернета" & auLF & "https://winmerge.org/downloads/?lang=ru")
Local nRet = MsgBoxLinks(1, "Инструмент сравнения не найден", FilePath, lst)
Free(lst)
If nRet = 2 Then Return
If nRet = 1001 Then
SendCommand(2040) # cm_IntCompareFilesByContent
Else
ShellExec(COMMANDER_PATH & "\Scripts\WinMergeDownload.bat")
EndIf
EndFunc
#{
Icon:
1 - Warning
2 - Error
3 - Information
4 - Shield
ByRef: List() of 1-3 elements
Returns: 1001-1003, 2 for cancel
#}
Func MsgBoxLinks(Icon, Header, Message, ByRef Links)
If Abs(Icon) > 4 Then Icon = 2
Icon = 65536 - Icon
If Links.Count = 0 Then Return MsgBox("Links not specified")
Local Res, Ret
Local buf = Buffer(auX64 ? 160 : 96), _
ttl = Buffer(16), _
hdr = Buffer(StrLen(Header)*2+2), _
msg = Buffer(StrLen(Message)*2+2), _
lnk = Buffer(auX64 ? 48 : 24)
ttl.SetStr("Autorun" & Chr(0))
hdr.SetStr(Header & Chr(0))
msg.SetStr(Message & Chr(0))
Local b1 = Buffer(512), b2 = Buffer(512), b3 = Buffer(512)
b1.Zero()
b2.Zero()
b3.Zero()
b1.SetStr(Links[0] & Chr(0))
If Links.Count > 1 Then b2.SetStr(Links[1] & Chr(0))
If Links.Count > 2 Then b3.SetStr(Links[2] & Chr(0))
lnk.Zero()
lnk.SetNum(0, "int", 1001, _
"ptr", b1.ptr, _
"int", 1002, _
"ptr", b2.ptr, _
"int", 1003, _
"ptr", b3.ptr)
buf.Zero()
buf.SetNum(0, "uint", buf.size, _
"hwnd", AUTORUN_TCHANDLE, _
"handle", 0, _
"dword", 0x0019, _
"dword", 0x0008, _
"ptr", ttl.ptr, _
"ptr", Icon, _
"ptr", hdr.ptr, _
"ptr", msg.ptr, _
"uint", Links.Count, _
"ptr", lnk.ptr)
Res = DllCall("TaskDialogIndirect", _
"ptr", buf.ptr, _
"int*", @Ret, _
"int*", 0, _
"bool*", 0, "hresult")
Free(buf, ttl, hdr, msg, lnk, b1, b2, b3)
Return Ret
EndFunc |
Ну не персик ли?
 PS Если персик не нужен, можно изменить nDialogMode = 1 на любое значение |
|
| Back to top |
|
 |
FallenAngel
Joined: 30 Dec 2025 Posts: 17
|
(Separately) Posted: Mon Feb 09, 2026 15:18 Post subject: |
|
|
| Orion9 wrote: |
Может вам так больше понравится. |
Пока так тестирую:
| Code: | StrFormat("%02.1f", Round(nRecvSpeed / 1000, 1)) & ' ↑ ' & StrFormat("%02.1f", Round(nSendSpeed / 1000, 1)) & ' mb/s' |
| Code: | WinSetState(23, hWnd) |
Да, так все ОК. |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 1002
|
(Separately) Posted: Tue Feb 10, 2026 13:54 Post subject: |
|
|
Прошелся тут по последним страницам. Удивительно, ссылки на 11,000 сохранилась, а ссылка на 13К не доступна. Непорядок творится в королевстве. Перезаливка.
https://www.upload.ee/files/19062762/TC.11.56.7z.html
 Warning Сайт находится в 16-20 Кб блоке. С территории России без средств обхода скачать архив не получится. Адрес площадки пока не меняю, вдруг блокировку еще снимут.
Обновил модуль Icons.aucfg.
 Hidden text | Code: | Pragma IncludeOnce
# 64000-65000
Global TrayShow = 0, TrayLog = List()
Global Tray1001 = 0, Tray1002 = 0, Tray1003 = 0, Tray1010 = 0
Global gNotifyIcon = COMMANDER_EXE
#Global gNotifyIcon = COMMANDER_PATH & "\Ini\Newsbar\notify-yes.ico"
# регистрация уникальных кодов
Global Code1003 = DllCall("RegisterWindowMessageW", "wstr", "TrayNotify1003", "uint")
Global Code1010 = DllCall("RegisterWindowMessageW", "wstr", "TrayNotify1010", "uint")
# коды кнопок
RegisterCommand 64000 "ToggleTrayIcon"
RegisterCommand 64001 "ChangeTrayIcon"
RegisterCommand 64002 "NotifyInfo"
RegisterCommand 64003 "RotateIcon"
# функции обратного вызова
SetMessageAction /P 99999 "AutorunTrayAction"
SetMessageAction /P %"Code1003" "MinTrayAction"
SetMessageAction /P %"Code1010" "TrayNotifyInfo"
# сворачивание в трей
ControlSetMouseAction /K:C /L /H:8 0 "MinimizeToTray"
# иконки окна уведомлений
Const NIIF_NONE = 0x00000000, _
NIIF_INFO = 0x00000001, _
NIIF_WARNING = 0x00000002, _
NIIF_ERROR = 0x00000003, _
NIIF_USER = 0x00000004
# без звука
Const NIIF_NOSOUND = 0x00000010
# большая иконка
Const NIIF_LARGE_ICON = 0x00000020
# сообщения окна уведомлений
Const NIN_BALLOONSHOW = 0x402, _
NIN_BALLOONHIDE = 0x403, _
NIN_BALLOONTIMEOUT = 0x404, _
NIN_BALLOONUSERCLICK = 0x405, _
NIN_POPUPOPEN = 0x406, _
NIN_POPUPCLOSE = 0x407
# флаги структуры
Const NIF_MESSAGE = 0x00000001, _
NIF_ICON = 0x00000002, _
NIF_TIP = 0x00000004, _
NIF_STATE = 0x00000008, _
NIF_INFO = 0x00000010
# системные сообщения
Const WM_MOUSEMOVE = 0x0200, _
WM_LBUTTONDOWN = 0x0201, _
WM_LBUTTONUP = 0x0202, _
WM_LBUTTONDBLCLK = 0x0203, _
WM_RBUTTONDOWN = 0x0204, _
WM_RBUTTONUP = 0x0205, _
WM_RBUTTONDBLCLK = 0x0206, _
WM_MBUTTONDOWN = 0x0207, _
WM_MBUTTONUP = 0x0208, _
WM_MBUTTONDBLCLK = 0x0209
# старт
TrayIcon()
# главная иконка
Func TrayIcon()
Local ico, idx = 0
# чтение конфигурации
IniRead TrayShow %AUTORUN_INI% "TrayIcon" "Show" 1
If Not TrayShow Then
Return
EndIf
IniRead ico %AUTORUN_INI% "TrayIcon" "Icon"
IniRead idx %AUTORUN_INI% "TrayIcon" "Index" 0
# раскрытие переменной окружения
ico = Set(ico)
# откат к умолчаниям
If ico = "" Or Not FileExist(ico) Then
idx = 0
ico = COMMANDER_EXE
EndIf
Local sHint = "Autorun " & FileGetVersion(AUTORUN_PATH & "\Autorun.wdx", "FileVersion")
If auX64 Then sHint &= " x64"
# дескриптор иконки
Local hIco = DllCall("shell32\ExtractIconW", _
"ptr", AUTORUN_TCHANDLE, _
"wstr", ico, "uint", idx, "ptr")
# установка в трей с идентификатором 1001
If NotifyIcon("add", 1001, 99999, hIco, sHint) Then Tray1001 = 1
If hIco > 0 Then DllCall("DestroyIcon", "ptr", hIco)
EndFunc
# главная иконка Autorun
# функция обратного вызова
Func AutorunTrayAction(hWnd, uMsg, wParam, lParam)
Local bCtrl = IsPressed(0x11)
Switch lParam
# движение над иконкой
Case WM_MOUSEMOVE
If LAST_HINT_WINDOW = 0 Then
If bCtrl Then ShowHint(GetState("threads"), "", "", 2000, 1)
EndIf
# левый клик
Case WM_LBUTTONDOWN
If bCtrl Then
ClipPut(GetState("threads"))
ShowHint(GetState("threads"))
#ShowDarkHint(GetState("threads"))
Return
EndIf
AutorunMenu(0)
# правый клик
Case WM_RBUTTONDOWN
If bCtrl Then
ShowDarkHint(GetState("libs"))
Else
ShowSetEnviroments()
EndIf
# клик по сообщению
Case NIN_BALLOONUSERCLICK
MsgBox("Baloon click")
#WinSetState(23)
# клик "закрыть сообщение"
Case NIN_BALLOONTIMEOUT
MsgBox("Time-out")
EndSwitch
EndFunc
# иконка уведомлений
Func TrayNotifyInfo(hWnd, uMsg, wParam, lParam)
Switch lParam
Case WM_LBUTTONDOWN
ShowPopupMenu /D /F "TrayNotifyInfoMenu"
Case WM_RBUTTONDOWN
#NotifyIcon("delete", 1010)
Case NIN_BALLOONUSERCLICK
Case NIN_BALLOONTIMEOUT
EndSwitch
EndFunc
# меню уведомлений
Func TrayNotifyInfoMenu()
Local txt, nIco, sIco, sTime, sInfo, sType, sFunc, i = 0, j = 0
For i = TrayLog.Count - 1 To 0 Step -1
nIco = -1
sIco = "-1"
sTime = StrPart(TrayLog[i], Chr(0), 1)
sInfo = StrPart(TrayLog[i], Chr(0), 2)
sType = StrPart(TrayLog[i], Chr(0), 4)
If BitAND(sType, 3) = 1 Then
nIco = 76
ElseIf BitAND(sType, 3) = 2 Then
nIco = 79
ElseIf BitAND(sType, 3) = 3 Then
nIco = 93
EndIf
If nIco <> -1 Then sIco = "imageres.dll," & nIco
sFunc = "TrayNotifyItem " & i & " " & nIco
txt &= 'MENUITEM "' & sTime & " " & sInfo & '", em_aucmd ' & sIco & " " & sFunc & auCRLF
j += 1
If j = 30 Then Break
Next
If TrayLog.Count = 0 Then txt &= 'MENUITEM "<Пусто>", em_aucmd' & auCRLF
txt &= 'MENUITEM SEPARATOR' & auCRLF
txt &= 'MENUITEM "Копировать", em_aucmd -1 TrayNotifyCopy' & auCRLF
txt &= 'MENUITEM "Скрыть иконку", em_aucmd -1 NotifyIcon "delete" 1010' & auCRLF
Return txt
EndFunc
Func TrayNotifyItem(nItem, nIco)
Local nFlag
Local sInfo = StrPart(TrayLog[nItem], Chr(0), 2)
Local sText = StrPart(TrayLog[nItem], Chr(0), 3)
Switch nIco
Case 76
nFlag = 64
Case 79
nFlag = 48
Case 93
nFlag = 16
Else
nFlag = ''
EndSwitch
MsgBox(sText, sInfo, nFlag)
EndFunc
Func TrayNotifyCopy()
Local txt = TrayLog.Text
txt = StrReplace(txt, Chr(0), ";")
ClipPut(txt)
ShowTransHint("Скопировано в буфер")
EndFunc
# переключение иконки
Func ToggleTrayIcon(lParam)
If Tray1001 > 0 Then
IniWrite %AUTORUN_INI% "TrayIcon" "Show" 0
If NotifyIcon("delete", 1001) Then Tray1001 = 0
Else
IniWrite %AUTORUN_INI% "TrayIcon" "Show" 1
TrayIcon()
EndIf
If Tray1001 > 0 Then
ShowTransHint("Иконка включена")
Else
ShowTransHint("Иконка отключена")
EndIf
EndFunc
# иконка свернутого окна
Func MinTrayAction(hWnd, uMsg, wParam, lParam)
If lParam = WM_LBUTTONDOWN Then
If NotifyIcon("delete", 1003) Then Tray1003 = 0
WinSetState(5)
WinSetState(23)
ElseIf lParam = WM_RBUTTONDOWN Then
EndIf
EndFunc
# сворачивание
Func MinimizeToTray()
Local sHint = "Click to restore Total Commander"
Local hIcon = SendMessage(AUTORUN_TCHANDLE, 0x7f, 2, 0)
If hIcon = 0 Then
MsgBox("Не удалось получить дескриптор иконки", "Autorun", 48)
Return
EndIf
If NotifyIcon("add", 1003, Code1003, hIcon, sHint) Then Tray1003 = 1
WinSetState(0)
EndFunc
# тестовая функция
Func ChangeTrayIcon(lParam)
Static sDLL = GetKnownFolderPath("System") & "\shell32.dll", i = 10
If Tray1001 = 0 Then
ShowHint("Иконка отключена")
Return
EndIf
i += 1
Local hIco
hIco = DllCall("shell32\ExtractIconW", _
"ptr", AUTORUN_TCHANDLE, _
"wstr", sDLL, "uint", i, "ptr")
If IsPressed(0x11) Then
If NotifyIcon("add", 1002, 99999, hIco, "Autorun #2", "Second icon added", "Autorun", NIIF_INFO) Then
Tray1002 = 1
EndIf
Else
If IsPressed(0x12) Then hIco = 0
NotifyIcon("set", 1001, 99999, hIco, "", "Icon changed to shell32.dll, " & i, "", NIIF_WARNING)
Sleep(2000)
NotifyIcon("set", 1001,, hIco,, "Icon changed to shell32.dll, " & i,, NIIF_ERROR)
EndIf
If hIco > 0 Then DllCall("DestroyIcon", "ptr", hIco, "bool")
EndFunc
# тест уведомлений
Func NotifyInfo(lParam)
Local bCtrl = IsPressed(0x11)
Static i = 0
i += 1
If i > 3 Then i = 1
If bCtrl Then i = 1
If i = 1 Then
NotifyInfoMessage("Test message", "Test 1", NIIF_INFO)
If Not bCtrl Then Return
Sleep(2000)
EndIf
If bCtrl Or i = 2 Then
txt = "Pragma Include %COMMANDER_PATH%\Ini\Scripts\Test.aucfg"
NotifyInfoMessage(txt, "Test 2", NIIF_WARNING + NIIF_NOSOUND)
If Not bCtrl Then Return
Sleep(2000)
EndIf
If bCtrl Or i = 3 Then
txt = "Test message line 1" & auCRLF & "Test message line 2"
NotifyInfoMessage(txt, "Test 3", NIIF_ERROR)
EndIf
EndFunc
# проверка существования иконки
# функция имеет проблемы на Win10
Func IsIconOnTray(uId)
Local rc = Buffer(16) # RECT
rc.Zero()
Local id = Buffer(auX64 ? 40 : 28)
id.Zero()
If auX64 Then
id.SetNum(0, "dword", id.size)
id.SetNum(8, "hwnd", AUTORUN_TCHANDLE)
id.SetNum(16, "uint", uId)
Else
id.SetNum(0, "dword", id.size, _
"hwnd", AUTORUN_TCHANDLE, _
"uint", uId)
EndIf
Local hr = DllCall("Shell32.dll\Shell_NotifyIconGetRect", "ptr", id.ptr, "ptr", rc.ptr)
Free(id, rc)
Return hr = 0 ? true : false
EndFunc
#{
Вызов системных уведомлений:
InfoText - текст уведомления (255 символов)
InfoTitle - текст заголовка уведомления (63 символов)
InfoType - флаги NIIF_* меняющие вид и поведение окна уведомлений
Функция использует идентификатор "1010"
#}
Func NotifyInfoMessage(InfoText, InfoTitle = "Autorun", InfoType = 0)
Local Offset = auX64 ? 40 : 24, sIcon
Static buf = Buffer(auPtrSize = 4 ? 956 : 976)
Static nFlags = BitOR(NIF_MESSAGE, NIF_ICON, NIF_INFO, NIF_TIP)
If FileExist(gNotifyIcon) Then
sIcon = gNotifyIcon
Else
sIcon = COMMANDER_EXE
EndIf
Static hIco = DllCall("shell32\ExtractIconW", _
"ptr", AUTORUN_TCHANDLE, _
"wstr", sIcon, "uint", 0, "ptr")
NotifyIcon("delete", 1010)
buf.Zero()
If auX64 Then
buf.SetNum(0, "dword", buf.size)
buf.SetNum(8, "hwnd", AUTORUN_TCHANDLE)
buf.SetNum(16, "uint", 1010, _
"uint", nFlags, _
"uint", Code1010)
buf.SetNum(32, "ptr", hIco)
buf.SetNum(296, "dword", 1, _
"dword", 1)
Else
buf.SetNum(0, "dword", buf.size, _
"hwnd", AUTORUN_TCHANDLE, _
"uint", 1010, _
"uint", nFlags, _
"uint", Code1010, _
"ptr", hIco)
buf.SetNum(280, "dword", 1, _
"dword", 1)
EndIf
buf.SetStr("Notify Messages" & Chr(0), Offset)
buf.SetStr(StrLeft(InfoText, 255) & Chr(0), Offset + 264) # 256 + 4 + 4
Offset += 264
If InfoTitle <> "" Then
buf.SetStr(StrLeft(InfoTitle, 63) & Chr(0), Offset + 516) # 512 + 4
EndIf
Offset += 516
If InfoType > 0 Then
buf.SetNum(Offset + 128, "dword", InfoType) # 128
EndIf
TrayLog.Add(Time() & Chr(0) & InfoTitle & Chr(0) & InfoText & Chr(0) & InfoType)
Tray1010 = 1
Return DllCall("Shell32.dll\Shell_NotifyIconW", "uint", 0, "ptr", buf.ptr)
EndFunc
#{
Добавление иконки в трей:
sAction - тип действия ("add", "set", "delete")
uID - внутренний уникальный идентификатор иконки
nCallback - код зарегистрированного сообщения для функции обратного вызова
hIcon - дескриптор иконки (только для "add")
sTip - текст подсказки в трее
sText - текст уведомления (только для "add" и "set")
sTitle - текст заголовка уведомления
nType - флаги NIIF_* (изменение вида и поведения окна уведомлений)
https://learn.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-notifyicondataw
#}
Func NotifyIcon(sAction, uID, nCallback = 0, hIcon = 0, sTip = "", sText = "", sTitle = "", nType = 0)
Local nAction, nFlags
Static TIP_MAXCHAR = 127, INFO_MAXCHAR = 255, TITLE_MAXCHAR = 63
Static buf = Buffer(auPtrSize = 4 ? 956 : 976)
buf.Zero()
nFlags = BitOR( hIcon = 0 ? 0 : NIF_ICON, _
nCallback = 0 ? 0 : NIF_MESSAGE, _
StrLen(sTip) = 0 ? 0 : NIF_TIP, _
StrLen(sText) = 0 ? 0 : NIF_INFO )
Switch sAction
Case "add"
nAction = 0
Case "set"
nAction = 1
Case "delete"
nAction = 2
Else
Return
EndSwitch
If auX64 Then
buf.SetNum(0, "dword", buf.size)
buf.SetNum(8, "hwnd", AUTORUN_TCHANDLE)
buf.SetNum(16, "uint", uID, _
"uint", nFlags, _
"uint", nCallback)
buf.SetNum(32, "ptr", hIcon)
Else
buf.SetNum(0, "dword", buf.size, _
"hwnd", AUTORUN_TCHANDLE, _
"uint", uID, _
"uint", nFlags, _
"uint", nCallback, _
"ptr", hIcon)
EndIf
Local nOffset = auX64 ? 40 : 24 # PtrSize*2 + 4*4 + padding for X64
If sTip <> 0 Then
buf.SetStr(StrLeft(sTip, TIP_MAXCHAR) & Chr(0), nOffset)
EndIf
If sText <> 0 Then
nOffset += 264
buf.SetStr(StrLeft(sText, INFO_MAXCHAR) & Chr(0), nOffset) # 256 + 4 + 4
If sTitle <> 0 Then
buf.SetStr(StrLeft(sTitle, TITLE_MAXCHAR) & Chr(0), nOffset + 516) # 512 + 4
EndIf
If nType > 0 Then
buf.SetNum(nOffset + 644, "dword", nType) # 128
EndIf
EndIf
Return DllCall("Shell32.dll\Shell_NotifyIconW", "uint", nAction, "ptr", buf.ptr, "bool")
EndFunc
Global ROTATE_THREAD = 0
Func RotateIcon()
If ROTATE_THREAD > 0 Then
ROTATE_THREAD = 0
Return
EndIf
RunThread("ThreadRotateIcon", IsPressed(0x11))
EndFunc
Func ThreadRotateIcon(FileIcons)
ROTATE_THREAD = 1
Local hIcon = SendMessage(AUTORUN_TCHANDLE, 0x7f, 2, 0)
While ROTATE_THREAD > 0
Sleep(150)
If FileIcons Then
IconRotateDraw()
Else
RotateDeviceContext()
EndIf
Wend
SendMessage(AUTORUN_TCHANDLE, 0x80, 0, hIcon)
WinRedraw(2)
EndFunc
Func IconRotateDraw()
Static nIco = 0
nIco += 1
If nIco > 4 Then nIco = 1
Local sFile = COMMANDER_PATH & "\Icons\TC\" & nIco & ".ico"
Local hIco = DllCall("shell32\ExtractIconW", _
"ptr", AUTORUN_TCHANDLE, _
"wstr", sFile, _
"uint", 0, _
"ptr")
Local hWnd = WinFind(AUTORUN_TCHANDLE, _
(AUTORUN_TCARCH = 32 ? "TMyPanel" : "Window"), _
(AUTORUN_TCARCH = 32 ? 6 : 10))
# Local hWnd = RequestInfo(15)
# hDC = DllCall("GetDC", "ptr", hWnd, "ptr")
Local hDC = DllCall("GetWindowDC", "ptr", hWnd, "ptr")
Local x, y, w, h
WinGetPos("x", "y", "w", "h", hWnd)
DllCall("DrawIconEx", _
"ptr", hDC, _
"int", w - 20, _
"int", 1, _
"ptr", hIco, _
"int", 16, _
"int", 16, _
"uint", 0, _
"ptr", 0, _
"uint", 0x0003)
SendMessage(AUTORUN_TCHANDLE, 0x80, 0, hIco)
SendMessage(AUTORUN_TCHANDLE, 0x80, 1, hIco)
DllCall("ReleaseDC", "ptr", AUTORUN_TCHANDLE, "ptr", hDC)
DllCall("DestroyIcon", "ptr", hIco)
EndFunc
Func RotateDeviceContext()
Static c = 0
c += 1
If c > 4 Then c = 1
Local x, y, w, h
Local hIco = SendMessage(AUTORUN_TCHANDLE, 0x7f, 2, 0)
Local hWnd = WinFind(AUTORUN_TCHANDLE, _
(AUTORUN_TCARCH = 32 ? "TMyPanel" : "Window"), _
(AUTORUN_TCARCH = 32 ? 6 : 10))
Local DC = DllCall("GetDC", "int", 0)
Local nDPI = DllCall("GetDeviceCaps", "handle", DC, "int", 88)
Local nScale = DllCall("MulDiv", "int", 100, "int", nDPI, "int", 96)
Local nSize = Round(16*nScale/100,0)
# Local hWnd = RequestInfo(15)
Local hdcWndDC = DllCall("GetWindowDC", "ptr", hWnd, "ptr")
Local hdcMemDC = DllCall("CreateCompatibleDC", "ptr", hdcWndDC, "ptr")
Local hdcBltDC = DllCall("CreateCompatibleDC", "ptr", hdcWndDC, "ptr")
Local hbmDB1 = DllCall("CreateCompatibleBitmap", "ptr", hdcWndDC, "int", nSize, "int", nSize,"ptr")
Local hbmDB2 = DllCall("CreateCompatibleBitmap", "ptr", hdcWndDC, "int", nSize, "int", nSize,"ptr")
DllCall("SelectObject", "ptr", hdcMemDC, "ptr", hbmDB1, "ptr")
DllCall("SelectObject", "ptr", hdcBltDC, "ptr", hbmDB2, "ptr")
DllCall("DrawIconEx", _
"ptr", hdcMemDC, _
"int", 1, _
"int", 1, _
"ptr", hIco, _
"int", nSize, _
"int", nSize, _
"uint", 0, _
"ptr", 0, _
"uint", 0x0003)
Local pt = Buffer(24)
pt.Zero()
If c = 1 Then
pt.SetNum(0, "int", nSize, "int", 0, _
"int", 0, "int", 0, _
"int", nSize, "int", nSize)
ElseIf c = 2 Then
pt.SetNum(0, "int", nSize, "int", nSize, _
"int", nSize, "int", 0, _
"int", 0, "int", nSize)
ElseIf c = 3 Then
pt.SetNum(0, "int", 0, "int", nSize, _
"int", nSize, "int", nSize, _
"int", 0, "int", 0)
ElseIf c = 4 Then
pt.SetNum(0, "int", 0, "int", 0, _
"int", 0, "int", nSize, _
"int", nSize, "int", 0)
EndIf
DllCall("PlgBlt", _
"ptr", hdcBltDC, _
"ptr", pt.Ptr, _
"ptr", hdcMemDC, _
"int", 0, _
"int", 0, _
"int", nSize, _
"int", nSize, _
"ptr", 0, _
"int", 0, "int", 0)
WinGetPos("x", "y", "w", "h", hWnd)
DllCall("BitBlt", _
"ptr", hdcWndDC, _
"int", w - 20, _
"int", 2, _
"int", nSize, _
"int", nSize, _
"ptr", hdcBltDC, _
"int", 1, _
"int", 1, _
"dword", 13369376)
DllCall("DeleteObject", "ptr", hbmDB1)
DllCall("DeleteObject", "ptr", hbmDB2)
DllCall("DeleteObject", "ptr", hdcMemDC)
DllCall("DeleteObject", "ptr", hdcBltDC)
DllCall("ReleaseDC", "ptr", AUTORUN_TCHANDLE, "ptr", hdcWndDC)
EndFunc |
В модуле есть две универсальные функции для показа системных уведомлений и создания иконок в трее: NotifyInfoMessage и NotifyIcon. Коды кнопок 64000-64002 тестирую функционал. Созданные идентификаторы иконок нужно добавить в секцию финализации, чтобы при выхода из ТС они не оставались висеть в трее.
 Pragma AutorunFinalizeSection | Code: | # удаление иконок
If Tray1001 > 0 Then NotifyIcon("delete", 1001)
If Tray1002 > 0 Then NotifyIcon("delete", 1002)
If Tray1003 > 0 Then NotifyIcon("delete", 1003)
If Tray1010 > 0 Then NotifyIcon("delete", 1010) |
Модуль можно накатить на тот, что в сборке, для удобного и быстрого теста. |
|
| Back to top |
|
 |
FallenAngel
Joined: 30 Dec 2025 Posts: 17
|
(Separately) Posted: Tue Feb 10, 2026 15:44 Post subject: |
|
|
| Orion9 wrote: | | Перезаливка. |
Почему просто не использовать приличный хостинг? terabox.com, mega.nz или pixeldrain.com ?
| Orion9 wrote: | | Обновил модуль Icons.aucfg. |
Добавляйте небольшое описание в самом начале файла, модуль возможно и интересный, но не ясно что он делает (как и остальные 13к строк).
Повторюсь, намного полезнее (понятнее, удобнее, логичнее, ...) было бы выкладывать просто модулями. Возможно и найдется самурай, который скачает сборку и осилит часть написанного... но это 1-2 юзера (с огромным запасом свободного времени) и не более. |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 1002
|
(Separately) Posted: Tue Feb 10, 2026 19:01 Post subject: |
|
|
| FallenAngel wrote: | | Возможно и найдется самурай, который скачает сборку и осилит часть написанного |
Cамурай звучит громо, скорее фрик, как я )
А я ведь предупреждал Loopback, что у нас с Autorun всё всьерёз и надолго, а он мне не верил ) Могу только повторить свой пледж и коммитмент:
 Hidden text Till death us do part, Auto 
| FallenAngel wrote: | | terabox.com, mega.nz или pixeldrain.com |
Первый всё в том же 16 Кб блоке, остальные, судя по всему, в белых списках, но требуют регистрацию, а оно мне вроде как не надо.
Сделать перманентную ссылку на том же гугл диске (или любом другом диске) не проблема. Но не раньше, чем Loopback сделает перманентную ссылку на финальную версию Autorun
А пока все это для тестов и эксперементов. Если кто-то может извлечь из этого пользу — без проблем. Буду только рад, что помимо меня кому-то ещё пригодилось.
| FallenAngel wrote: | | Добавляйте небольшое описание в самом начале файла, модуль возможно и интересный, но не ясно что он делает (как и остальные 13к строк). |
Ранний функционал довольно хорошо документирован, просто на последние модули я не нашел возможности сделать описание. Думал, сейчас у меня будет большое окно и смогу наверстать упущенное, но нет, судя по всему, опять не получится.
Но не все так плохо. В этом топике осталось практически всё, правда мотать придется чуть дальше.
Конкретно по этому модулю. Имхо, он неплохо документирован самими комментариями. Да, возможно, сейчас вам так не кажется, но со временем все прояснится, если вы не бросите заниматься Autorun.
Когда-то, глянув на этот модуль, я подумал, надо быть реально повернутым, чтобы полностью в нем разобраться. Однако сейчас я на него смотрю и он мне кажется довольно простым и понятным. Одна мальнькая ремарка: с тех пор прошло два года
Так что верно говорят, что путь осилит идущий, а нет кто с него сходит или топчется на месте)
P.s. Ссылка на модуль за CloudFlare, т.ч. приложу его сюда.
 Hidden text | Code: | ;https://www.autohotkey.com/boards/viewtopic.php?t=113308
;======================================================================================================================
; ToolTipOptions - additional options for ToolTips
;
; Tooltip control -> https://learn.microsoft.com/en-us/windows/win32/controls/tooltip-control-reference
; TTM_SETMARGIN = 1050
; TTM_SETTIPBKCOLOR = 1043
; TTM_SETTIPTEXTCOLOR = 1044
; TTM_SETTITLEW = 1057
; WM_SETFONT = 0x30
; SetClassLong() -> https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setclasslongw
; ======================================================================================================================
Class ToolTipOptions {
; -------------------------------------------------------------------------------------------------------------------
Static HTT := DllCall("User32.dll\CreateWindowEx", "UInt", 8, "Str", "tooltips_class32", "Ptr", 0, "UInt", 3
, "Int", 0, "Int", 0, "Int", 0, "Int", 0, "Ptr", A_ScriptHwnd, "Ptr", 0, "Ptr", 0, "Ptr", 0)
Static SWP := CallbackCreate(ObjBindMethod(ToolTipOptions, "_WNDPROC_"), , 4) ; subclass window proc
Static OWP := 0 ; original window proc
Static ToolTips := Map()
; -------------------------------------------------------------------------------------------------------------------
Static BkgColor := ""
Static TktColor := ""
Static Icon := ""
Static Title := ""
Static HFONT := 0
Static Margins := ""
; -------------------------------------------------------------------------------------------------------------------
Static Call(*) => False ; do not create instances
; -------------------------------------------------------------------------------------------------------------------
; Init() - Initialize some class variables and subclass the tooltip control.
; -------------------------------------------------------------------------------------------------------------------
Static Init() {
If (This.OWP = 0) {
This.BkgColor := ""
This.TktColor := ""
This.Icon := ""
This.Title := ""
This.Margins := ""
If (A_PtrSize = 8)
This.OWP := DllCall("User32.dll\SetClassLongPtr", "Ptr", This.HTT, "Int", -24, "Ptr", This.SWP, "UPtr")
Else
This.OWP := DllCall("User32.dll\SetClassLongW", "Ptr", This.HTT, "Int", -24, "Int", This.SWP, "UInt")
OnExit(ToolTipOptions._EXIT_, -1)
Return This.OWP
}
Else
Return False
}
; -------------------------------------------------------------------------------------------------------------------
; Reset() - Close all existing tooltips, delete the font object, and remove the tooltip's subclass.
; -------------------------------------------------------------------------------------------------------------------
Static Reset() {
If (This.OWP != 0) {
For HWND In This.ToolTips.Clone()
DllCall("DestroyWindow", "Ptr", HWND)
This.ToolTips.Clear()
If This.HFONT
DllCall("DeleteObject", "Ptr", This.HFONT)
This.HFONT := 0
If (A_PtrSize = 8)
DllCall("User32.dll\SetClassLongPtrW", "Ptr", This.HTT, "Int", -24, "Ptr", This.OWP, "UPtr")
Else
DllCall("User32.dll\SetClassLongW", "Ptr", This.HTT, "Int", -24, "Int", This.OWP, "UInt")
This.OWP := 0
Return True
}
Else
Return False
}
; -------------------------------------------------------------------------------------------------------------------
; SetColors() - Set or remove the text and/or the background color for the tooltip.
; Parameters:
; BkgColor - color value like used in Gui.BackColor(...)
; TxtColor - see above.
; -------------------------------------------------------------------------------------------------------------------
Static SetColors(BkgColor := "", TxtColor := "") {
This.BkgColor := BkgColor = "" ? "" : BGR(BkgColor)
This.TxtColor := TxtColor = "" ? "" : BGR(TxtColor)
BGR(Color, Default := "") { ; converts colors to BGR
; HTML Colors (BGR)
Static HTML := {AQUA: 0xFFFF00, BLACK: 0x000000, BLUE: 0xFF0000, FUCHSIA: 0xFF00FF, GRAY: 0x808080,
GREEN: 0x008000, LIME: 0x00FF00, MAROON: 0x000080, NAVY: 0x800000, OLIVE: 0x008080,
PURPLE: 0x800080, RED: 0x0000FF, SILVER: 0xC0C0C0, TEAL: 0x808000, WHITE: 0xFFFFFF,
YELLOW: 0x00FFFF}
If HTML.HasProp(Color)
Return HTML.%Color%
If (Color Is String) && IsXDigit(Color) && (StrLen(Color) = 6)
Color := Integer("0x" . Color)
If IsInteger(Color)
Return ((Color >> 16) & 0xFF) | (Color & 0x00FF00) | ((Color & 0xFF) << 16)
Return Default
}
}
; -------------------------------------------------------------------------------------------------------------------
; SetFont() - Set or remove the font used by the tooltip.
; Parameters:
; FntOpts - font options like Gui.SetFont(Options, ...)
; FntName - font name like Gui.SetFont(..., Name)
; -------------------------------------------------------------------------------------------------------------------
Static SetFont(FntOpts := "", FntName := "") {
Static HDEF := DllCall("GetStockObject", "Int", 17, "UPtr") ; DEFAULT_GUI_FONT
Static LOGFONTW := 0
If (FntOpts = "") && (FntName = "") {
If This.HFONT
DllCall("DeleteObject", "Ptr", This.HFONT)
This.HFONT := 0
LOGFONTW := 0
}
Else {
If (LOGFONTW = 0) {
LOGFONTW := Buffer(92, 0)
DllCall("GetObject", "Ptr", HDEF, "Int", 92, "Ptr", LOGFONTW)
}
HDC := DllCall("GetDC", "Ptr", 0, "UPtr")
LOGPIXELSY := DllCall("GetDeviceCaps", "Ptr", HDC, "Int", 90, "Int")
DllCall("ReleaseDC", "Ptr", HDC, "Ptr", 0)
If (FntOpts != "") {
For Opt In StrSplit(RegExReplace(Trim(FntOpts), "\s+", " "), " ") {
Switch StrUpper(Opt) {
Case "BOLD": NumPut("Int", 700, LOGFONTW, 16)
Case "ITALIC": NumPut("Char", 1, LOGFONTW, 20)
Case "UNDERLINE": NumPut("Char", 1, LOGFONTW, 21)
Case "STRIKE": NumPut("Char", 1, LOGFONTW, 22)
Case "NORM": NumPut("Int", 400, "Char", 0, "Char", 0, "Char", 0, LOGFONTW, 16)
Default:
O := StrUpper(SubStr(Opt, 1, 1))
V := SubStr(Opt, 2)
Switch O {
Case "C":
Continue ; ignore the color option
Case "Q":
If !IsInteger(V) || (Integer(V) < 0) || (Integer(V) > 5)
Throw ValueError("Option Q must be an integer between 0 and 5!", -1, V)
NumPut("Char", Integer(V), LOGFONTW, 26)
Case "S":
If !IsNumber(V) || (Number(V) < 1) || (Integer(V) > 255)
Throw ValueError("Option S must be a number between 1 and 255!", -1, V)
NumPut("Int", -Round(Integer(V + 0.5) * LOGPIXELSY / 72), LOGFONTW)
Case "W":
If !IsInteger(V) || (Integer(V) < 1) || (Integer(V) > 1000)
Throw ValueError("Option W must be an integer between 1 and 1000!", -1, V)
NumPut("Int", Integer(V), LOGFONTW, 16)
Default:
Throw ValueError("Invalid font option!", -1, Opt)
}
}
}
}
NumPut("Char", 1, "Char", 4, "Char", 0, LOGFONTW, 23) ; DEFAULT_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS
NumPut("Char", 0, LOGFONTW, 27) ; FF_DONTCARE
If (FntName != "")
StrPut(FntName, LOGFONTW.Ptr + 28, 32)
If !(HFONT := DllCall("CreateFontIndirectW", "Ptr", LOGFONTW, "UPtr"))
Throw OSError()
If This.HFONT
DllCall("DeleteObject", "Ptr", This.HFONT)
This.HFONT := HFONT
}
}
; -------------------------------------------------------------------------------------------------------------------
; SetMargins() - Set or remove the margins used by the tooltip
; Parameters:
; L, T, R, B - left, top, right, and bottom margin in pixels.
; -------------------------------------------------------------------------------------------------------------------
Static SetMargins(L := 0, T := 0, R := 0, B := 0) {
If ((L + T + R + B) = 0)
This.Margins := 0
Else {
This.Margins := Buffer(16, 0)
NumPut("Int", L, "Int", T, "Int", R, "Int", B, This.Margins)
}
}
; -------------------------------------------------------------------------------------------------------------------
; SetTitle() - Set or remove the title and/or the icon displayed on the tooltip.
; Parameters:
; Title - string to be used as title.
; Icon - icon to be shown in the ToolTip.
; This can be the number of a predefined icon (1 = info, 2 = warning, 3 = error
; (add 3 to display large icons on Vista+) or a HICON handle.
; -------------------------------------------------------------------------------------------------------------------
Static SetTitle(Title := "", Icon := "") {
Switch {
Case (Title = "") && (Icon != ""):
This.Icon := Icon
This.Title := " "
Case (Title != "") && (Icon = ""):
This.Icon := 0
This.Title := Title
Default:
This.Icon := Icon
This.Title := Title
}
}
; -------------------------------------------------------------------------------------------------------------------
; For internal use only!
; -------------------------------------------------------------------------------------------------------------------
Static _WNDPROC_(hWnd, uMsg, wParam, lParam) {
; WNDPROC -> https://learn.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-wndproc
Switch uMsg {
Case 0x0411: ; TTM_TRACKACTIVATE - just handle the first message after the control has been created
If This.ToolTips.Has(hWnd) && (This.ToolTips[hWnd] = 0) {
If (This.BkgColor != "")
SendMessage(1043, This.BkgColor, 0, hWnd) ; TTM_SETTIPBKCOLOR
If (This.TxtColor != "")
SendMessage(1044, This.TxtColor, 0, hWnd) ; TTM_SETTIPTEXTCOLOR
If This.HFONT
SendMessage(0x30, This.HFONT, 0, hWnd) ; WM_SETFONT
If (Type(This.Margins) = "Buffer")
SendMessage(1050, 0, This.Margins.Ptr, hWnd) ; TTM_SETMARGIN
If (This.Icon != "") || (This.Title != "")
SendMessage(1057, This.Icon, StrPtr(This.Title), hWnd) ; TTM_SETTITLE
This.ToolTips[hWnd] := 1
}
Case 0x0001: ; WM_CREATE
DllCall("UxTheme.dll\SetWindowTheme", "Ptr", hWnd, "Ptr", 0, "Ptr", StrPtr(""))
This.ToolTips[hWnd] := 0
Case 0x0002: ; WM_DESTROY
This.ToolTips.Delete(hWnd)
}
Return DllCall(This.OWP, "Ptr", hWnd, "UInt", uMsg, "Ptr", wParam, "Ptr", lParam, "UInt")
}
; -------------------------------------------------------------------------------------------------------------------
Static _EXIT_(*) {
If (ToolTipOptions.OWP != 0)
ToolTipOptions.Reset()
}
} |
|
|
| 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
|