firex
AutoIT Гуру
- Сообщения
- 943
- Репутация
- 208
Доброго времени суток!
Заранее приношу свои извинения за столь ужасный вид примера, набросал его вырывая куски из проекта.
Попробуйте потянуть за ползунок в Edit ( или управляющие скроллом стрелки ), желательно несколько раз.
Происходит следующее:
1) Тянем ползунок, функция _Wnd_Proc повисает пока не отпустим клавишу ( работает стандартный обработчик CallWindowProc ).
2) Отпускаем ползунок, обработчик освобождает выполнение и мой завершается.
3) И тут начинается самое веселое: В тот момент, когда мы тянули ползунок - сообщения о перерисовке окна должен был принимать CallBack, однако AutoIt их не вызывает до тех пор, пока не завершит работу CallWindowProc.
4) После завершения работы CallWindowProc он оставляет ( предыдущие вызовы ) у себя в памяти, а самое странное -
не выполняет их.
5) При получении нового вызова - он выполняет не его, а первый в порядке приоритета из повисших!
Схема ( как видно - происходит сдвиг в вызове, зачем их AutoIt вообще коллекционирует? ):
Может у кого есть идеи как можно совместить все обработчики и заставить их корректно отрабатывать?
*Для контрола и окна отдельные Callback функции не решают проблему.
*GUICreate ( внутренний обработчик AutoIt ) решает проблему, но к сожалению ее использование не допускается.
P.S. Есть идея:
1)Ставить хук $WH_CALLWNDPROC
2)Фильтровать на нужные сообщения
3)Если сообщения подходят - ставить контролу свой обработчик
4)CallNextHook
5)Ловить это сообщение в обработчике
5-1)Вернуть стандартный обработчик
5-2)Сделать необходимые действия.
Но сами понимаете - такие дебри я буду использовать в последнюю очередь, надеюсь на вашу помощь.
Заранее приношу свои извинения за столь ужасный вид примера, набросал его вырывая куски из проекта.
Попробуйте потянуть за ползунок в Edit ( или управляющие скроллом стрелки ), желательно несколько раз.
Происходит следующее:
1) Тянем ползунок, функция _Wnd_Proc повисает пока не отпустим клавишу ( работает стандартный обработчик CallWindowProc ).
2) Отпускаем ползунок, обработчик освобождает выполнение и мой завершается.
3) И тут начинается самое веселое: В тот момент, когда мы тянули ползунок - сообщения о перерисовке окна должен был принимать CallBack, однако AutoIt их не вызывает до тех пор, пока не завершит работу CallWindowProc.
4) После завершения работы CallWindowProc он оставляет ( предыдущие вызовы ) у себя в памяти, а самое странное -
не выполняет их.
5) При получении нового вызова - он выполняет не его, а первый в порядке приоритета из повисших!
Схема ( как видно - происходит сдвиг в вызове, зачем их AutoIt вообще коллекционирует? ):
Код:
1>>Кнопка мыши зажата на ползунке ( ПРИНЯТО ).
2>>Ползунок сдвинут, перерисовать окно ( НЕ ПРИНЯТО ).
3>>Ползунок сдвинут, перерисовать окно ( НЕ ПРИНЯТО ).
4>> Кнопку мыши отпустили ( ПРИНЯТО "2" )
5>>Сообщение любому другому элементу ( ПРИНЯТО "3" )
Может у кого есть идеи как можно совместить все обработчики и заставить их корректно отрабатывать?
*Для контрола и окна отдельные Callback функции не решают проблему.
*GUICreate ( внутренний обработчик AutoIt ) решает проблему, но к сожалению ее использование не допускается.
Код:
#include <GuiEdit.au3>
#include <WinAPIEx.au3>
#include <APIConstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
Global $fExit, $WndHandle, $hCtrl_DbgEdit, $sText, _
$iWndW = 220, $iWndX = ( @DesktopWidth / 2 ) - ( $iWndW / 2 ), _
$iWndH = 260, $iWndY = ( @DesktopHeight/ 2 ) - ( $iWndH / 2 )
For $Idx = 1 To 999 Step 1
$sText &= "Line" & $Idx & @CRLF
Next
$User32Dll = DllOpen( 'user32.dll' )
$hModule = _WinAPI_GetModuleHandle( 0 )
$hFont = _WinAPI_GetStockObject( 17 )
$hBrush = _WinAPI_CreateSolidBrush( 0xeeeeee )
$hCursor = _WinAPI_LoadCursor( 0, 32512 )
$hWndProc = DllCallbackRegister( '_Wnd_Proc', 'lresult', 'hwnd;uint;wparam;lparam' )
; *
$sClass = "ExampleClass"
$sName = "ExampleName"
; ---
$tClass = DllStructCreate( 'wchar[' & StringLen( $sClass ) + 1 & ']' )
DllStructSetData( $tClass, 1, $sClass )
$tWndClassEx = DllStructCreate( $tagWNDCLASSEX )
DllStructSetData( $tWndClassEx, 'Size', DllStructGetSize( $tWndClassEx ) )
DllStructSetData( $tWndClassEx, 'Style', 0 )
DllStructSetData( $tWndClassEx, 'hWndProc', DllCallbackGetPtr( $hWndProc ) )
DllStructSetData( $tWndClassEx, 'ClsExtra', 0 )
DllStructSetData( $tWndClassEx, 'WndExtra', 0 )
DllStructSetData( $tWndClassEx, 'hInstance', $hModule )
DllStructSetData( $tWndClassEx, 'hIcon', 0 )
DllStructSetData( $tWndClassEx, 'hCursor', $hCursor )
DllStructSetData( $tWndClassEx, 'hBackground', $hBrush )
DllStructSetData( $tWndClassEx, 'MenuName', 0 )
DllStructSetData( $tWndClassEx, 'ClassName', DllStructGetPtr( $tClass ) )
DllStructSetData( $tWndClassEx, 'hIconSm', 0 )
; *
DllCall( $User32Dll, 'dword', 'RegisterClassExW', 'ptr', DllStructGetPtr( $tWndClassEx ) )
$WndHandle = DllCall( $User32Dll, 'hwnd', 'CreateWindowExW', 'dword', 0x00050181, 'wstr', $sClass, 'str', $sName, 'dword', 0x94CB00CC, _
'int', $iWndX, 'int', $iWndY, 'int', $iWndW, 'int', $iWndH, 'hwnd', 0, 'hwnd', 0, 'hwnd', $hModule, 'ptr', 0 )
$WndHandle = $WndHandle[0]
$hCtrl_DbgEdit = _WinAPI_CreateWindowEx( 0x00000200, "Edit", "", 0x50210844, 5, 5, 205, 225, $WndHandle, 10000 )
$hCtrl_DefProc = _WinAPI_SetWindowLong( $hCtrl_DbgEdit, $GWL_WNDPROC, DllCallbackGetPtr( $hWndProc ) )
_WndEdit_AppendText( $hCtrl_DbgEdit, $sText )
While Not $fExit And Sleep( 10 )
WEnd
; < Cleanup
_WinAPI_DestroyWindow( $hCtrl_DbgEdit )
_Wnd_Proc( $WndHandle, $WM_CLOSE, 1, 1 )
_WinAPI_DestroyCursor( $hCursor )
DllCall( $User32Dll, 'dword', 'UnregisterClassW', 'wstr', $sClass, 'ptr', $hModule )
DllCallbackFree( $hWndProc )
Func _Wnd_Proc($hWnd, $iMsg, $wParam, $lParam)
Switch $hWnd
Case $WndHandle
Switch $iMsg
Case $WM_CLOSE
If Not $wParam Or Not $lParam Then
$fExit = True
Return
Else
$wParam = 0
$lParam = 0
EndIf
EndSwitch
Case $hCtrl_DbgEdit
Return _WinAPI_CallWindowProc( $hCtrl_DefProc, $hWnd, $iMsg, $wParam, $lParam )
EndSwitch
Return _WinAPI_DefWindowProc($hWnd, $iMsg, $wParam, $lParam)
EndFunc
Func _WndEdit_AppendText( $hWnd, $sText )
Local $iLength = _SendMessage( $hWnd, 0x000E ) ;WM_GETTEXTLENGTH
; ---
_SendMessage( $hWnd, $EM_SETSEL, $iLength, $iLength )
_SendMessage( $hWnd, $EM_REPLACESEL, True, $sText & @CRLF, 0, "wparam", "wstr" )
EndFunc ;==>_GUICtrlEdit_AppendText
P.S. Есть идея:
1)Ставить хук $WH_CALLWNDPROC
2)Фильтровать на нужные сообщения
3)Если сообщения подходят - ставить контролу свой обработчик
4)CallNextHook
5)Ловить это сообщение в обработчике
5-1)Вернуть стандартный обработчик
5-2)Сделать необходимые действия.
Но сами понимаете - такие дебри я буду использовать в последнюю очередь, надеюсь на вашу помощь.