Что нового

Функция "прокрутки" текста в label

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Версия AutoIt: 3.3.12.0

Описание: Нужна функция для эмуляции прокручивания текста(лог событий) в элементе label колесом мыши.

В элементе label видно только 2 строки, высота элемента 34.
Функция должна уметь добавлять новую строчку, которая появится снизу, предыдущаяя строка должна вставь сверху, а также должна уметь менять эти две строчки, при прокрутки колесом.

Вот примерно так, в рамке выделено то, что видно на экране.

строка1
строка2
|строка3|
|строка4|
строка5

если прокуртить вниз, то должно быть видно это:
строка1
строка2
строка3
|строка4|
|строка5|

Если вверх, то это:
строка1
|строка2|
|строка3|
строка4
строка5

Примечание: Форма Opt("GUIOnEventMode", 1)
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
CreatoR
Там можно добавлять текст динамически?
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
inververs [?]
Там можно добавлять текст динамически?
Пока что нет, также как и создание более одного элемента.
Попробую решить эти недостатки...
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
Держи, если удовлетворит - допишу.

Код:
#include-Once

Global Const $__CTRLLABEL_LIMIT = 99
; *
Global $_aCtrlLabel[$__CTRLLABEL_LIMIT + 1][6], $_fProc
; #######

#Region Example
$hGui = GUICreate( "Test", 150, 100, -1, -1 )
GUISetState( @SW_SHOW )
$sTextLabel = ''
For $Idx = 1 To 50 Step 1
	$sTextLabel &= "TEST" & $Idx & @CRLF
Next
$iLabel = _GUICtrlLabel_Create( $sTextLabel, 4, 5, 5, 100, 90 )
	GUICtrlSetBkColor( $iLabel, 0xff0000 )

While Sleep( 10 )
	Switch GUIGetMsg()
		Case -3
			ExitLoop
	EndSwitch
WEnd
#EndRegion Example

Func _GUICtrlLabel_Create( $sText, $iLines, $iX, $iY, $iW, $iH, $iStyle = Default, $iExStyle = Default )
	Local $Idx = __CtrlLabel_FindFree()
	; ---
	If $Idx >= 0 Then
		If Not $_fProc Then
			GUIRegisterMsg( 0x020A, "__CtrlLabel_Proc" ) ;WM_MOUSEWHEEL
			$_fProc = True
		EndIf
		; *
		$_aCtrlLabel[0][0] = $Idx - 1
		$_aCtrlLabel[$Idx][0] = GUICtrlCreateLabel( '', $iX, $iY, $iW, $iH, $iStyle, $iExStyle )
		$_aCtrlLabel[$Idx][1] = GUICtrlGetHandle( $_aCtrlLabel[$Idx][0] )
		$_aCtrlLabel[$Idx][2] = 0
		$_aCtrlLabel[$Idx][3] = $iLines
		$_aCtrlLabel[$Idx][4] = True
		If $sText Then _
			_GUICtrlLabel_AddText( $_aCtrlLabel[$Idx][0], $sText )
		; ---
		Return $_aCtrlLabel[$Idx][0]
	EndIf
	; ---
	Return SetError( 1, 0, 0 )
EndFunc ; << _GUICtrlLabel_Create

Func _GUICtrlLabel_Destroy( $iCtrl )
	Local $Idx = __CtrlLabel_FindMe( $iCtrl )
	; *
	If $Idx < 0 Then Return SetError( 1, 0, False )
	; ---
	GUICtrlDelete( $_aCtrlLabel[$Idx][0] )
		$_aCtrlLabel[$Idx][0] = 0
		$_aCtrlLabel[$Idx][5] = ''
	; ---
	Return True
EndFunc ; << _GUICtrlLabel_Destroy

Func _GUICtrlLabel_SetText( $iCtrl, $sText )
	Local $Idx = __CtrlLabel_FindMe( $iCtrl )
	; *
	If $Idx < 0 Then Return SetError( 1, 0, False )
	; ---
	$_aCtrlLabel[$Idx][2] = 0
	$_aCtrlLabel[$Idx][5] = ''
	Return __CtrlLabel_AddText( $Idx, $sText, 0 )
EndFunc ; << _GUICtrlLabel_SetText

Func _GUICtrlLabel_AddText( $iCtrl, $sText, $iLine = -1 )
	Local $Idx = __CtrlLabel_FindMe( $iCtrl )
	; *
	If $Idx < 0 Then Return SetError( 1, 0, False )
	; ---
	Return __CtrlLabel_AddText( $Idx, $sText, $iLine )
EndFunc ; << _GUICtrlLabel_AddText

Func _GUICtrlLabel_GetText( $iCtrl )
	Local $Idx = __CtrlLabel_FindMe( $iCtrl )
	; *
	If $Idx < 0 Then Return SetError( 1, 0, False )
	; ---
	Return $_aCtrlLabel[$Idx][5]
EndFunc ; << _GUICtrlLabel_GetText

Func _GUICtrlLabel_Scroll( $iCtrl, $iLine = 1 )
	Local $Idx = __CtrlLabel_FindMe( $iCtrl )
	; *
	If $Idx < 0 Then Return SetError( 2, 0, False )
	; ---
	Return __CtrlLabel_Scroll( $Idx, $iLine )
EndFunc ; << _GUICtrlLabel_Scroll

Func _GUICtrlLabel_EnableScroll( $iCtrl, $fState = True )
	Local $Idx = __CtrlLabel_FindMe( $iCtrl )
	; *
	If $Idx < 0 Then Return SetError( 1, 0, False )
	; ---
	$_aCtrlLabel[$Idx][4] = $fState
	Return True
EndFunc ; << _GUICtrlLabel_EnableScroll



;### INTERNAL USE ONLY!
; ===========================
Func __CtrlLabel_Proc( $hWnd, $iMsg, $wParam, $lParam )
	Switch $iMsg
		Case 0x020A ;WM_MOUSEWHEEL
			Local $iDelta = BitShift($wParam, 16), _
				$aCursor = GUIGetCursorInfo(), $Idx
			; -
			If IsArray( $aCursor ) And $aCursor[4] Then
				$Idx = __CtrlLabel_FindMe( $aCursor[4] )
				If $_aCtrlLabel[$Idx][4] Then ;ScrollEnabled
					Switch $iDelta
						Case 120
							__CtrlLabel_Scroll( $Idx, $_aCtrlLabel[$Idx][2] - 1 )
						Case -120
							__CtrlLabel_Scroll( $Idx, $_aCtrlLabel[$Idx][2] + 1 )
					EndSwitch
				EndIf
			EndIf
	EndSwitch
	; ---
	Return 'GUI_RUNDEFMSG'
EndFunc

Func __CtrlLabel_AddText( $Idx, $sText, $iLine ) ;$iLine=[ < 0:End], [0 Or 1:Begin], [Else:LineIdx]
	Local $Line, $aNewText, $aOldText, $iSize
	; ---
	$aNewText = StringSplit( StringStripCR( $sText ), @LF )
	If $aNewText[0] Then
		If Not IsArray( $_aCtrlLabel[$Idx][5] ) Then
			$_aCtrlLabel[$Idx][5] = $aNewText
		Else
			$aOldText = $_aCtrlLabel[$Idx][5]
			$iSize = $aOldText[0] + $aNewText[0]
			; *
			Local $aTmpText[$iSize + 1] = [$iSize]
			For $Line = 1 To $aTmpText[0] Step 1
				Switch $iLine
					Case 0, 1
						If $Line > $aNewText[0] Then
							$aTmpText[$Line] = $aOldText[$Line - $aNewText[0]]
						Else
							$aTmpText[$Line] = $aNewText[$Line]
						EndIf
					Case 2 To $aOldText[0]



					Case Else ;Default:End
						If $Line > $aOldText[0] Then
							$aTmpText[$Line] = $aNewText[$Line - $aOldText[0]]
						Else
							$aTmpText[$Line] = $aOldText[$Line]
						EndIf
				EndSwitch
			Next
			; *
			$_aCtrlLabel[$Idx][5] = $aTmpText
		EndIf
		If Not $_aCtrlLabel[$Idx][2] Then _
			Return __CtrlLabel_Scroll( $Idx, 1 )
		; ---
		Return True
	EndIf
	; ---
	Return False
EndFunc

Func __CtrlLabel_Scroll( $Idx, $iLine )
	Local $Line, $iEnd, $sText, $aText
	; ---
	$aText = $_aCtrlLabel[$Idx][5]
	If IsArray( $aText ) Then
		Switch $iLine
			Case 0
				$iLine = 1
				ContinueCase
			Case 1 To $aText[0]
				$Line = $iLine
				$iEnd = $iLine + $_aCtrlLabel[$Idx][3] - 1
				If $iEnd > $aText[0] Then
					$Line -= $iEnd - $aText[0]
					$iEnd = $aText[0]
					If $Line < 1 Then _
						$Line = 1
				EndIf
			Case Else ;Default:End
				$Line = $aText[0] - $_aCtrlLabel[$Idx][3] + 1
				$iEnd = $aText[0]
				If $Line < 1 Then _
					$Line = 1
		EndSwitch
		; ---
		If $_aCtrlLabel[$Idx][2] <> $Line Then
			$_aCtrlLabel[$Idx][2] = $Line
			For $Line = $Line To $iEnd Step 1
				$sText &= $aText[$Line]
				If $Line < $iEnd Then _
					$sText &= @CRLF
			Next
			Return GUICtrlSetData( $_aCtrlLabel[$Idx][0], $sText )
		EndIf
		Return True
	EndIf
	; ---
	Return SetError( 1, 0, False )
EndFunc

Func __CtrlLabel_FindMe( $iCtrl = 0, $hWnd = 0 )
	Local $Idx
	; ---
	For $Idx = 0 To $__CTRLLABEL_LIMIT Step 1
		If ( $iCtrl And $_aCtrlLabel[$Idx][0] == $iCtrl ) Or ( $hWnd And $_aCtrlLabel[$Idx][1] = $hWnd ) Then
			Return $Idx
		ElseIf Not $_aCtrlLabel[$Idx][1] Then
			ExitLoop
		EndIf
	Next
	; ---
	Return SetError( 1, 0, -1 )
EndFunc

Func __CtrlLabel_FindFree()
	Local $Idx
	; ---
	For $Idx = 0 To $__CTRLLABEL_LIMIT Step 1
		If Not $_aCtrlLabel[$Idx][0] Then _
			Return $Idx
	Next
	; ---
	Return SetError( 1, 0, -1 )
EndFunc
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
firex
Да, кажется оно! Еще особо не тестировал, запустил, проверил, текст скролится так как нужно. Отлично!
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
Код:
#include-Once

Global Const $__CTRLLABEL_LIMIT = 99
; *
Global $_aCtrlLabel[$__CTRLLABEL_LIMIT + 1][6], $_fProc
; #######

Func _GUICtrlLabel_Create( $sText, $iLines, $iX, $iY, $iW, $iH, $iStyle = Default, $iExStyle = Default )
	Local $Idx = __CtrlLabel_FindFree()
	; ---
	If $Idx >= 0 Then
		If Not $_fProc Then
			GUIRegisterMsg( 0x020A, "__CtrlLabel_Proc" ) ;WM_MOUSEWHEEL
			$_fProc = True
		EndIf
		; *
		$_aCtrlLabel[0][0] = $Idx - 1
		$_aCtrlLabel[$Idx][0] = GUICtrlCreateLabel( '', $iX, $iY, $iW, $iH, $iStyle, $iExStyle )
		$_aCtrlLabel[$Idx][1] = GUICtrlGetHandle( $_aCtrlLabel[$Idx][0] )
		$_aCtrlLabel[$Idx][2] = 0
		$_aCtrlLabel[$Idx][3] = $iLines
		$_aCtrlLabel[$Idx][4] = True
		If $sText Then _
			_GUICtrlLabel_AddText( $_aCtrlLabel[$Idx][0], $sText )
		; ---
		Return $_aCtrlLabel[$Idx][0]
	EndIf
	; ---
	Return SetError( 1, 0, 0 )
EndFunc ; << _GUICtrlLabel_Create

Func _GUICtrlLabel_Destroy( $iCtrl )
	Local $Idx = __CtrlLabel_FindMe( $iCtrl )
	; *
	If $Idx < 0 Then Return SetError( 1, 0, False )
	; ---
	GUICtrlDelete( $_aCtrlLabel[$Idx][0] )
		$_aCtrlLabel[$Idx][0] = 0
		$_aCtrlLabel[$Idx][5] = ''
	; ---
	Return True
EndFunc ; << _GUICtrlLabel_Destroy

Func _GUICtrlLabel_SetText( $iCtrl, $sText )
	Local $Idx = __CtrlLabel_FindMe( $iCtrl )
	; *
	If $Idx < 0 Then Return SetError( 1, 0, False )
	; ---
	$_aCtrlLabel[$Idx][2] = 0
	$_aCtrlLabel[$Idx][5] = ''
	Return __CtrlLabel_AddText( $Idx, $sText, 0 )
EndFunc ; << _GUICtrlLabel_SetText

Func _GUICtrlLabel_AddText( $iCtrl, $sText, $iLine = -1 )
	Local $Idx = __CtrlLabel_FindMe( $iCtrl )
	; *
	If $Idx < 0 Then Return SetError( 1, 0, False )
	; ---
	Return __CtrlLabel_AddText( $Idx, $sText, $iLine )
EndFunc ; << _GUICtrlLabel_AddText

Func _GUICtrlLabel_GetText( $iCtrl )
	Local $Idx = __CtrlLabel_FindMe( $iCtrl )
	; *
	If $Idx < 0 Then Return SetError( 1, 0, False )
	; ---
	Return $_aCtrlLabel[$Idx][5]
EndFunc ; << _GUICtrlLabel_GetText

Func _GUICtrlLabel_Scroll( $iCtrl, $iLine = 1 )
	Local $Idx = __CtrlLabel_FindMe( $iCtrl )
	; *
	If $Idx < 0 Then Return SetError( 2, 0, False )
	; ---
	Return __CtrlLabel_Scroll( $Idx, $iLine )
EndFunc ; << _GUICtrlLabel_Scroll

Func _GUICtrlLabel_EnableScroll( $iCtrl, $fState = True )
	Local $Idx = __CtrlLabel_FindMe( $iCtrl )
	; *
	If $Idx < 0 Then Return SetError( 1, 0, False )
	; ---
	$_aCtrlLabel[$Idx][4] = $fState
	Return True
EndFunc ; << _GUICtrlLabel_EnableScroll



;### INTERNAL USE ONLY!
; ===========================
Func __CtrlLabel_Proc( $hWnd, $iMsg, $wParam, $lParam )
	Switch $iMsg
		Case 0x020A ;WM_MOUSEWHEEL
			Local $iDelta = BitShift($wParam, 16), _
				$aCursor = GUIGetCursorInfo(), $Idx
			; -
			If IsArray( $aCursor ) And $aCursor[4] Then
				$Idx = __CtrlLabel_FindMe( $aCursor[4] )
				If $_aCtrlLabel[$Idx][4] Then ;ScrollEnabled
					Switch $iDelta
						Case 120
							__CtrlLabel_Scroll( $Idx, $_aCtrlLabel[$Idx][2] - 1 )
						Case -120
							__CtrlLabel_Scroll( $Idx, $_aCtrlLabel[$Idx][2] + 1 )
					EndSwitch
				EndIf
			EndIf
	EndSwitch
	; ---
	Return 'GUI_RUNDEFMSG'
EndFunc

Func __CtrlLabel_AddText( $Idx, $sText, $iLine ) ;$iLine=[ < 0:End], [0 Or 1:Begin], [Else:LineIdx]
	Local $Line, $aNewText, $aOldText, $iSize
	; ---
	$aNewText = StringSplit( StringStripCR( $sText ), @LF )
	If $aNewText[0] Then
		If Not IsArray( $_aCtrlLabel[$Idx][5] ) Then
			$_aCtrlLabel[$Idx][5] = $aNewText
		Else
			$aOldText = $_aCtrlLabel[$Idx][5]
			$iSize = $aOldText[0] + $aNewText[0]
			; *
			Local $aTmpText[$iSize + 1] = [$iSize]
			For $Line = 1 To $aTmpText[0] Step 1
				Switch $iLine
					Case 0, 1
						If $Line > $aNewText[0] Then
							$aTmpText[$Line] = $aOldText[$Line - $aNewText[0]]
						Else
							$aTmpText[$Line] = $aNewText[$Line]
						EndIf
					Case 2 To $aOldText[0]
						Select
							Case $Line < $iLine
								$aTmpText[$Line] = $aOldText[$Line]
							Case $Line >= $iLine And $Line < $iLine + $aNewText[0]
								$aTmpText[$Line] = $aNewText[$Line-$iLine+1]
							Case Else
								$aTmpText[$Line] = $aOldText[$Line-$aNewText[0]]
						EndSelect
					Case Else ;Default:End
						If $Line > $aOldText[0] Then
							$aTmpText[$Line] = $aNewText[$Line - $aOldText[0]]
						Else
							$aTmpText[$Line] = $aOldText[$Line]
						EndIf
				EndSwitch
			Next
			; *
			$_aCtrlLabel[$Idx][5] = $aTmpText
		EndIf
		If Not $_aCtrlLabel[$Idx][2] Then _
			$_aCtrlLabel[$Idx][2] = 1
		; ---
		Return __CtrlLabel_Scroll( $Idx, $_aCtrlLabel[$Idx][2], True )
	EndIf
	; ---
	Return False
EndFunc

Func __CtrlLabel_Scroll( $Idx, $iLine, $fRefresh = False )
	Local $Line, $iEnd, $sText, $aText
	; ---
	$aText = $_aCtrlLabel[$Idx][5]
	If IsArray( $aText ) Then
		Switch $iLine
			Case 0
				$iLine = 1
				ContinueCase
			Case 1 To $aText[0]
				$Line = $iLine
				$iEnd = $iLine + $_aCtrlLabel[$Idx][3] - 1
				If $iEnd > $aText[0] Then
					$Line -= $iEnd - $aText[0]
					$iEnd = $aText[0]
					If $Line < 1 Then _
						$Line = 1
				EndIf
			Case Else ;Default:End
				$Line = $aText[0] - $_aCtrlLabel[$Idx][3] + 1
				$iEnd = $aText[0]
				If $Line < 1 Then _
					$Line = 1
		EndSwitch
		; ---
		If $_aCtrlLabel[$Idx][2] <> $Line Or $fRefresh Then
			$_aCtrlLabel[$Idx][2] = $Line
			For $Line = $Line To $iEnd Step 1
				$sText &= $aText[$Line]
				If $Line < $iEnd Then _
					$sText &= @CRLF
			Next
			Return GUICtrlSetData( $_aCtrlLabel[$Idx][0], $sText )
		EndIf
		Return True
	EndIf
	; ---
	Return SetError( 1, 0, False )
EndFunc

Func __CtrlLabel_FindMe( $iCtrl = 0, $hWnd = 0 )
	Local $Idx
	; ---
	For $Idx = 0 To $__CTRLLABEL_LIMIT Step 1
		If ( $iCtrl And $_aCtrlLabel[$Idx][0] == $iCtrl ) Or ( $hWnd And $_aCtrlLabel[$Idx][1] = $hWnd ) Then
			Return $Idx
		ElseIf Not $_aCtrlLabel[$Idx][1] Then
			ExitLoop
		EndIf
	Next
	; ---
	Return SetError( 1, 0, -1 )
EndFunc

Func __CtrlLabel_FindFree()
	Local $Idx
	; ---
	For $Idx = 0 To $__CTRLLABEL_LIMIT Step 1
		If Not $_aCtrlLabel[$Idx][0] Then _
			Return $Idx
	Next
	; ---
	Return SetError( 1, 0, -1 )
EndFunc


Дописал функцию _GUICtrlLabel_AddText. Вроде как все.
 
Верх