Страница 194 из 243

Добавлено: Пн июл 21, 2025 12:49
AkulaBig
Loopback писал(а):То что не работает - это баг, регресс с версии 2.2.17.
Понятно. Тогда будем ждать исправлений. Так-то такая запись и по моему мнению более правильная, чем буфер гонять.

Добавлено: Вт июл 22, 2025 05:22
yahuu
Loopback писал(а):
yahuu писал(а):Можно ли добавить функцию двойного щелчка в SetHotkeyAction?
Наверно имелось в виду ControlSetMouseAction? В любом случае, к сожалению, нет. Есть технические сложности.
Нет, я ожидаю, что у SetHotkeyAction будет функция двойного щелчка, например, двойной щелчок по цифровой клавише для выполнения какой-либо команды cm_ или em_.

Если это невозможно реализовать, придется использовать AHK.

Добавлено: Вт июл 22, 2025 11:12
Loopback
yahuu
Теперь понял. Для обработки двойного нажатия клавиши требуется другой принцип, в отличие от использованного в SetHotkeyAction. Сомневаюсь, что удастся такое реализовать в рамках SetHotkeyAction, но посмотрю.

Добавлено: Сб июл 26, 2025 12:59
Orion9
yahuu писал(а):Если это невозможно реализовать, придется использовать AHK.
Да, в AHK есть примеры, как сделать обработку двойного или даже тройного нажатия клавиш, но и в Autorun можно сделать что-то похожее. Самый простой пример:

Код: Выделить всё

SetHotkeyAction /H:F12 F12DoublePress

Func F12DoublePress()
    Static t1 = 0
    If (GetUptime() - t1) < 300 Then
       ShowHint("F12 double pressed")
    EndIf
    t1 = GetUptime()
EndFunc
В примере не учитывается обработка одиночного нажатия, но если она нужна, то её можно добавить.

Loopback
К сожалению, дел ещё по горло и времени на Autorun и на ТС пока нет, но все-таки посмотрел флаг DT_CALCRECT в функции DrawText, как обещал. Заморочек там много, и вряд ли они стоят того, чтобы с ними разбираться. Может быть, вы внесёте изменения в ShowHint и сделаете возможность менять содержимое посказки и другие параметры без вызова новой подсказки? Например, брать хэндл не из макроса LAST_HINT_WINDOW, а от самой функции ShowHint и возвращаемого ей значения. А все остальные операции с подсказкой делать через этот хэндл, включаяя изменение стиля и текста, если требуется.

Ещё одна давняя проблема. На нижней функциональной кнопке "Выход" у меня висит две функции:

Код: Выделить всё

ControlSetMouseAction /L /B:7 17 AutorunStatus
ControlSetHint /F /D:50 /B:7 17 "AutorunHints"
Одна для вызова меню по клику, другая для вызова подсказки по наведению указателя мыши. Если навести мышь на кнопку и нажать до появления подсказки над ней, то ТС очень часто валится. Если нажимать после появления подсказки - то никогда. Вероятно, это связано с тем, что при наведении указателя на кнопку происходит запуск функции ControlSetHint, которая не успев отработать до конца перекрывается вызовом ControlSetMouseAction. Можно как-то решить проблему?

А по поводу Гислера... Ну что тут можно сказать. Меня его смешные и нелепые отмазки не устраивают, и это касается не только drag'n'drop на панелях. Как было отмечено в оригинальном топике, для тех, у кого много кнопок на главной панели, эта фича просто маст-хэв. Я уж не говорю, что совсем не лишним было бы перетаскивание кнопок с панели на панель, например с вертикальной на горизонтальную и наоборот.
AkulaBig писал(а):Наконец-то я закончил переделку сборки на многоязычную. 2202 строки кода на Autorun.
Рад, что дела у вас не стоят на месте. Когда я полность освобожусь, то обязательно посмотрю последнюю версию вашей сборки.

Добавлено: Сб июл 26, 2025 15:51
AkulaBig
Orion9 писал(а):А по поводу Гислера... Ну что тут можно сказать. Меня его смешные и нелепые отмазки не устраивают
Кода у вас появится время, прочтите на оффоруме (если к тому времени тема не пропадет) мою тему про косяки перевода. Меня многие поддержали и обосновали намного лучше меня. Ответ Гислера гениален - я не буду ничего переделывать :lol:

Добавлено: Сб июл 26, 2025 19:13
Orion9
AkulaBig
Ну, это хотя бы честный ответ, который можно принять и жить дальше. Но зачем водить за нос пользователей несерьёзными аргументами типа "если бы я добавил drag and drop, даже с Shift, была бы большая опасность случайного перетаскивания кнопок". Подобные ответы, кроме смеха и недоумения ничего не вызывают.

Добавлено: Сб июл 26, 2025 21:38
Loopback
Orion9 писал(а):но и в Autorun можно сделать что-то похожее
Кстати да, вполне себе рабочий вариант. Я как-то в тот момент зациклился на внутренней реализации, а зачем, если всё уже есть.
Orion9 писал(а):К сожалению, дел ещё по горло и времени на Autorun и на ТС пока нет, но все-таки посмотрел флаг DT_CALCRECT в функции DrawText, как обещал. Заморочек там много, и вряд ли они стоят того, чтобы с ними разбираться. Может быть, вы внесёте изменения в ShowHint и сделаете возможность менять содержимое посказки и другие параметры без вызова новой подсказки?
У меня тоже времени не сказать чтобы много.

В принципе нет там каких-то особых заморочек. Потом посмотрю, наверно можно сделать коррекцию размера при получении сообщения WM_SETTEXT, тогда можно будет менять текст с WinSetText.
Orion9 писал(а): Например, брать хэндл не из макроса LAST_HINT_WINDOW, а от самой функции ShowHint и возвращаемого ей значения. А все остальные операции с подсказкой делать через этот хэндл, включаяя изменение стиля и текста, если требуется.
Если бы так было можно, то так и было бы сделано. Но в чём проблема с использованием LAST_HINT_WINDOW?

Стили по хэндлу менять точно нет.
Orion9 писал(а):Можно как-то решить проблему?
Не знаю пока, надо тестировать.

Добавлено: Сб июл 26, 2025 23:33
Orion9
Loopback писал(а):У меня тоже времени не сказать чтобы много.
О срочности речи не было. Да и вообще это не так уж и обязательно. Просто если будет возможность менять текст подсказки без вызова нового окна, это позволит использовать подсказку в виде "висящего табло", в котором содержимое обновляется без мелькания окон.
Loopback писал(а):Но в чём проблема с использованием LAST_HINT_WINDOW?
Немного смутило, что в справке говорится об использовании задержки, если хэндл не возвращается.
Loopback писал(а):Стили по хэндлу менять точно нет.
А вообще это можно как-то сделать на уже отображенной подсказке? Опять же, сугубо факультативно.
Loopback писал(а):Не знаю пока, надо тестировать.
Да вот сделал на скорую руку, думал баг проявится, но нет - ТС ни разу не завалился:

Код: Выделить всё

ControlSetHint /F /D:50 /B:5 17 "F7Hint"

Func F7Hint()
    Return "F7 hint text" 
EndFunc

ControlSetMouseAction /L /B:5 17 F7MouseAction

Func F7MouseAction()
     ShowPopupMenu /D /F "CreateF7Menu"
EndFunc

Func CreateF7Menu()
    Local txt
    txt = txt & 'MENUITEM "Menu 1", 10000' & auCRLF         
    txt = txt & 'MENUITEM "Menu 2", 10000' & auCRLF         
    txt = txt & 'MENUITEM "Menu 3", 10000' & auCRLF         
    txt = txt & 'MENUITEM SEPARATOR' & auCRLF
    txt = txt & 'MENUITEM "Settings...", 10000' & auCRLF         
    Return txt
EndFunc
В реальности все сложнее. Я так подозревваю, проблема может быть из-за того, что в обеих функциях у меня используется объект Plugin. Хинт я уже сбрасывал:
[cut]

Код: Выделить всё

ControlSetHint /F /D:50 /B:7 17 "AutorunHints"
 
Func AutorunHints()   
    Local A_Version, A_Copyright, A_DateTime, _
          A_Wdx = AUTORUN_PATH & "\Autorun.wdx", txt   
                        
    If IsPressed (KEY_SHIFT) Then Return GetState("libs")
    If IsPressed (KEY_CTRL) Then 
       txt = GetState("procs")
       If StrLen(txt) > 0 Then txt = auCRLF & txt
       Return GetState("threads") & txt
    Endif   
    If IsPressed (KEY_ALT) Then Return GetState("paths") 
    
    A_Version   = FileGetVersion(A_Wdx, "FileVersion")
    A_Copyright = FileGetVersion(A_Wdx, "LegalCopyright")
    obj = Plugin("FileDateTime")
    If ERROR = 0 Then
       obj.FileName = A_Wdx
       A_DateTime = StrFormat("%.0f", obj.GetValue(3))
       Free(obj)
    Else
       A_DateTime = "Error " & ERROR
    Endif
    Return "Версия: " & A_Version & auCRLF & "Дата изменения: " & A_DateTime & auCRLF & "Авторские права: " & A_Copyright 
    
EndFunc
[/cut]
А вот меню так просто сбросить не получится - там много всего лишнего завязано. В общем, как появится больше времени, вернусь к этому.

Добавлено: Вс июл 27, 2025 11:54
Loopback
Orion9 писал(а):Немного смутило, что в справке говорится об использовании задержки, если хэндл не возвращается.
Если что, речь идет не более чем нескольких десятках миллисекунд. И это ограничение я, кажется, уже устранил.
Orion9 писал(а):А вообще это можно как-то сделать на уже отображенной подсказке? Опять же, сугубо факультативно.
Если всё переписать фактически с нуля - можно, конечно. Просто подсказки вообще не планировались с прицелом на динамическое использование.
Orion9 писал(а):ТС ни разу не завалился
Ну ок, как появится что-то, что можно повторить - вернёмся к этому.

Добавлено: Вс июл 27, 2025 12:21
Orion9
Loopback писал(а):Если что, речь идет не более чем нескольких десятках миллисекунд. И это ограничение я, кажется, уже устранил.
Это хорошо. А то действительно не совсем понятно было, что с этой задержкой делать. Ведь если не известно, нужна задержа или не нужна, пришлось бы по факту каждый раз её вставлять, чтобы гарантировать получение хэндла.
Loopback писал(а):Если всё переписать фактически с нуля - можно, конечно.
Понял. Не стоит оно того. Не берите в голову. Ну тогда хотя бы текстовое содержимое если будет возможность менять динамически, и то будет хорошо.
Loopback писал(а):Ну ок, как появится что-то, что можно повторить - вернёмся к этому.
Я буду ещё пересматривать и оптимизировать эту кнопку, когда появится возможность. Так что да - можно будет к этому вернуться со временем.

А пока заменил получение данных от объекта Plugin на:

Код: Выделить всё

A_DateTime = Date('yyyyMMdd', FileGetTime(A_Wdx))
Проблема стала появляться значительно реже, но всё ещё появляется. Думал, что это как-то связано с GetState(), т.к. у меня перед выстраиванием меню каждый раз запрашивается GetState("paths"). Внёс некоторые изменения, не помогло. Скорее всего это никак не связано с какой-то отдельной функцией Autorun, объектом или вызовом, просто кода довольно много собрано в ControlSetHint и в ControlSetMouseAction. А когда эти две функции одновременно выполняются (при наведении и нажатии на кнопку B:7), происходит какой-то конфликт, который и приводит к завалу ТС.

В общем, разберемся со временем.

Добавлено: Вс июл 27, 2025 18:20
Orion9
Loopback
Решил добить я это дело, так как вылет ТС всё-таки раздражает, и, кажется, понял в чём проблема.

Код для теста и воспроизведения проблемы:

[cut]

Код: Выделить всё

ControlSetHint /F /D:50 /B:5 17 "F7Hint"

Func F7Hint()
    If IsPressed (0x10) Then Return GetState("paths") 
    Sleep(50)
    Return "F7 hint text" & auCRLF & GetState("paths")
EndFunc

ControlSetMouseAction /L /B:5 17 F7MouseAction
ControlSetMouseAction /L /K:C /B:5 17 F7MouseAction

Func F7MouseAction()
     ShowPopupMenu /D /F "CreateF7Menu"
EndFunc

Func CreateF7Menu()
    Local txt
    Static p = GetState("paths")
    txt = txt & 'MENUITEM "Menu 1", 10000' & auCRLF         
    txt = txt & 'MENUITEM "Menu 2", 10000' & auCRLF         
    txt = txt & 'MENUITEM "Menu 3", 10000' & auCRLF         
    txt = txt & 'MENUITEM SEPARATOR' & auCRLF
    txt = txt & 'MENUITEM "Settings...", 10000' & auCRLF         
    Return txt
EndFunc
[/cut]
В общем, ТС на самом деле не валился, а просто выходил по cm_Exit, то есть получалось, что время от времени ControlSetMouseAction не срабатывала и нажималась обычная кнопка выхода, хотя этого не должно происходить. В примере выше функция F7MouseAction тоже иногда не срабатывает, что приводит не к вызову меню, а запуску стандартного диалога для создания нового каталога. Но будьте готовы, что баг проявляется довольно редко - может потребоваться 10-15 кликов, и то нет гарантии, что поймаете ) Нужно стараться кликнуть прямо перед самым появлением подсказки. У меня он, конечно, проявлялся намного чаще, пока не заменил получение данных от Plugin("FileDateTime") на Date('yyyyMMdd', FileGetTime(A_Wdx)).

Добавлено: Вс июл 27, 2025 21:21
Loopback
Orion9 писал(а):Но будьте готовы, что баг проявляется довольно редко
Я так и не смог добиться описанного эффекта.

Единственный момент, когда на самом деле вызывается исходное действие кнопки - это когда курсор находится над самым её краем с левой стороны, буквально в пределах нескольких пикселей. Тут дело в том, что нет возможности точно узнать ширину и координаты этих кнопок, они рассчитываются исходя из общей ширины контрола и позиции кнопки, в результате возникает ошибка координат прямоугольника, тем большая, чем правее расположена кнопка. Если не переопределять исходное действие, это обычно незаметно.

Возможно, это и есть причина, но она никак не связана с подсказками.

Добавлено: Вс июл 27, 2025 23:14
Orion9
Loopback
Вероятно, так и есть. Я почему-то был уверен, что дело именно в конфликте двух привязанных к контролу функций - ControlSetHint и ControlSetMouseAction, которые приводили к вылету из ТС. Но теперь стало понятно, что никакого вылета и не было, а просто срабатывало исходное действие кнопки "Выход". В свое время я наловчился обходить этот вылет ТС "умелым" кликом после появления подсказки - так мне казалось безопаснее, чем кликать до её появления ) Но поскольку давно не пользовался этой кнопкой и её функционалом, связанным с Autorun, завалил несколько раз ТС, что и привело к желанию написать о баге и разобраться с ним наконец, хотя это следовало сделать намного раньше.

Спасибо, что помогли разобраться! )

Добавлено: Пн июл 28, 2025 12:40
Loopback
Orion9 писал(а):Вероятно, так и есть.
Это хорошо. Конечно, такое смещение кнопок тоже косячок, надо будет попробовать исправить.

Добавлено: Пн июл 28, 2025 16:58
Orion9
Loopback писал(а):надо будет попробовать исправить
Да, было бы здорово. Но и сейчас уже стало неплохо, когда знаешь истинную причину. Стараюсь теперь ближе к центру кликать по горизонтали - пока ни разу не [s]лоханулся[/s] промахнулся )

Кстати, неплохой пример с менюшкой на предыдущей странице. Я когда с функцией обратного вызова разбирался, тоже пробовал что-то такое. С практической точки зрения совершенно бесполезное, но с технической точки зрения может кому-то пригодится:

Код: Выделить всё

# WM_MENUSELECT
SetMessageAction /P 0x011F "MenuSelectCallback" 	

Func MenuSelectCallback(hWnd, uMsg, wParam, lParam)
    Local buf = Buffer(100), _          
          nId = BitAND(wParam, 0xffff)
    DllCall("GetMenuStringW", _
            "handle", lParam, _   
            "uint", nId, _   
            "ptr", buf.ptr, _   
            "int", 50, _
            "uint", 0)
    WinSetText("uMsg: " & uMsg & " ID: " & nId & " lParam: " & lParam & " Item: " & buf.GetStr())   
    ShowHint("uMsg: "   & uMsg & auCRLF & _
             "ID: "     & nId & auCRLF & _
             "lParam: " & lParam & auCRLF & _
             "Item: "   & buf.GetStr(), "", "", 500, 1)         
EndFunc
Функция MenuSelectCallback вешается на сообщение WM_MENUSELECT в окне ТС и вызывается каждый раз, когда происходит выбор пункта меню. Работает и на верхнем меню ТС, и на контекстном. Функция ничего не делает, только выводит информацию о пункте меню в заголовок и в отдельную подсказку, но неплохо демонстрирует, как работает Callback через SetMessageAction.