Что нового

_GUIRegisterMsg - расширение нативной функции

Webarion

Осваивающий
Сообщения
143
Репутация
24
Версия AutoIt
3.3.14.5
Версия
1.0.1
Небольшая UDF, для расширения GUIRegisterMsg. Помогает, когда необходимо зарегистрировать несколько функций для одного сообщения и определить порядок их выполнения. Может пригодиться, когда в UDF от другого разработчика, сообщение уже используется, а вам, тоже надо.

Пример регистрации нескольких функций на сообщение WM_INITMENUPOPUP:
Код:
#include <Array.au3>
#include '_GUIRegisterMsg.au3'

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

#Region GUI
$hForm = GUICreate("_GuiRegisteMsg", 243, 155, -1, -1)
$iMenu = GUICtrlCreateMenu(_Tr('Open this menu', 'Откройте это меню'))
$iMenuItem = GUICtrlCreateMenuItem(_Tr('Menu item', 'Пункт меню'), $iMenu)
$iButton1 = GUICtrlCreateButton(_Tr('Viewing registered functions', 'Просмотр зарегистрированных функций'), 8, 8, 227, 25)
$iButton2 = GUICtrlCreateButton(_Tr('Change the order of execution of functions', 'Изменить порядок выполнения функций'), 8, 39, 227, 25)
$iButton3 = GUICtrlCreateButton(_Tr('Release _Example1', 'Освободить _Example1'), 8, 72, 139, 25)
$iButton4 = GUICtrlCreateButton(_Tr('Release _Example2', 'Освободить _Example2'), 8, 100, 139, 25)
$iButton5 = GUICtrlCreateButton(_Tr('Reset', 'Сброс'), 176, 100, 59, 25)
GUISetState(@SW_SHOW)
#EndRegion GUI

; Registering functions for the $ WM_INITMENUPOPUP message. Регистрация функций для сообщения $WM_INITMENUPOPUP
_GUIRegisterMsg($WM_INITMENUPOPUP, '_Example1', 1)
_GUIRegisterMsg($WM_INITMENUPOPUP, '_Example2', 2)
_GUIRegisterMsg($WM_INITMENUPOPUP, '_Example3', 3)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $iButton1
            _DemoList() ; Show a list of registered functions. Показываем список зарегистрированных функций
        Case $iButton2
            ; We set for the message $ WM_INITMENUPOPUP, the order of execution of the function _Example1 after all others
            ; Устанавливаем для сообщения $WM_INITMENUPOPUP, порядок выполнения функции _Example1 после всех других
            _GUIRegisterMsg($WM_INITMENUPOPUP, '_Example1', 10)
            _DemoList()
        Case $iButton3
            ; Freeing the _Example1 function from the $ WM_INITMENUPOPUP message. Освобождаем функцию _Example1 от сообщения $WM_INITMENUPOPUP
            _GUIUnRegisterMsg($WM_INITMENUPOPUP, '_Example1')
            _DemoList()
        Case $iButton4
            ; Freeing the _Example2 function from the $ WM_INITMENUPOPUP message. Освобождаем функцию _Example2 от сообщения $WM_INITMENUPOPUP
            _GUIUnRegisterMsg($WM_INITMENUPOPUP, '_Example2')
            _DemoList()
        Case $iButton5
            ; Restoring the registration example to default values. Восстанавливаем пример регистрации, до значений по умолчанию
            _GUIRegisterMsg($WM_INITMENUPOPUP, '_Example1', 1)
            _GUIRegisterMsg($WM_INITMENUPOPUP, '_Example2', 2)
            _GUIRegisterMsg($WM_INITMENUPOPUP, '_Example3', 3)
            _DemoList()
    EndSwitch
    Sleep(10)
WEnd

; To perform functions, open the form menu. Для выполнения функций, откройте меню формы
Func _Example1($hWnd, $Msg, $wParam, $lParam)
    _ExampleMsgBox(1)
EndFunc   ;==>_Example1

Func _Example2($hWnd, $Msg)
    _ExampleMsgBox(2)
EndFunc   ;==>_Example2

Func _Example3()
    _ExampleMsgBox(3)
EndFunc   ;==>_Example3

Func _ExampleMsgBox($i)
    MsgBox(0, '', _Tr('Executed function _Example' & $i & ' for message $ WM_INITMENUPOPUP', 'Выполнена функция _Example' & $i & ' для сообщения $WM_INITMENUPOPUP'))
EndFunc   ;==>_ExampleMsgBox

Func _DemoList()
    _ArrayDisplay( _Get_GUIRegisterMsg(), _Tr('List of registered functions', 'Список зарегистрированных функции'), '', 0, Default, _Tr('Message', 'Сообщение') & '|' & _Tr('Function name', 'Название функции') & '|' & _Tr('Execution order', 'Порядок выполнения'))
EndFunc   ;==>_DemoList

Func _Tr($sEn, $sRu)
    Return Number(@OSLang) = 419 ? $sRu : $sEn
EndFunc   ;==>_Tr
 
Автор
Webarion
Источник
Ссылка на источник

Вложения

  • _GUIRegisterMsg.zip
    6.4 КБ · Просмотры: 4
Последнее редактирование:

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Это не сильно помогает для совместимости с чужими UDF, т.к зарегистрированное в них уже сообщение попросту не будет обработано.
Вот если бы GUIRegisterMsg возвращала имя ранее зарегистрированной функции, то это имело бы смысл.
Это могло бы быть полезно в построении своих UDF, чтобы избавиться от конфликта с другими.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
11 лет назад был создан тикет на эту тему, Валик отклонил предложение и сказал что эта функция должна в нативном варианте работать по типу AdlibRegister, но оно так и не было реализовано.
 
Автор
W

Webarion

Осваивающий
Сообщения
143
Репутация
24
Это не сильно помогает для совместимости с чужими UDF, т.к зарегистрированное в них уже сообщение попросту не будет обработано.
Вот если бы GUIRegisterMsg возвращала имя ранее зарегистрированной функции, то это имело бы смысл.
Это могло бы быть полезно в построении своих UDF, чтобы избавиться от конфликта с другими.

В этом случае достаточно посмотреть, какую функцию регистрирует сторонняя UDF и перерегистрировать её в своей программе, и обе функции будут работать. Не так гибко, как в случае с возвращением имени функции, но работать будет, например:
Код:
; Допустим, в стороннем UDF используется следующая регистрация
GUIRegisterMsg($WM_PAINT, '_Function_Another_Developer') ;
;

; Просто делаем в своём коде так
_GUIRegisterMsg($WM_PAINT, '_Function_Another_Developer', 1) ; Перерегистрируем функцию другого разработчика
_GUIRegisterMsg($WM_PAINT, '_MyFunction', 2) ; Регистрируем свою функцию

; Или так, если нужно изменить последовательность выполнения
_GUIRegisterMsg($WM_PAINT, '_Function_Another_Developer', 2)
_GUIRegisterMsg($WM_PAINT, '_MyFunction', 1)

11 лет назад был создан тикет на эту тему, Валик отклонил предложение и сказал что эта функция должна в нативном варианте работать по типу AdlibRegister, но оно так и не было реализовано.
Да, жаль что не реализовали, это было бы достаточно гибко. Пока буду пользоваться самописным вариантом.
 
Последнее редактирование:

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
На данный момент всё что может сделать автор библиотеки, так это указать в справке нечто такое:
Эта UDF регистрирует WM_COPYDATA сообщение, поэтому любая другая UDF или скрипт регистрирующий данное сообщение, должен вызывать функцию __SciTE_WM_COPYDATA из своей регистрируемой функции, пример:
Код:
Func WM_COPYDATA($hWnd, $nMsg, $wParam, $lParam)
    __SciTE_WM_COPYDATA($hWnd, $nMsg, $wParam, $lParam)
    
    ;...
EndFunc
 
Автор
W

Webarion

Осваивающий
Сообщения
143
Репутация
24
На данный момент всё что может сделать автор библиотеки, так это указать в справке нечто такое:
Согласен, это самый простой и быстрый вариант. Только не "обзывайся")) Я хотел сделать эквивалент оригинала. В своей UDF, если я её допилю), я собираюсь указать, что вместо GuiRegisterMsg, нужно использовать _GuiRegisterMsg, которая будет встроена в библиотеку.
 
Последнее редактирование:
Автор
W

Webarion

Осваивающий
Сообщения
143
Репутация
24
Возможно тебе будет интересно посмотреть другие аналоги подобной UDF.
Да, первый вариант в поиске интересен. Немного смущает организация данных в массиве, быть может и есть в этом смысл. Единственное, что могу сказать, что мой скрипт чуть быстрее отрабатывает событие. А так, любой вариант можно использовать.
 
Верх