1

Тема: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Можно ли добавить кнопку в окно калькулятора, например?
При нажатии на эту кнопку должна выполняться функция скрипта ahk, например, открывать еще один калькулятор.
Если нельзя средствами ahk (я по крайней мере не нашел), то можно ли сделать это как-то по-другому?

Сейчас единственным решением вижу, создание окна GUI поверх окна калькулятора.

2

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Не знаю как насчет добавить, а повесить свою функцию на существующую кнопку можно так, например (проверено на калькуляторе) :

MButton::  MouseGetPos,,, TargetWin, TargetControl
$LButton::
   MouseGetPos,,, CurentWin, CurrentControl
   if ((TargetWin == CurentWin) && (TargetControl == CurrentControl))
   {
     MsgBox,,, Своя программа,1
   }
   else Click down
return

LButton UP:: Click up

Выбор кнопки - средняя клавиша мыши

3

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Irbis пишет:

Не знаю как насчет добавить, а повесить свою функцию на существующую кнопку можно так, например (проверено на калькуляторе) :

MButton::  MouseGetPos,,, TargetWin, TargetControl
$LButton::
   MouseGetPos,,, CurentWin, CurrentControl
   if ((TargetWin == CurentWin) && (TargetControl == CurrentControl))
   {
     MsgBox,,, Своя программа,1
   }
   else Click down
return

LButton UP:: Click up

Выбор кнопки - средняя клавиша мыши

По-моему, это что-то новое. Стоит добавить в коллекцию.

4

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Сделано
http://forum.script-coding.com/viewtopic.php?id=6997

Заменить это понятно и легко. А вот именно надо добавить кнопки, а не использовать существующие. Это возможно?

5

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

А если у приложения контролы устроены не стандартно, что делать будете?

6

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Это другой вопрос. Будем считать, что контролы стандартные. Я привел пример калькулятора, там стандартные контролы. Мне надо туда добавить 3 своих кнопки.

7

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Можно увеличить свободное пространство окна,

WinMove, Калькулятор, , , , 800

затем создать своё окно GUI с прозрачным фоном с нужными кнопками и переместить его в свободное пространство. Тогда вопрос сводится к тому, как сделать, чтобы они не "разъехались" при перетаскивании.

Либо создать GUI-клон "Калькулятора", добавить в него свои кнопки. Окно "Калькулятора" сделать невидимым, информацию из него передавать в GUI при помощи ControlGet --> ControlSetText, а из GUI в него при помощи ControlSend.

8

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Да. О создании GUI поверх я писал в первом посте.
GUI клон не подходит, меня интересует именно добавление своих кнопок в окно.
Видимо прямого решения с добавлением кнопок нет.
В любом случае тема стала немного полезна, добавили один скрипт в коллекцию.

9

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Жаль, не могу посоветовать, как сделать динамическое изменение формы стандартного приложения, НО есть способ, как добавить элементы управления в  EXE файл:
Resource Hacker позволяет добавить любые кнопки, изменить размер формы и много еще чего

http://savepic.net/2602537.jpg

Самим приложением они не обрабатываются, но думаю и сами знаете, что с ними делать.  Надеюсь, это пригодится.

10

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Это уже интереснее и ближе к делу, но ковырять exe нет возможности.
Я хотел это сделать в окне AutoCAD, точнее в окне быстрого выбора.

11

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Один из вариантов и наверное самый простой, кроме того можно подгружать AutoHotkey.dll и создавать свои окна и контолы в чужом процессе, в том числе выполнять скрипты в отдельном потоке, но это уже отдельная тема.

VarSetCapacity(pt,8)
Gui, +Hwndhgui -Caption +ToolWindow
Gui, Margin,0,0
Gui, Add,Button,w36 h24 gbt1

z::
hParentWnd:=WinActive("A")
;MouseGetPos,,,,hParentWnd,2
DllCall("GetCursorPos","uint",&pt)
DllCall("ScreenToClient","uint",hParentWnd,"uint",&pt)
x:=NumGet(pt), y:=NumGet(pt,4)
DllCall("SetParent","uint",hgui,"uint",hParentWnd)
Gui, Show, x%x% y%y%
return

bt1:
MsgBox Своя кнопка
return

Esc::
ExitApp

12

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Браво! Все гениально просто... (выглядит)

13

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

InFlames пишет:

Сделано
http://forum.script-coding.com/viewtopic.php?id=6997

Заменить это понятно и легко. А вот именно надо добавить кнопки, а не использовать существующие. Это возможно?

Поправьте, пожалуйста, описание.
Абсолютно не понятно, что делает код. Попробовал запустить скрипт и всё равно не понял, что он делает с калькулятором (у меня в нём всё по-прежнему).

14

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

kirtech пишет:

Один из вариантов и наверное самый простой, кроме того можно подгружать AutoHotkey.dll и создавать свои окна и контолы в чужом процессе, в том числе выполнять скрипты в отдельном потоке, но это уже отдельная тема.

VarSetCapacity(pt,8)
Gui, +Hwndhgui -Caption +ToolWindow
Gui, Margin,0,0
Gui, Add,Button,w36 h24 gbt1

z::
hParentWnd:=WinActive("A")
;MouseGetPos,,,,hParentWnd,2
DllCall("GetCursorPos","uint",&pt)
DllCall("ScreenToClient","uint",hParentWnd,"uint",&pt)
x:=NumGet(pt), y:=NumGet(pt,4)
DllCall("SetParent","uint",hgui,"uint",hParentWnd)
Gui, Show, x%x% y%y%
return

bt1:
MsgBox Своя кнопка
return

Esc::
ExitApp

---------------------------
test.ahk
---------------------------
Error:  Invalid option.

Specifically: y

Line#
004: Gui,Add,Button,w36 h24 gbt1
006: Return
007: hParentWnd := WinActive("A")
009: DllCall("GetCursorPos","uint",&pt) 
010: DllCall("ScreenToClient","uint",hParentWnd,"uint",&pt) 
011: x:=NumGet(pt), y:=NumGet(pt,4) 
012: DllCall("SetParent","uint",hgui,"uint",hParentWnd) 
---> 013: Gui,Show,x%x% y%y%
014: Return
017: MsgBox,����
018: Return
021: ExitApp
022: Exit
023: Exit
023: Exit

The current thread will exit.
---------------------------
ОК   
---------------------------

15 (изменено: Irbis, 2012-04-09 09:50:34)

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Drugoy пишет:

017: MsgBox,����

Посмотри тут, пункты 1 и 4.

Насчет http://forum.script-coding.com/viewtopic.php?id=6997 согласен, не для всех очевидно, что своя функция (в данном примере) вешается на кнопку средней клавишей мыши.
Надо бы расписать логику работы, составить блок-схему, заодним уж развернуто объяснить, как работает MouseGetPos,
для чего нужны хоткеи, что делает конструкция if...  else... И так - по каждому скрипту на 30+ страницах форума
В общем, RTFM и будет вам счастье.

16 (изменено: Drugoy, 2012-08-23 03:03:02)

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Разобрался-таки с тем, что делает скрипт.
Куда интересней мне показался скрипт от kirtech.
Вот по нему есть пара вопросов:
1. как конкретно у этой кнопки и как вообще в AutoHotkey можно (ли?) задавать позицию не от левого верхнего угла окна?
Поясню, для чего: если тем скриптом создать в окне 500х500пикс кнопку в самом низу, а потом ресайзнуть окно за нижнюю границу, потянув её вверх (и тем самым уменьшив размер окна) - то кнопка исчезнет из зоны видимости. А хочется, чтобы её позиция была как у, скажем, какого-то статусбара, который виден всегда.
У меня есть идея, только через запуск Loop с какой-то периодичность перерисовывать кнопку, но этот вариант мне не нравится.

2. Для чего в этом скрипте нужно:

VarSetCapacity(pt,8)

? И почему длина переменной выбрана равной именно восьми? В хэлпе как-то не очень понятно ссылаются на то, что эта команда используется обычно при DllCall (который я пока ещё не освоил), но не понятно зачем.

3. Где можно найти список функций для DllCall? Без него не понятно что вот эти строки делают:

DllCall("GetCursorPos","uint",&pt)
DllCall("ScreenToClient","uint",hParentWnd,"uint",&pt)
DllCall("SetParent","uint",hgui,"uint",hParentWnd)

4. Читал мануалы по команде GUI, но так и не понял - умеет ли AHK назначать картинку вместо текста создаваемым кнопкам?

5. Как правильно переделать скрипт так, чтобы кнопка добавлялась не по хоткею, а при появлении окна?
У меня есть только такая идея:

WinWait, specific_window
hParentWnd:=WinExist("specific_window")

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

WinWaitClose, specific_window
goto/gosub start

?

6. Можно ли как-то избежать того, что при клике по добавленной кнопке, окно, к которому она была добавлена - теряет фокус? Можно конечно в метку, которая отвечает за выполнение кода при нажатии на кнопку, добавить в начало команду "WinActivate родительское окно", но если по кнопке нажать и не отпускать - то родительское окно потеряет фокус, т.е. фокус хоть на время, но теряется. Можно ли этого избежать?

7. У меня есть скрипт который скрывает/восстанавливает активному окну заголовок (title bar), так вот созданная вышеприведённым скриптом кнопка по сути находится внутри своего собственного окна, и ей тоже получается восстановить заголовок (и при этом происходит баг, что кнопка смещается), можно ли это как-то запретить насовсем?

17

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

kirtech пишет:

Один из вариантов и наверное самый простой, кроме того можно подгружать AutoHotkey.dll и создавать свои окна и контолы в чужом процессе, в том числе выполнять скрипты в отдельном потоке, но это уже отдельная тема.

Пожалуйста, а не могли бы вы показать на примере как это сделать?

18

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

1. Можете используя ShellProc callback function отлавливать HSHELL_REDRAW и «перерисовывать окно» при перерисовке родительского окна.
2. Ответ в справке
3. GetCursorPos задавайте подобные вопросы как можно чаще.
5. Либо «ждите окно» постоянно, либо отслеживайте HSHELL_WINDOWACTIVATED.
7. Добавьте в упомянутом скрипте соответствующее окно в исключения.

Пожалуйста, а не могли бы вы показать на примере как это сделать?

Вопрос не мне задан, но: по ссылке достаточно документации с примерами.

Ваш бы энтузиазм в задавании вопросов да перенаправить на поиск ответов…

19

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

4. Да, уже было на форуме.
6. Конечно нет.

20 (изменено: Drugoy, 2012-08-23 17:26:50)

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

creature.ws пишет:

1. Можете используя ShellProc callback function отлавливать HSHELL_REDRAW и «перерисовывать окно» при перерисовке родительского окна.

По ссылке понятно, что это за функция и для чего она. Но я не понимаю, как её использовать: там же описан C++ синтаксис, а не AutoHotkey, не могли бы вы привести кусок кода (я прошу даже не рабочий скрипт, а просто кусок кода, чтоб понять какой там синтаксис использовать).

creature.ws пишет:

2. Ответ в справке

Я же написал, что справку читал. Там сказано, что это позволяет ограничивать длину переменной. Но зачем? Что будет, если её не ограничивать? DllCall съест всю память чтоли?

creature.ws пишет:

3. GetCursorPos задавайте подобные вопросы как можно чаще.

Я умею пользоваться поиском. Вопрос был не в том, что такое GetCursorPos (ведь и из названия понятно, что эта функция возвращает позицию курсора), а в том какие функции может вызывать DllCall. Для меня сам DllCall, пока что - это тёмный лес. Я так понял, что DllCall - это такой "мост" из autohotkey к "более системным" функциям самой винды, ведь "Dll Call" переводится как вызов библиотеки динамических ссылок.
Очень хотелось бы узнать как им пользоваться, желательно с массой примеров (примеров много не бывает), но документации о том как им пользоваться из AutoHotkey - я не нашёл, приходится учиться читая коды чужих скриптов и расспрашивая не особо разговорчивых людей.

creature.ws пишет:

5. Либо «ждите окно» постоянно, либо отслеживайте HSHELL_WINDOWACTIVATED.

Как я понял - это тоже функция ShellProc, и в autohotkey справке абсолютно ничего не сказано по ShellProc.

creature.ws пишет:

7. Добавьте в упомянутом скрипте соответствующее окно в исключения.

Nочно, сам подумал об этом позже, спасибо.

creature.ws пишет:

Вопрос не мне задан, но: по ссылке достаточно документации с примерами.

Меня спугнуло то, что там требуют установить AutoHotkey_H, и не сказано работает ли это в AutoHotkey_L. Ну и потом - не очень-то это удобно, когда ради ответа на маленький вопрос приходится читать топик целиком. И никто не обещает, что в этом топике будут примеры использования.

Александр_ пишет:

4. Да, уже было на форуме.

Спасибо, кажется нашёл.
Поражает, что среди перечисленных в справке вариантов для "Gui, Add" отсутствует "picture", который идёт ниже в качестве примеров. Очень плохая документация по GUI.

Александр_ пишет:

6. Конечно нет.

Я правильно понял, что если сформулировать ваш ответ иначе, то в AutoHotkey принципиально отсутствует возможность добавления кнопок в существующие окна таким образом, чтобы это было именно добавление кнопок, а не эмуляция добавления, через создания собственных окон повех существующих?

21 (изменено: creature.ws, 2012-08-23 17:41:33)

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Нужный кусок кода можно найти в поиске по форуму. Вы не пробовали.

Размер резервируется под возвращаемое значение, если размер меньше нужного — данные не поместятся. Динамическое выделение памяти под переменные, автоматическая инициализация — свойство ahk, но не неопределённого множества функций которые можно вызвать используя DllCall.

Масса абстрактных примеров не нужна. Необходимая базовая информация есть в соответствующем разделе справки.
Вы просите «обзор по функция win API», к разделу форума отношения запрос не имеет msdn читайте.

22

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

creature.ws пишет:

Нужный кусок кода можно найти в поиске по форуму. Вы не пробовали.

Не правда, пробовал: гугл по этому запросу "shellproc site:forum.script-coding.com" выдаёт 0 результатов.

creature.ws пишет:

Размер резервируется под возвращаемое значение, если размер меньше нужного — данные не поместятся. Динамическое выделение памяти под переменные, автоматическая инициализация — свойство ahk, но не неопределённого множества функций которые можно вызвать используя DllCall.

Да что будет с данными, если им не хватает места - это и так понятно. Вопрос то был в другом: зачем вообще задавать какие-то ограничения размера? Если их не задавать - что будет? Я думаю, что в таком случае, сколько переменная запросит места - столько ей и выделят. Если это так, и если известно, что люди в своих скриптах используют ограничения длины для значений переменных (зачем-то же они это делают), то значит есть либо какая-то вероятность утечки памяти, если не задать ограничение, либо что-то будет работать не так, как положено.
В этом и вопрос - зачем люди задают ограничение на длину значения для переменной?
В справке на этот вопрос ответа нет.

creature.ws пишет:

Масса абстрактных примеров не нужна. Необходимая базовая информация есть в соответствующем разделе справки.
Вы просите «обзор по функция win API», к разделу форума отношения запрос не имеет msdn читайте.

На msdn понятия не имеют о существовании AutoHotkey, там все коды на С++. Даже если они сами по себе понятны - не понятно как их из AutoHotkey правильно использовать.

Я вижу, что у меня появляется больше вопросов, чем ответов, значит я что-то делаю не так. Значит, пора задать свои вопросы где-то ещё.

23

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Давайте ссылку где вы прочитали, что VarSetCapacity() ограничивает длину, иначе ход ваших мыслей непонятен. Вроде бы сказано мной — «резервирует место» под данные в переменной.

Задавать вопросы и не читать ответы — плохой способ разобраться в чём-либо, выглядит как поиск внимания, а не ответов.
Возможно где-то любят цитировать msdn

24 (изменено: Александр_, 2012-08-23 19:24:27)

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

Drugoy пишет:

Я правильно понял, что если сформулировать ваш ответ иначе, то в AutoHotkey принципиально отсутствует возможность добавления кнопок в существующие окна таким образом, чтобы это было именно добавление кнопок, а не эмуляция добавления, через создания собственных окон повех существующих?

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

creature.ws пишет:

«резервирует место»

«выделяет память» .

25

Re: AHK: Добавить кнопку в произвольное окно (не ahk GUI)

creature.ws пишет:

Давайте ссылку где вы прочитали, что VarSetCapacity() ограничивает длину, иначе ход ваших мыслей непонятен. Вроде бы сказано мной — «резервирует место» под данные в переменной.

Задавать вопросы и не читать ответы — плохой способ разобраться в чём-либо, выглядит как поиск внимания, а не ответов.
Возможно где-то любят цитировать msdn

Простите мне мою невнимательность: я чего-то и не обратил внимания, на то, что вы (да и в мануале то же самое) говорили именно про выделение памяти, а не ограничение максимального размера для выделеяемой памяти. Тогда всё сразу становится понятно.
Только маленький вопрос: а что будет, если выделить переменной больше места, чем надо?

Александр_ пишет:

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

Я в этом очень плохо разбираюсь, так что заранее прошу за возможно очень глупый вопрос, но разве внедрение dll-ки в процесс - не добавляет эту dll-ку в адресное пространство процесса?
У меня даже в подтверждение моей версии есть пример: есть такая утилита, называется "unlocker" которая позволяет удалять занятые (используемые в данный момент) каким-то приложением файлы. Насколько я помню - она работает через внедрение своей dll-ки в чужие процессы. И потом эту саму внедряемую dll-ку нельзя будет удалить, пока процесс не будет перезапущен, т.к. система будет говорить, что какое-то приложение использует этот файл.
Нельзя кнопку в чужой процесс внедрить как dll-ку?