1 (изменено: Raam, 2012-03-17 16:28:29)

Тема: AHK: Вызов контролов хоткеем с установкой метки на контроле

Хотелось бы скрипт для биндинга кнопок. При этом хотелось бы обрамлять контрол или подписывать . Это нужно для быстрого перехода между треками в Аудио Редакторе. Если точнее то хочется назначать клик в иконку гитары, барабана и т.д. помечая ее (см Скриншот). Редактор этого сам не умеет, а для использования функция необходимая для перехода между разными инструментами в реальном времени.
http://cachepe.zzounds.com/media/quality,85/SHS7_ConsoleView-760df984399caca22c8adc86a38bff41.jpg

Структурная схема Кода:

#RButton:: ; win + правый клик в иконку гитары
Создает красную рамку вокруг иконки и назначает Hotkey1.

Каждый клик создает новую рамку с новым биндом(Hotkey2 , 3...).

Hotkey1::Клик в центр привязанной рамки рамки

Эта тема началась из другой, но чтоб не оффтопить решил создать отдельную, хоть и связанную.
Горячие клавиши:
win + Left Click - каждый клик привязывает целевой контрол к очередной клавиши Нампада.
win + Right Click - стирание всех назначений
win + Numpad(x) - ControlClick в привязанный контрол.
  *чтоб не спамить укоротил код до трех клавиш. Подозреваю, что можно укоротить код и другими способами, но не хватает знаний.

Причина создания темы и связь с предыдущей:
Хочется добавить сюда элементы GUI, чтоб каждый отмеченый контрол помечался меткой в виде названия хоткея (которая может перемещаться с контролом, и не затирается другими окнами). К сожалению, это пока не получилось. Поможете?

#LButton::
MouseGetPos, , , id, control
WinGetTitle, title, ahk_id %id%

If bind =
{
    Bind =1
    track1 = %control% 
    Shortcut = Numpad1
    TrayTip, %title%, : %Shortcut%, 10, 1
    Return
}
If bind = 1
{
    Bind =2
    track2 = %control%
    Shortcut = Numpad2
    TrayTip, %title%, : %Shortcut%, 10, 1
    Return
}
If bind = 2
{
    Bind = 3
    track3 = %control%
    Shortcut = Numpad3
    TrayTip, %title%, : %Shortcut%, 10, 1
    Return
}
Return

#RButton::
bind =
track1 =
track2 =
track3 =
title =
TrayTip, Win - %title%, Shortcut: %Shortcut% `n Canceled , 10, 1
 Return

#Numpad1::
ControlClick, %track1%, %title%,,,, NA x100 y100
Return

#Numpad2::
ControlClick, %track2%, %title%,,,, NA x100 y100
Return

#Numpad3::
ControlClick, %track3%, %title%,,,, NA x100 y100
Return

2

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

Raam, ознакомься с первой темой на странице, отредактируй заголовок.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

Пардон, забыл, исправил.

4 (изменено: creature.ws, 2012-03-16 21:42:53)

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

hWnds := []

#Numpad1::
#Numpad2::
#Numpad3::
#Numpad4::
#Numpad5::
#Numpad6::
#Numpad7::
#Numpad8::
#Numpad9::
    ControlClick,, % "ahk_id" hWnds[SubStr(A_ThisHotkey, 8)]
    Return
Numpad1 & LButton::
Numpad2 & LButton::
Numpad3 & LButton::
Numpad4 & LButton::
Numpad5 & LButton::
Numpad6 & LButton::
Numpad7 & LButton::
Numpad8 & LButton::
Numpad9 & LButton::
    MouseGetPos,,,, hWndSub, 2
    hWnds[SubStr(A_ThisHotkey, 7, 1)] := hWndSub
    Return

При включенном NumLock, при зажатой клавише NumPad'а, клик левой кнопки мыши по контролу ассоциирует контрол с зажатой клавишей.
Нажатие Win + NumPad(x) производит клик по ассоциированному контролу.

// NumLock должен быть включен, «контролы» должны определятся стандартными средствами AHK (Для кликов по элементам интерфейса многих браузеров и всех игр не подойдёт)


hWnds := []
Loop 9
    Hotkey, #Numpad%A_Index%, cClick

Return

cClick:
    ControlClick,, % "ahk_id" hWnds[SubStr(A_ThisHotkey, 8)]
    Return
#RButton::hWnds.Remove(hWnds.MinIndex(), hWnds.MaxIndex())
#!RButton::hWnds.Remove() ; удаляет последний «бинд»
#LButton::
    MouseGetPos,,,, hWndSub, 2
    hWnds.Insert(hWndSub)
    Return

Так — компактнее, но менее «дружелюбно к пользователю».

5

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

Спасибо за примеры. Так действительно намного компактнее.
Первый скрипт удобен, независимой очередностью биндов. Его недостаток - использование чистых клавиш нампада в процессе назначения, а эти клавиши уже имеют свои функции в программе и активируют свои функции.
Второй - работает как мой, но выглядит компактно. Теперь курю Help, чтоб понять куда там вставить TrayTip, чтоб наглядно видеть какую клавишу назначаю или отменяю.
Впрочем это не главная задача.  Первостепенно для меня прицепить к контролу  Идентификатор ( GUI метку с названием назначенного хоткея )

6

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

А заголовок темы и пример кода создают впечатление, что речь о компактном коде привязывающем клик по кнопке к горячей клавише

Отредактировали бы заголовок тогда, до конкретной формулировки без жаргонизмов.

7

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

Снова пардон   Виноват, исправился.
Изменил формулировку в названии и уточнил текст первого поста.
Приведенные Вами компактные коды имеют практическую и образовательную пользу для меня, так что ваш труд не напрасен. И я буду рад продолжению и развитию темы.

8

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

Еще раз спасибо за ваши версии скриптов. Я их проанализировал с Хелпом и теперь я использую не на ClassNN, а HWND. Это исключает ошибочное срабатывание, когда открыты опциональные окна в программе. Теперь все работает точнее.

«контролы» должны определятся стандартными средствами AHK (Для кликов по элементам интерфейса многих браузеров и всех игр не подойдёт)

То есть если мне нужны более точные координаты дочерних контролов, и контроллов других программ, то это вне компетенции AHK? Или нужно будет обращаться к DllCall?
Приделывание GUI меток все еще актуально.
Поскольку я так и не смог понять как извлечь переменную для TrayTip из вашего скрипта, я по прежнему пользуюсь своей старой структурой скрипта, видоизменив в деталях.

Ниже мой текущий скрипт целиком:

SetControlDelay -1

#Numpad1::ControlClick , , ahk_id %track1%
#Numpad2::ControlClick , , ahk_id %track2%
#Numpad3::ControlClick , , ahk_id %track3%
#Numpad4::ControlClick , , ahk_id %track4%
#Numpad5::ControlClick , , ahk_id %track5%
#Numpad6::ControlClick , , ahk_id %track6%
#Numpad7::ControlClick , , ahk_id %track7%
#Numpad8::ControlClick , , ahk_id %track8%
#Numpad9::ControlClick , , ahk_id %track9%
#Numpad0::ControlClick , , ahk_id %track0%





#LButton::
MouseGetPos ,,,Id , TrackId, 3

If bind =
{
    Bind =1
    track1 = %TrackId% 
    Shortcut = Numpad1
    TrayTip,   Win + %Shortcut%, Assigned , 11, 1
    Return
}
If bind = 1
{
    Bind =2
    track2 = %TrackId%
    Shortcut = Numpad2
    TrayTip,   Win + %Shortcut%, Assigned , 11, 1
    Return
}
If bind = 2
{
    Bind = 3
    track3 = %TrackId%
    Shortcut = Numpad3
    TrayTip,   Win + %Shortcut%, Assigned , 11, 1
    Return
}
If bind = 3
{
    Bind = 4
    track4 = %TrackId%
    Shortcut = Numpad4
    TrayTip,   Win + %Shortcut%, Assigned , 11, 1
    Return
}
If bind = 4
{
    Bind = 5
    track5 = %TrackId%
    Shortcut = Numpad5
    TrayTip,   Win + %Shortcut%, Assigned , 11, 1
    Return
}
If bind = 5
{
    Bind = 6
    track6 = %TrackId%
    Shortcut = Numpad6
    TrayTip,   Win + %Shortcut%, Assigned , 11, 1
    Return
}
If bind = 6
{
    Bind = 7
    track7 = %TrackId%
    Shortcut = Numpad7
    TrayTip,   Win + %Shortcut%, Assigned , 11, 1
    Return
}
If bind = 7
{
    Bind = 8
    track8 = %TrackId%
    Shortcut = Numpad8
    TrayTip,   Win + %Shortcut%, Assigned , 11, 1
    Return
}
If bind = 8
{
    Bind = 9
    track9 = %TrackId%
    Shortcut = Numpad9
    TrayTip,   Win + %Shortcut%, Assigned , 11, 1
    Return
}
If bind = 9
{
    Bind = 0
    track0 = %TrackId%
    Shortcut = Numpad0
    TrayTip,   Win + %Shortcut%, Assigned , 11, 1
    Return
}
If bind = 0
    TrayTip,   Win + %Shortcut%, Assigned , 11, 1
return


#RButton::
bind =
track1 =
track2 =
track3 =
track4 =
track5 =
track6 =
track7 =
track8 =
track9 =
track0 =
Shortcut =
TrayTip, Cancel , All Shortcuts Remuved , 11, 1
 Return

9 (изменено: creature.ws, 2012-03-17 16:17:10)

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

То есть если мне нужны более точные координаты дочерних контролов, и контроллов других программ, то это вне компетенции AHK? Или нужно будет обращаться к DllCall?

Более точные чем… ? Каких других программ? К какой функции посредством DllCall вы собираетесь обратится?

Поскольку я так и не смог понять как извлечь переменную для TrayTip из вашего скрипта, я по прежнему пользуюсь своей старой структурой скрипта, видоизменив в деталях.

Какая переменная требуется для TrayTip?
hWnds.Insert(hWndSub) записывает в массив hWnd дочернего окна при каждом клике. Записывает в «следущую ячейку массива». Если при каждом клике вы ожидаете видеть TrayTip с ассоциированной в массиве позицией — добавьте в подпрограмму #LButton::
TrayTip, % "Win + Numpad" hWnds.MaxIndex(), Assigned, 11, 1

Приделывание GUI меток все еще актуально.

Догадаться, что речь про обрамление дочерних окон и добавление некого текстового комментария рядом с  «контролом» поверх родительского окна, можно лишь прочитав тему по ссылке. Не удивляйтесь отсутствию комментариев.

10 (изменено: Raam, 2012-03-17 16:52:20)

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

Снова дополнил первый пост.

Более точные чем… ? Каких других программ? К какой функции посредством DllCall вы собираетесь обратится?

На картинке в исправленном первом посте, видно еще много кнопочек, а MouseGetPos определяет только столбик инструмента целиком независимо от точки клика. "Каких других программ?" Ну вы говорили про игры и браузеры. DllCall - для меня темный лес, не туда приплел видимо. Вот я и спрашиваю возможно ли средствами AHK найти id всех этих мини кнопочек и иконок с картинки, или кнопок в играх.

Спасибо за строку  TrayTip, % "Win + Numpad" hWnds.MaxIndex(), Assigned, 11, 1

Не удивляйтесь отсутствию комментариев.

Я не удивляюсь, я рад вашим комментариям, не требуя обязательного участия от всех. Хотя было бы приятно видеть участие других.

11

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

много кнопочек, а MouseGetPos определяет только столбик инструмента целиком независимо от точки клика

Если предположить, что в «столбике инструмента» не «неопределяемые контролы», а «картинка обрабатывающая координаты кликов»,
то привязывать к горячим клавишам придётся координаты клика. Точности определения координат клика посредством MouseGetPos достаточно.

OFF: Разве предназначение комментариев не передача информации, а доставление радости? Я вот пытаюсь передать, что название темы не освещает вопрос, обсуждение либо решение которого является приоритетным.

12

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

creature.ws пишет:

Если предположить, что в «столбике инструмента» не «неопределяемые контролы», а «картинка обрабатывающая координаты кликов»

Туплю. Вероятно это именно так и я это учту.

OFF: Разве предназначение комментариев не передача информации, а доставление радости? Я вот пытаюсь передать, что название темы не освещает вопрос, обсуждение либо решение которого является приоритетным.

OFF: Для меня общение это синтез информации и эмоций.  Если бы вы мне грубили или игнорировали, общение было бы коротким. Если для Вас это не так, то наверно у нас в мозгу разные скрипты .  Предложите пожалуйста название, я уже трижды менял, и все не в тему?

13

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

Raam пишет:

Эта тема началась из другой, но чтоб не оффтопить решил создать отдельную, хоть и связанную.

Раз создали, значит надо решать.

Raam пишет:

Хочется добавить сюда элементы GUI...

Основной элемент есть в моём коде, если захотите добавить, ещё и не получится, обсудим тут (извините, не стал заморачиваться более чем с одним (не считая уведомлений)).

Функционал:
Win+LMB - первое нажатие, поиск контрола (с активацией подсветки периметра контрола под курсором), после выбора контрола-жертвы, повторное нажатие на ту же связку клавиш (Win+LMB), для присвоения горячей клавиши/клавиш выбранному контролу в поле ввода. Дальнейшие добавления хоткеев по той же схеме. В случае когда надо удалить/переназначить/отменить есть стандартное уведомление с вариантами (удалить все назначенные хоткеи можно отметив чек-бокс в самом окне).

CoordMode, Mouse
Menu, Tray, NoStandard
Menu, Tray, Add, Exit, ExitScript

HKeys:=[], IsKey:=False
bmd1=
(Join
0000ffff000000000000ffff000000000000
ffff000000000000ffff000000000000ffff
)
bmd2=
(Join
00ffffff0000000000ffffff0000000000ff
ffff0000000000ffffff0000000000ffffff
)
hpatbr1:=CreatePBrush(bmd1), hpatbr2:=CreatePBrush(bmd2)

#LButton::
   If WinExist("ahk_id"GUIhWnd) Or WinExist("ahk_id"hMsg)
      Return
   If !IsSeek
      For Key, Value In HKeys
         Hotkey, % Value.key1, HKeyLabel, Off
   If IsSeek
      SetTimer, Settings, -75
   SetTimer, ChaseCursor, % (IsSeek:=!IsSeek) ? 125:"Off"
   Return

ChaseCursor:
   MouseGetPos,,,, nCtrl, 1
   MouseGetPos,,,, hCtrl, 2
   WinGetPos, X, Y, W, H, % "ahk_id"hCtrl
   CreateRgn(X, Y, W, H, hpatbr1, 6)
   If hCtrlPassed<>hCtrl
      Gosub, Redraw
   hCtrlPassed:=hCtrl
   Return

Settings:
   Gui, +AlwaysOnTop -Caption +Border +ToolWindow HwndGUIhWnd
   Gui, Add, Hotkey, vHKey x4 y4 w118 h20
   Gui, Add, Button, x76 y27 w45 h20, Set
   If % Counter>=1
   {
      Gui, Add, Checkbox, x6 y27 w70 h20 vIsChecked, Delete all
      Gui, Add, ListView, x4 y57 w118 h100
         , % " hotkey"(Counter>1 ? "s":"")
         . " ("Counter ") |  hCtrl  |  nCtrl  "
      For Key, Value In HKeys
      {
         SetFormat, Integer, H
         Value_value1:=Value.value1
         SetFormat, Integer, D
         LV_Add("", Value.key1, Value_value1, Value.value2)
      }
      Gui, Show, w127 h164
   }
   Else Gui, Show, w127 h53
   CreateRgn(X, Y, W, H, hpatbr1)
   CoordMode, Mouse, Relative
   ControlGetPos, CX, CY, CW, CH, Button1, % "ahk_id"GUIhWnd
   MouseMove, CX+CW//2, CY+CH//2, 0
   CoordMode, Mouse
   Return

ButtonSet:
   Gui, Submit
   Gui, Destroy
   SetTimer, Redraw, -0
   If !HKey Or IsChecked
   {
      SetTimer, % "EditMsg"(IsChecked ? "":"2"), -50
      MsgBox, % 2622 . (IsChecked ? 08:12)
            ,, % IsChecked ? "Deleted":"Hotkey is not set"
            . ", try again?", % IsChecked ? 1:0
      IfMsgBox, Yes
         Goto, Settings
      Else Goto, Continue
   }
   For Key, Value In HKeys
      If IsDuplicate:=(Value.key1=HKey And Value.value1=hCtrl)
      {
         SetTimer, EditMsg, -50
         MsgBox, 262160,, % "Duplicate`n("HKey ")", 1
         Goto, Continue
      }
   For Key, Value In HKeys
      If % Value.key1=HKey Or Value.value1=hCtrl
      {
         IsKey:=(Value.key1=HKey) ? True:False
         SetTimer, % "EditMsg"(IsKey ? "":"2"), -50
         MsgBox, % 26221 . (IsKey ? 1:2)
               ,, % "This "(IsKey ? "hotkey ("HKey ")":"control")
               . " already used"(IsKey ? ", choose resolve below":"")
               . "`n"(IsKey ? "":"set this hotkey ("HKey ") too?")
         IfMsgBox, No
            Goto, Continue
         IfMsgBox, Yes
         {
            For Key, Value In HKeys
               If % Value.key1=HKey
                  HKeys.Remove(Key)
            Break
         }
         IfMsgBox, Cancel
         {
            For Key, Value In HKeys
               If % Value.key1=HKey
                  HKeys.Remove(Key)
            Goto, Continue
         }
      }
   HKeys.Insert( New Data(HKey, hCtrl, nCtrl))
Continue:
   For Key, Value In HKeys
   {
      Counter:=A_Index
      Hotkey, % Value.key1, HKeyLabel, On
   }
   Return

HKeyLabel:
   SetTimer, Redraw, -250
   For Key, Value In HKeys
      If Value.key1=A_ThisHotkey
      {
         WinGetPos, X, Y, W, H, % "ahk_id"Value.value1
         Break
      }
   MouseClick,, X+W//2, Y+H//2,, 0
   CreateRgn(X, Y, W, H, hpatbr2)
   KeyWait, % A_ThisHotkey
   Return

EditMsg:
   If IsChecked Or IsDuplicate
   {
      Control, Hide,, Button1, A
      If IsChecked
         HKeys:=[], Counter:=IsChecked:=False
      IsDuplicate:=False
      WinMove, A,, A_ScreenWidth//2-(150//2)
                 , A_ScreenHeight//2-(90//2), 150, 90
   }
   Else
   {
      ControlSetText, Button1, Reassign, A
      ControlSetText, Button2, Cancel, A
      ControlSetText, Button3, Delete, A
   }
EditMsg2:
   WinSet, Style, -0xC00000, % "ahk_id"hMsg:=WinActive("A")
   Return

Redraw:
   DllCall("RedrawWindow", "UInt", 0
                         , "UInt", 0
                         , "UInt", hRgn
                         , "UInt", 0x787)
   DllCall("DeleteObject", "UInt", hRgn)
   Return

ExitScript:
   DllCall("DeleteObject", "UInt", hpatbr1)
   DllCall("DeleteObject", "UInt", hpatbr2)
   ExitApp

CreatePBrush(bmd)
{
   VarSetCapacity(Buffer, nSize:=StrLen(bmd)//2, 0)
   Loop, % nSize
      NumPut("0x"SubStr(bmd, 2*A_Index-1, 2)
                           , Buffer, A_Index-1, "UChar")
   hBm:=DllCall("CreateBitmap", "UInt", 3
                              , "UInt", 3
                              , "UInt", 1
                              , "UInt", 32
                              , "UInt", &Buffer)
   Return, DllCall("CreatePatternBrush", "UInt", hBm)
   DllCall("DeleteObject", "UInt", hBm)
}

CreateRgn(xpos, ypos, width, height, pbrush, mixmode=13)
{
   global hRgn
   hDC:=DllCall("GetDC", "UInt", 0)
   DllCall("SetROP2", "UInt", hDC, "Int", mixmode)
   hRgn:=DllCall("CreateRectRgn", "Int", xpos
                                , "Int", ypos
                                , "Int", xpos+width
                                , "Int", ypos+height)
   DllCall("FrameRgn", "UInt", hDC
                     , "UInt", hRgn
                     , "UInt", pbrush
                     , "UInt", 6
                     , "UInt", 6)
   DllCall("ReleaseDC", "UInt", 0
                      , "UInt", hDC)
}

Class Data
{
   __New(key1, value1, value2)
   {
      This.key1:=key1, This.value1:=value1, This.value2:=value2
   }
}

14

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

Финальная версия, ура Впечатляет.

15

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

creature.ws пишет:

Впечатляет.

Спасибо, было бы это всё востребовано.

16

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

creature.ws и Grey.
Большое спасибо за скрипты и подсказки. Код востребован и будет использоваться.
Grey, я успел скопировать даже предыдущий Ваш скрипт и потом удивиться что он исчез . Но поскольку было мало времени для тестов и анализа я не отозвался сразу.
Идея развилась еще более глобально, а всей той базы что вы мне дали, на данный момент достаточно. Когда появятся неразрешимые самостоятельно вопросы, я задам их.

/*
Вообще, я не программист, а музыкант. Поэтому, прежде чем задать очередной вопрос, для анализа и реализации новых функций приходится выкуривать АХК.Хелп вдоль и поперек (не вешать же все на ваши плечи ). А раньше, в игроманские загулы написал на АХК десятки мелких скриптов и ботов для своих персонажей в играх. Потом я делал скрипты для работы с таблицами и 1С, на работе. Во многом тогда помог Teadrinker.  Вот, теперь я вернулся к АХК, для решения насущных задач музыкантов.
*/

17

Re: AHK: Вызов контролов хоткеем с установкой метки на контроле

Raam пишет:

...потом удивиться что он исчез .

Да, совершенно неожиданно нашёл ошибку, забрал код на доработку, впредь буду оставлять комментарий своих действий.