Autorun

Обсуждение только плагинов и утилит для Total Commander.

Модераторы: Avada, CaptainFlint, Nik, d-view, Моторокер

AkulaBig
Сообщения: 639
Зарегистрирован: Ср дек 03, 2008 11:48

Сообщение AkulaBig »

Loopback писал(а):Очень похоже на наблюдаемое поведение.
Возможно конкретный плагин устанавливается дольше, чем другие и действительно отключает или что-то подобное делает. В общем очень похоже, что вы правильно ситуацию описали. Только вот дергать похоже не надо. Я просто подождал какое-то время и все заработало. Отсюда я сделал вывод, что ShellExec(COMMANDER_PATH & "\Utilities\TCPlugman\Plugman.exe", "/Restart") надо выполнять с задержкой, хотя не очень этого хочется. Соответственно в эту строку надо вставить /WAIT, а у меня что-то не получилось. Я так и не пойму, где надо кавычки и какие ставить. Кажется пишешь впереди ~/HIDE /WAIT запятая и дальше приведенная строка. Но почему-то не работает так. Помнится я разбирался с этим, но опять забыл.

Добавлено спустя 1 час:

Похоже вы совершенно правы. Чтобы Autorun сработал, надо именно чего-нибудь дернуть. Сейчас ждал долго. Не работает. Мышкой начал щелкать в другом окне, после этого заработала перезагрузка. И проблема только при установке wdx-плагинов. Что-то можно с этим сделать?
Loopback
Сообщения: 1646
Зарегистрирован: Пн сен 07, 2009 09:29

Сообщение Loopback »

AkulaBig писал(а):в эту строку надо вставить /WAIT,
Не, сюда не надо вставлять WAIT, которая согласно документации ждёт завершения процесса. Тут, видимо, простой Sleep перед ShellExec нужен.
AkulaBig писал(а):И проблема только при установке wdx-плагинов.
Ну вот и выяснили. Значит, тотал выгружает wdx-плагины при установке нового.
AkulaBig писал(а):Что-то можно с этим сделать?
Наверно, можно попробовать запретить выгрузку Autorun директивой AutorunBlockUnload.
AkulaBig
Сообщения: 639
Зарегистрирован: Ср дек 03, 2008 11:48

Сообщение AkulaBig »

Loopback писал(а):запретить выгрузку Autorun директивой AutorunBlockUnload.
То, что нужно! Спасибо.

Добавлено спустя 1 час 6 минут:

По факту использования для хинтов портянок со сведениями из MI пришел к выводу, что это действительно не всегда удобно. Собственно решение проблемы понятно. Сделать кнопку в Панели настроек для переключения вида подсказок. Простые хинты, с Ctrl расширенные, либо всегда расширенные.
Но есть в ТС такой ключик FileTipWindowsOnIcon. Он позволяет отключить, либо ограничить именем файла подсказки над именем и другими колонками ТС, а хинты показывать над иконкой.
А можно такое в Autorun реализовать? То-есть чтобы подсказка из полей Autorun показывалась над иконкой файла?
Соответственно в строке If IsPressed (0x10) Then подставить не нажатие клавиши, а расположение над иконкой.
Loopback
Сообщения: 1646
Зарегистрирован: Пн сен 07, 2009 09:29

Сообщение Loopback »

AkulaBig писал(а):чтобы подсказка из полей Autorun показывалась над иконкой файла?
Не совсем понятно. Если включить эту опцию, то подсказка будет появляться только над значками, неважно, из полей Autorun получает она информацию, или из других.

Но при желании, полагаю, можно и без этой опции определить, находится ли указатель мыши в момент запроса полей Autorun в зоне над значком. Алгоритм должен быть примерно такой:
- узнать, включены ли значки
- узнать их размер
- получить панель, над которой находится курсор (ItemAtCursor)
- получить хэндл панели (RequestInfo)
- получить координаты этой панели (WinGetPos)
- вычислить прямоугольник, где может находиться курсор, с помощью размера значка
- получить координаты курсора (MouseGetPos)
- проверить, находится ли курсор в границах прямоугольника
AkulaBig
Сообщения: 639
Зарегистрирован: Ср дек 03, 2008 11:48

Сообщение AkulaBig »

Loopback писал(а):Если включить эту опцию, то подсказка будет появляться только над значками, неважно, из полей Autorun получает она информацию, или из других.
Я имел ввиду, что сделать такое средствами Autorun. То-есть мне совершенно не нравится, когда подсказок нет совсем. Я-бы использовал для показа подсказок стандартный ключ, а над иконкой показывал-бы средствами Autorun.
Loopback писал(а):Но при желании, полагаю, можно и без этой опции определить, находится ли указатель мыши в момент запроса полей Autorun в зоне над значком
Да, именно это меня и заинтересовало. Спасибо за алгоритм. Только один вопрос. С Ctrl+ЛКМ подсказка работает просто отвратительно. Приходится очень неудобно перемещать мышь, чтобы она появлялась. То-есть сделать такой режим основным я не за что не решусь. Поэтому хотелось-бы с этой моей хотелкой разобраться. Мышь себя будет естественно вести? То-есть я буду просто вести мышью по иконкам и подсказка просто будет появляться без всяких выкобениваний? В общем стандартно, как при использовании ключа ТС?

Добавлено спустя 30 минут:

Похоже не рабочая у меня хотелка. Проверил как работает вывод значков. Раз мы выводим хинты средствами ТС, то нельзя над полями выводить стандартный хинт, а над иконкой из Autorun. Для этого нужен код, никак не связанный с ТС. Так что сделаю просто выбор между стандартным выводом и расширенным.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Loopback писал(а):Не представляю, как сюда блокировку притянуть.
Как вы, наверное, догадались, данную статейку я почитал на досуге, чтобы лучше понимать механизм сообщений, но она меня навела на одну мысль.

Если откинуть баги Гислера и Lazarus, остается только один вариант: сообщение с IDCANCEL посылается специально и с определенной целью. Быть может, в работе ТСх64 есть некий критичный момент, когда появление диалогового окна нежелательно и может привести к проблемам, именно поэтому сразу посылается сообщение о закрытии.

Например, AkulaBig недавно писал, что при использовании TCFS2 значок Тотала на панели задач пропадает, а потом опять появляется. Я тоже заметил этот "прикол", характерный только для ТСх64. Но дело не только в TCFS2. Такое происходит и при отправке сообщений окну ТС из Autorun. То есть, складывается впечатление, что ТСх64, обрабатывыая полученные сообщения и выполняя какие-то внутренние операции, скрывает главное окно и повторно его инициализирует. По крайней мере, так выглядит визуально на панели задач.

А теперь допустим, что в такой момент что-то произойдет и значок на панели задач так и не появится. Вот именно о таком критичном моменте я и говорил. Но это только мысли, которые к реальности могут не иметь никакого отношения.
Loopback писал(а):Экземпляр контрола штука не всегда надёжная. Он постоянен только тогда, когда количество созданных контролов в процессе работы не изменяется, т.е. они не удаляются и не создаются новые.
Спасибо за объяснения. Теперь я, кажется, стал это лучше понимать.
Loopback писал(а):Для получения хэндлов элементов главного окна лучше пользоваться RequestInfo.
Да, забыл о таком, думал с хэндлами прокатит. Но этот вариант действительно представляется более надежным. Только я не совсем понял, какой именно индекс заменяет TMyPanel6 в ТСх86, потому что именно в это окно я хотел рисовать вентихлятор )

Обновленная функция, которая не требует отдельных файлов с иконками (иконка берется из основного окна ТС сообщением 0x7f и поворачивается вызовом функции PlgBlt из gdi32.dll)
[cut]

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

RegisterCommand 62016 "RotateIcon"

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(100)
        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)
    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 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", 16, "int", 16,"ptr")
    Local hbmDB2 = DllCall("CreateCompatibleBitmap", "ptr", hdcWndDC, "int", 16, "int", 16,"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", 16, _
                   "int", 16,  _
                   "uint", 0, _
                   "ptr", 0,  _
                   "uint", 0x0003)
    Local pt = Buffer(24)
    pt.Zero()
    If c = 1 Then
       pt.SetNum(0, "int", 16, "int", 0, _
                    "int", 0, "int", 0, _
                    "int", 16,  "int", 16)
    ElseIf c = 2 Then
       pt.SetNum(0, "int", 16, "int", 16, _
                    "int", 16, "int", 0, _
                    "int", 0,  "int", 16)
    ElseIf c = 3 Then
       pt.SetNum(0, "int", 0, "int", 16, _
                    "int", 16, "int", 16, _
                    "int", 0,  "int", 0)
    ElseIf c = 4 Then
       pt.SetNum(0, "int", 0, "int", 0, _
                    "int", 0, "int", 16, _
                    "int", 16,  "int", 0)
    EndIf                               
    DllCall("PlgBlt", _
                   "ptr", hdcBltDC, _
                   "ptr", pt.Ptr, _
                   "ptr", hdcMemDC, _ 
                   "int", 0, _
                   "int", 0, _ 
                   "int", 16, _
                   "int", 16, _
                   "ptr", 0, _
                   "int", 0, "int", 0)
    WinGetPos("x", "y", "w", "h", hWnd)                     
    DllCall("BitBlt", _
                   "ptr", hdcWndDC, _
                   "int", w - 20, _
                   "int", 2, _
                   "int", 16, _
                   "int", 16, _
                   "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
[/cut]
Старая функция по-прежнему доступна и вызывается с удержнием CTRL.
Loopback писал(а):- узнать, включены ли значки
- узнать их размер
- получить панель, над которой находится курсор (ItemAtCursor)
- получить хэндл панели (RequestInfo)
- получить координаты этой панели (WinGetPos)
- вычислить прямоугольник, где может находиться курсор, с помощью размера значка
- получить координаты курсора (MouseGetPos)
- проверить, находится ли курсор в границах прямоугольника
Норм алгоритм, но нужно на практике проверить, как он будет работать. Но я не стал бы заморачиваться. Когда приходится дополнительно куда-то целиться, это немного напрягает.
AkulaBig
Сообщения: 639
Зарегистрирован: Ср дек 03, 2008 11:48

Сообщение AkulaBig »

Orion9 писал(а):Когда приходится дополнительно куда-то целиться, это немного напрягает.
Представляете, многие используют подсказки над иконками. Меня это тоже удивляет.
Orion9 писал(а):Норм алгоритм, но нужно на практике проверить, как он будет работать.
А уже понятно, что он мне не подойдет. Так как он полностью зависит от настроек ТС. То-есть я хотел чтобы над колонками всплывали стандартные хинты, а над иконкой расширенные. Но такого стиля в ТС нет. Только если вообще как-то через Autorun делать. Но это чересчур.
Loopback
Сообщения: 1646
Зарегистрирован: Пн сен 07, 2009 09:29

Сообщение Loopback »

AkulaBig писал(а):Я-бы использовал для показа подсказок стандартный ключ, а над иконкой показывал-бы средствами Autorun.
В теории можно, но по факту... Придется обрабатывать сообщение WM_MOUSEMOVE, которое заворачивать в скриптовую часть, как по мне, не лучшая затея. И выполнять сопутствующие расчеты. И еще придется бороться с встроенной подсказкой или отключать ее совсем. В общем, я бы с этим не связывался.
AkulaBig писал(а): Мышь себя будет естественно вести? То-есть я буду просто вести мышью по иконкам и подсказка просто будет появляться без всяких выкобениваний?
Понятия не имею. Если пользоваться стандартной подсказкой тотала, вряд ли будут принципиальные отличия.


Orion9 писал(а):Только я не совсем понял, какой именно индекс заменяет TMyPanel6 в ТСх86
Скорее всего никакой, не у всех элементов окна есть соответствующие индексы. А вот, например, индексы 11, 12 ведут на скрытые панели, повторяющие текст видимых, но ими не являющиеся. Так что тут только экспериментировать.
Orion9 писал(а):Но я не стал бы заморачиваться.
Я и не собираюсь, поэтому только алгоритм, а не готовый код :)
AkulaBig
Сообщения: 639
Зарегистрирован: Ср дек 03, 2008 11:48

Сообщение AkulaBig »

Loopback писал(а): я бы с этим не связывался.
Я тоже пришел к такому выводу. Смысла нет связываться с этим.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

AkulaBig писал(а):Представляете, многие используют подсказки над иконками. Меня это тоже удивляет.
Это вопрос привычки, как мне кажется. На мой взгляд, удобно вызывать подсказки с удержанием различных клавиш-модификаторов, например CTRL или CTRL+SHIFT. Но можно и CapsLock использовать в некоторых случаях.
AkulaBig писал(а):То-есть я хотел чтобы над колонками всплывали стандартные хинты, а над иконкой расширенные.
Используйте CapsLock для переключения, и вся проблема. Буквально один вызов нужно добавить для проверки состояния:

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

If BitAND(DllCall("GetKeyState", "int", 0x14, "short"), 1) = 0 Then Return
Модификаторы не советую, так как они не работают в TCx64.

Раз уж речь зашла о подсказках, была у меня ещё одна в давнишних проспектах:
[cut]

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

ControlSetHint /F /D:50 28 "ButtonBarHints"

Func ButtonBarHints()
    #If Not IsPressed(0x11) Then Return
    # проверка CapsLock
    If BitAND(DllCall("GetKeyState", "int", 0x14, "short"), 1) = 0 Then Return     
    Local x, y, w, h, _
          mx, my, idx, _
          row, rows, rowh, _
          def, txt, b, extra
    # запрос дескриптора панели      
    Local hWnd = RequestInfo(28)
    If hWnd = 0 Then 
       Return "Окно панели не найдено " & hWnd
    EndIf
    # чтение информации о файле панели в wincmd.ini
    IniRead def %COMMANDER_INI% "Buttonbar" "Buttonbar" "%COMMANDER_PATH%\DEFAULT.BAR" 
    # чтение текста окна панели
    txt = WinGetText(hWnd)
    # на панель загружен временный .bar файл
    If Not StrPos(def, txt) Then
       def = COMMANDER_PATH & "\Bars" & txt
    EndIf
    # проверка существования файла панели
    def = Set (def)   
    If Not FileExist(def) Then
       Return "Файл панели не найдена " & def     
    EndIf
    # координаты и размеры окна панели
    WinGetPos("x", "y", "w", "h", hWnd) 
    # координаты указателя мыши
    MouseGetPos("mx", "my")
    # чтение информации о высоте кнопок
    IniRead b %COMMANDER_INI% "Buttonbar" "Buttonheight"
    # вычисление количества рядов кнопок на панели
    rows = Floor(h/b)    
    extra = Mod(h,b)
    # высота одного ряда
    rowh = b + Floor(extra/rows)
    # номер ряда под указателем
    row = Ceil((my - y )/rowh)
    # индекс кнопки в ряду
    idx = (Floor((mx - x)/b) + 1) + (row-1)*(Floor(w/b))
    # чтение информации о кнопке из .bar фйла
    Local sMenu, sButton, sCmd, sParam, sPath, sIcon
    IniRead sMenu   %def% "Buttonbar" %'"menu"   & idx' ""
    IniRead sButton %def% "Buttonbar" %'"button" & idx' ""        
    IniRead sCmd    %def% "Buttonbar" %'"cmd"    & idx' ""    
    IniRead sParam  %def% "Buttonbar" %'"param"  & idx' ""    
    IniRead sPath   %def% "Buttonbar" %'"path"   & idx' ""
    IniRead sIcon   %def% "Buttonbar" %'"iconic" & idx' ""    
    # возврат текста                
    Return "bar x=" & x & " y=" & y & " w=" & w & " h=" & h & auCRLF &  _
           "mouse x=" & mx & " y=" & my & auCRLF & _    
           "index= " & idx & auCRLF & _
           "rows=" & rows & " extra=" & extra & " hight=" & rowh & " row=" & row & auCRLF & _           
           "-----------" & auCRLF & _
           "menu=" & sMenu & auCRLF & _
           "button=" & sButton & auCRLF & _
           "cmd=" & sCmd & auCRLF & _
           "param=" & sParam & auCRLF & _
           "path=" & sPath  & auCRLF & _
           "iconic=" & sIcon                                           
EndFunc
[/cut]
Дополнительная подсказка к главной панели инструментов, которая отображается при включенном CapsLock или зажатом CTRL. Эта тема всплывала некоторе время назад, но чуть в другом контексте. Тут главное индекс расчитать правильно, что не так сложно, если на панели нет разделителей. И сейчас алгоритм делает именно это, он не учитывает возможные разделители в .bar файле. Поэтому хорошо будет работать, если на панели не используются разделители.

Разделители нужно учитывать отдельно, и с этим есть проблема. Но пока функция только эксперементальная, делал её только посмотреть, что из может выйти и как будет смотреться такая подсказка. Если одним словом, то понравилась.
Loopback писал(а):Скорее всего никакой, не у всех элементов окна есть соответствующие индексы.
Ну, я так и подумал, только решил уточнить на всякий случай. Будем продолжать эксперементировать и пробовать разные индексы.
AkulaBig
Сообщения: 639
Зарегистрирован: Ср дек 03, 2008 11:48

Сообщение AkulaBig »

Orion9 писал(а):удобно вызывать подсказки с удержанием различных клавиш-модификаторов, например CTRL или CTRL+SHIFT.
Дак не работают они в ТС64. И мне не нравится как они работают. Приноравливаться надо.
Orion9 писал(а):можно и CapsLock использовать
Надо попробовать. Еще ScrollLock надо проверить.
Orion9 писал(а):Буквально один вызов нужно добавить для проверки состояния
Мы эту тему обсуждали, так что я помню.
Orion9 писал(а):отображается при включенном CapsLock или зажатом CTRL.
Ctrl в ТС64 не работает. Так что остается только CapsLock.
Думаю без кнопки переключения в настройках не обойтись.

Добавлено спустя 26 минут:

ScrollLock не работает, PrintScreen работает.
AkulaBig
Сообщения: 639
Зарегистрирован: Ср дек 03, 2008 11:48

Сообщение AkulaBig »

Наконец-то форум опять заработал.
Orion9
А вы знаете, что If BitAND(DllCall("GetKeyState", "int", 0x11, "short"), 1) = 0 Then Return работает и в ТС64? Правда по хитрому. Конечно нажатие подцепиться не может, а вот переключение подхватывается. Именно на основании этого я подобрал работающее сочетание Ctrl+Break. работают много какие клавиши ,но они не удобны для использования, так как много где задействованы. Правда я в сборке сделал кнопочку для переключения вида подсказок.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

AkulaBig писал(а):Приноравливаться надо.
Это действительно вопрос привычки, о чём я писал. Но других вариантов не много. На панелях я обычно использую стандартную подсказку в зависимости от расширений. Если мне нужно получить расширенную информацию по какому-то файлу, я просто навожу на него указатель с удержанием CTRL или SHIFT+CTRL. Если я вижу, что на панели есть несколько файлов, для которых нужна расширенная подсказка, тогда использую закрепление подсказки через CapsLock.
AkulaBig писал(а):Ctrl в ТС64 не работает. Так что остается только CapsLock.
Не работает при вызове подсказки на файловых панелях, но речь шла о главной панели инструментов, где CTRL работает. Да, возможно, не многим это нужно, но у меня количество кнопок на главной панели инструментов давно перевалило за сотню, и часто хочется видеть, какую именно команду выполняет та или иная кнопка при наведении на нее указателя. Пришлось доработать функцию вызова подсказки и учесть разделители на панели.
[cut]

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

# наведение на главную панель инструментов
ControlSetHint /F /D:50 28 "ButtonBarHint"

Func ButtonBarHint()
    # состояние CapsLock и Ctrl
    If BitAND(DllCall("GetKeyState", "int", 0x14, "short"), 1) = 0 Then
       If Not IsPressed(0x11) Then Return
    EndIf
    # состояние Shift
    Local bMap = IsPressed(0x10)
    # дескриптор горизонтальной панели 
    Local hWnd = RequestInfo(28)
    If hWnd = 0 Then 
       Return "Окно панели не найдено " & hWnd
    EndIf    
    # дескриптор монитора окна ТС
    Local hMon = DllCall("MonitorFromWindow", "hwnd", AUTORUN_TCHANDLE, "dword", 2)
    # информация о масштабировании экрана
    Local nScale = 0, bRes
    bRes = DllCall("Shcore.dll\GetScaleFactorForMonitor", "hwnd", hMon, "dword*", @nScale)
    # буфер для структуры 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 x, y, w, h, mx, my, idx, row, rows, rowh, bar, txt, b, extra
    # чтение информации о файле панели в wincmd.ini
    IniRead bar %COMMANDER_INI% "Buttonbar" "Buttonbar" "%COMMANDER_PATH%\DEFAULT.BAR"
    # раскрытие переменной окружения
    bar = Set (bar)
    # в wincmd.ini указано только имя файла
    If FileGetDir(bar) = "" Then bar = COMMANDER_PATH & "" & bar
    # чтение текста окна панели
    txt = WinGetText(hWnd)
    # на панель загружен временный .bar файл
    If Not StrPos(bar, txt) Then       
       bar = COMMANDER_PATH & "\Bars" & txt
    EndIf
    # проверка существования файла панели
    If Not FileExist(bar) Then
       bar = COMMANDER_PATH & "" & txt
       If Not FileExist(bar) Then Return "Файл панели не найден " & bar     
    EndIf
    Local i, j, nButton = 0, nDiv = 0, nCount = 0    
    Local aBar = List(), aMap = List(), oButton = Map(), oCmd = Map()
    IniRead nCount  %bar% "Buttonbar" "Buttoncount" 0    
    If aBar.Count = 0 Then
       aBar.LoadFromFile(bar)
    EndIf
    Local key, val, found
    For j = 0 To aBar.Count - 1        
        found = 0    
        If StrLeft(aBar[j], 6) = "button" Then  
           found = 1
        ElseIf StrLeft(aBar[j], 3) = "cmd" Then  
           found = 2
        EndIf
        If found > 0 Then
           key = StrLower(StrPart(aBar[j], "=", 1))
           val = StrLen(StrPart(aBar[j], "=", 2))
           If found = 1 Then
              oButton.Set (key, val)              
           Else
              oCmd.Set (key, val)          
           EndIf
        EndIf
    Next
    For i = 1 To nCount     
        key = "button" & i
        val = oButton.Get(key, 0)         
        If val > 0 Then
           # количество кнопок                 
           nButton += 1
           aMap.Add(1)
        Else
           # количество разделителей  
           nDiv += 1   
           aMap.Add(0)
        EndIf
    Next
    # карта панели
    If bMap Then
       txt = auCRLF & "" & auCRLF
       For i = 0 To aMap.Count - 1
           txt &= aMap[i] & "  "
           If i > 0 and Mod(i, 50) = 0 Then txt &= auCRLF
       Next
    EndIf       
    Free(aBar, oButton, oCmd)
    # координаты и размеры окна панели
    WinGetPos("x", "y", "w", "h", hWnd) 
    # координаты указателя мыши
    MouseGetPos("mx", "my")
    # чтение информации о высоте кнопок
    IniRead b %COMMANDER_INI% "Buttonbar" "Buttonheight"
    # масштабирование экрана
    If nScale > 0 Then b = Round(b*nScale/100,0)
    # количество рядов кнопок на панели
    rows = Floor(h/b)
    If rows = 0 Then Return "Error number of rows = 0"
    # количество дополнительных пикселей
    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 nDiv = 0 Then
       idx = (Floor((mx - x)/b) + 1) + (row-1)*(Floor(w/b))
    Else
       j = 1
       idx = 0       
       For i = 0 To aMap.Count - 1
           cx += (aMap[i] = 0 ? div : b)
           ex = j*w - cx
           If i + 1 <= aMap.Count - 1 Then
              If ex < (aMap[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   
    # чтение информации о кнопке из .bar фйла
    Local sMenu, sButton, sCmd, sParam, sPath, sIcon
    If idx > 0 Then
       IniRead sMenu   %bar% "Buttonbar" %'"menu"   & idx' ""
       IniRead sButton %bar% "Buttonbar" %'"button" & idx' ""        
       IniRead sCmd    %bar% "Buttonbar" %'"cmd"    & idx' ""    
       IniRead sParam  %bar% "Buttonbar" %'"param"  & idx' ""    
       IniRead sPath   %bar% "Buttonbar" %'"path"   & idx' ""
       IniRead sIcon   %bar% "Buttonbar" %'"iconic" & idx' ""
    EndIf   
    Free(aMap)
    # возврат текста                
    Return "mouse=" & mx & ", " & my & auCRLF & _
           "bar=" & x & ", " & y & ", " & w & ", " & h & auCRLF &  _
           "map=" & tx & ", " & cx & auCRLF & _
           "row=" & row & " of " & rows & auCRLF & _
           "height=" & rowh & " (" & extra & ")" & auCRLF & _ 
           "buttons=" & nButton & " + " & nDiv & " divs" & auCRLF & _ 
           "width=" & b & ", " & div & auCRLF & _
           "mon=" & HMon & " scale=" & nScale & "%" & auCRLF & _
           "" & auCRLF & _           
           "index=" & idx & " of " & nCount & auCRLF & _           
           "menu=" & sMenu & auCRLF & _
           "button=" & sButton & auCRLF & _
           "cmd=" & sCmd & auCRLF & _
           "param=" & sParam & auCRLF & _
           "path=" & sPath  & auCRLF & _
           "iconic=" & sIcon & (bMap ? txt : "")           
EndFunc
[/cut]
Сейчас буквально выстраивается "карта" панели, чтобы расчитать все координаты. Но по-другому, видимо, нельзя.
CapsLock или CTRL - вызов подсказки. SHIFT - показ карты.
Тестировал не очень глубоко, так что за полную работоспособность ручаться не могу.
AkulaBig
Сообщения: 639
Зарегистрирован: Ср дек 03, 2008 11:48

Сообщение AkulaBig »

Orion9 писал(а):Да, возможно, не многим это нужно
У меня так настроен ТС, что тема иконок переключается при изменении в настройках ТС. Поэтому чем меньше пользовательских кнопок, тем красивей.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

AkulaBig писал(а):Поэтому чем меньше пользовательских кнопок, тем красивей.
Чем меньше пользовательских кнопок, тем больше пустого, зияющего пространства справа, что само по себе некрасиво, на мой взгляд. По той же причине верхнее меню должно иметь больше пунков и занимать хотя бы половину экрана, а не четверть, как это сейчас. Ну и начиная с Win10, пустое пространство заголовка ТС просто само просит, чтобы его чем-то заполнили. CPU, RAM и прочее как никогда оказались кстати.

Loopback
Ну как там багофиксы продвигаются, конец виден?
Ответить