- Сообщения
- 5,379
- Репутация
- 2,724
Для тех, кто пишет UDF'ы.
Есть в AutoIt довольно скверная штука - GUIRegisterMsg(), предназначенная для регистрации пользовательских функций обработки WM_... сообщений, не возвращает имя предыдущего обработчика. После вызова GUIRegisterMsg() для какой-нибудь функции, предыдущий обработчик автоматически "отдыхает", и узнать после этого название его функции не представляется возможным. Таким образом, если я написал два UDF, в которых используется, например, WM_COMMAND, а пользователь в своей программе использует оба этих UDF, один из них просто не будет нормально работать (или вообще не будет работать). Для частичного решения данной проблемы можно поступить следующим образом:
UDF1.au3
UDF2.au3
Теперь оба обработчика будут работать вне зависимости от того, какой из этих двух UDF'ов пользователь поставил первым в списке #Include <...>. Также могут использоваться как оба UDF'а одновременно, так и по отдельности. Единственное, что нельзя предусмотреть, это использование WM_... сообщений в самой пользовательской программе, но тут необходимо его предупредить, что если он регистрирует (в данном случае) WM_COMMAND, то из его функции обработки этого сообщения нужно вызвать один из обработчиков вышеописанных 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
Вот и все.