Что нового

Совместное использование сообщений двумя UDF библиотеками

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 714
Для тех, кто пишет UDF'ы.

Есть в AutoIt довольно скверная штука - GUIRegisterMsg(), предназначенная для регистрации пользовательских функций обработки WM_... сообщений, не возвращает имя предыдущего обработчика. После вызова GUIRegisterMsg() для какой-нибудь функции, предыдущий обработчик автоматически "отдыхает", и узнать после этого название его функции не представляется возможным. Таким образом, если я написал два UDF, в которых используется, например, WM_COMMAND, а пользователь в своей программе использует оба этих UDF, один из них просто не будет нормально работать (или вообще не будет работать). Для частичного решения данной проблемы можно поступить следующим образом:

UDF1.au3
Код:
Global $__UDF1_WM0111 = 0

GUIRegisterMsg($WM_COMMAND, 'UDF1_WM_COMMAND')

...

Func UDF1_WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
	; Handler from UDF2.au3
	If (IsDeclared('__UDF2_WM0111')) And (Not $__UDF2_WM0111) Then
		$__UDF1_WM0111 = 1
		Local $Result = UDF2_WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
		$__UDF1_WM0111 = 0
		If $Result <> $GUI_RUNDEFMSG Then
			Return $Result
		EndIf
	EndIf
	...
	Return $GUI_RUNDEFMSG
EndFunc   ;==>UDF1_WM_COMMAND


UDF2.au3
Код:
Global $__UDF2_WM0111 = 0

GUIRegisterMsg($WM_COMMAND, 'UDF2_WM_COMMAND')

...

Func UDF2_WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
	; Handler from UDF1.au3
	If (IsDeclared('__UDF1_WM0111')) And (Not $__UDF1_WM0111) Then
		$__UDF2_WM0111 = 1
		Local $Result = UDF1_WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
		$__UDF2_WM0111 = 0
		If $Result <> $GUI_RUNDEFMSG Then
			Return $Result
		EndIf
	EndIf
	...
	Return $GUI_RUNDEFMSG
EndFunc   ;==>UDF2_WM_COMMAND


Теперь оба обработчика будут работать вне зависимости от того, какой из этих двух UDF'ов пользователь поставил первым в списке #Include <...>. Также могут использоваться как оба UDF'а одновременно, так и по отдельности. Единственное, что нельзя предусмотреть, это использование WM_... сообщений в самой пользовательской программе, но тут необходимо его предупредить, что если он регистрирует (в данном случае) WM_COMMAND, то из его функции обработки этого сообщения нужно вызвать один из обработчиков вышеописанных UDF'ов (любой, но только один). Примерно так:

Код:
Func MY_WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    Local $Result = UDF1_WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    If $Result <> $GUI_RUNDEFMSG Then
        Return $Result
    EndIf
    ...
    Return $GUI_RUNDEFMSG
EndFunc   ;==>MY_WM_SETCURSOR


Вот и все.
 
Верх