Что нового

Autoscroll для компонента Edit программы чата

S1R1US

скрипт мне запили!
Сообщения
50
Репутация
6
Собрал клиент для локального мессенджера, но не работает поле автопрокрутки чата, текст появляется, но при этом чат не проматывается вниз, когда приходит/посылается новое сообщение...плз подскажите где я недоглядел.
Код клиента:
Код:
#RequireAdmin
#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.8.0
 Author:         S1R1US[B.S.]

 Script Function:
	Messenger Client.

#ce ----------------------------------------------------------------------------
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#NoTrayIcon

$g_IP = InputBox("Messenger Client","Введите адрес сервера",@IPADDRESS1,"",340,500) ; конфигурируем вход на сервер
$g_port = 33891 ; открываем сокет для передачи данных

; Запуск TCP службы
;==============================================
TCPStartUp()

; Подключение к сокету сервера
;==============================================
$socket = TCPConnect( $g_IP, $g_port )
If $socket = -1 Then Exit

Opt("TrayOnEventMode",1) ; трей в режиме событий
Opt("TrayMenuMode",1)   ; нестандартное меню отображения трея

$GOOEY = GUICreate("messenger - " & @ComputerName, 340, 500)  ; создаем гуй
GUISetOnEvent ($GUI_EVENT_MINIMIZE, "_Hide") ; назначаем кнопку свернуть кнопкой сворачивания в трей
$input = GUICtrlCreateInput ("", 20, 430, 300, 20)
$edit = GUICtrlCreateEdit ("", 20, 20, 300, 400, $ES_AUTOVSCROLL + $WS_VSCROLL + $ES_NOHIDESEL + $ES_WANTRETURN + $ES_READONLY)
GUICtrlSendMsg(-1, $EM_LIMITTEXT, -1, 0) ; снимает ограничение на количество символов 30 000
$otpravka = GUICtrlCreateButton("Отправить", 20, 460, 70, 30)
GUICtrlSetOnEvent($otpravka, "_SEND")
GUICtrlSetTip ($otpravka, "Отправить ваше сообщение")
$ochistka = GUICtrlCreateButton("Очистить", 90, 460, 70, 30)
GUICtrlSetOnEvent($ochistka, "_CLEAR")
GUICtrlSetTip ($ochistka, "Очистить чат")
TraySetClick(16)    ; трей вызывается правой кнопкой мыши

$showitem = TrayCreateItem("Показать")
TrayItemSetOnEvent($showitem,"_Show")

TrayCreateItem("")

$hideitem = TrayCreateItem("Скрыть")
TrayItemSetOnEvent($hideitem,"_Hide")

TrayCreateItem("")

$exititem = TrayCreateItem("Выход")
TrayItemSetOnEvent($exititem,"_Exit")

TraySetState()
TraySetToolTip("Messeger - для входа в меню нажмите правой кнопкой")

$dummywindow = GUICreate("", 200, 100)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

GUISwitch($GOOEY)
GUISetState(@SW_SHOW)

GUICtrlSetData ($edit, "",1); вставить начальную строку в поле Edit
GUICtrlSetData ($input, "Status Online",1); вставить начальную строку в поле Edit чата
GUICtrlSetState ($otpravka, $GUI_DEFBUTTON); установка кнопки Отправить кнопкой по умолчанию

; Гуй в режиме сообщений
;==============================================
While 1
   $msg = GUIGetMsg()
   ; закрыть гуй
   ;---------------------------------------
   If $msg = $GUI_EVENT_CLOSE Then
	ToolTip("messenger by S1R1US[B.S.] - выходим...",0,0,"Завершение работы")
	Sleep(2000)
    ExitLoop
	EndIf
   ; свернуть гуй
   ;---------------------------------------
   If $msg = $GUI_EVENT_MINIMIZE Then
	GUISetState(@SW_HIDE)
	EndIf
   ; Нажатие клавиши Отправить
   ;---------------------------------------
   If $msg = $otpravka Then
	$ret = TCPSend($socket, @ComputerName & ": " & GUICtrlRead($input))
	If @ERROR Then
	WinSetTitle($GOOEY,"","Ошибка отправки")
	Sleep(2000)
	ExitLoop
	EndIf
	; Сервер отключен -> выход
    ;---------------------------------------
   If $ret > 0 Then GUICtrlSetData($edit, GUICtrlRead($edit) & GUICtrlRead($input) & @CRLF)
	GUICtrlSetData($input,"")
   EndIf
   $recv = TCPRecv($socket, 8192)
   $err = @error
   If $recv = "~~bye" Then
    GUICtrlSetData($edit, GUICtrlRead($edit) & "~~Connection Lost" & @CRLF)
    WinSetTitle($GOOEY,"","Соединение сброшено")
    Sleep(2000)
	ExitLoop
   EndIf
   If $err <> 0 Then ExitLoop
   ; Сервер отключен -> выход
   ;---------------------------------------
   If $err=0 AND $recv <> "" Then GUICtrlSetData($edit, GUICtrlRead($edit) & ">" & $recv & @CRLF)
WEnd

Func _Hide() ; функция сворачивания
	GUISetState(@SW_HIDE)
EndFunc

Func _Show() ; функция отображения скрытого окна
	GUISetState(@SW_SHOW)
	Sleep(300)
	GUISetState(@SW_RESTORE)
EndFunc

Func _Exit()
    ToolTip("messenger by S1R1US[B.S.] - выходим...",0,0,"Завершение работы")
	Sleep(2000)
    Exit
EndFunc


Код сервера (взят со справки):
Код:
#RequireAdmin
#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.8.0
 Author:         myName

 Script Function:
	Template AutoIt script.

#ce ----------------------------------------------------------------------------
;SERVER!! Start Me First !!!!!!!!!!!!!!!
#include <GUIConstants.au3>

; Initialize a variable to represent a connection
;==============================================
Global $MainSocket, $ConnectedSocket = -1
Global $g_IP = @IPADDRESS1
Global $g_port = 33891

; Start The TCP Services
;==============================================
TCPStartUp()

; Create a Listening "SOCKET"
;==============================================
$MainSocket = TCPListen($g_IP, $g_port,  100 )
If $MainSocket = -1 Then Exit
$RogueSocket = -1

; Create a GUI for chatting
;==============================================
$GOOEY = GUICreate("messenger Admin - " & @ComputerName,350,200,@DesktopWidth/2+100,@DesktopHeight/2-350)
$edit = GUICtrlCreateEdit("",10,40,330,150)
$input = GUICtrlCreateInput("",10,10,250,20)
$butt = GUICtrlCreateButton("Send",260,10,80,20)
GUISetState()

; GUI Message Loop
;==============================================
While 1
   $msg = GUIGetMsg()

   ; GUI Closed
   ;--------------------
   If $msg = $GUI_EVENT_CLOSE Then ExitLoop

   ; User Pressed SEND
   ;--------------------
   If $msg = $butt Then
      If $ConnectedSocket > -1 Then
         $ret = TCPSend( $ConnectedSocket, GUICtrlRead($input))
         If @ERROR Then
            ; ERROR OCCURRED, CLOSE SOCKET AND RESET ConnectedSocket to -1
            ;----------------------------------------------------------------
            TCPCloseSocket( $ConnectedSocket )
            WinSetTitle($GOOEY,"","Server " & @ComputerName)
            $ConnectedSocket = -1
         ElseIf $ret > 0 Then
            ; UPDATE EDIT CONTROL WITH DATA WE SENT
            ;----------------------------------------------------------------
            GUICtrlSetData($edit, GUICtrlRead($edit) & GUICtrlRead($input) & @CRLF )
         EndIf
      EndIf
      GUICtrlSetData($input,"")
   EndIf

   If $RogueSocket > 0 Then
      $recv = TCPRecv( $RogueSocket, 512 )
      If NOT @error Then
         TCPCloseSocket( $RogueSocket )
         $RogueSocket = -1
      EndIf
   EndIf

   ; If no connection look for one
   ;--------------------
   If $ConnectedSocket = -1 Then
      $ConnectedSocket = TCPAccept( $MainSocket)
      If $ConnectedSocket >= 0 Then
          WinSetTitle($GOOEY,"","Server Running" & @ComputerName)
      EndIf

   ; If connected try to read some data
   ;--------------------
   Else
      ; EXECUTE AN UNCONDITIONAL ACCEPT IN CASE ANOTHER CLIENT TRIES TO CONNECT
      ;----------------------------------------------------------------
      $RogueSocket = TCPAccept( $MainSocket)
      If $RogueSocket > 0 Then
          TCPSend( $RogueSocket, "~~rejected" )
      EndIf

      $recv = TCPRecv( $ConnectedSocket, 512 )

      If $recv <> "" And $recv <> "~~bye" Then
         ; UPDATE EDIT CONTROL WITH DATA WE RECEIVED
         ;----------------------------------------------------------------
         GUICtrlSetData($edit, GUICtrlRead($edit) & ">" & $recv & @CRLF)

      ElseIf @error Or $recv = "~~bye" Then
         ; ERROR OCCURRED, CLOSE SOCKET AND RESET ConnectedSocket to -1
         ;----------------------------------------------------------------
         WinSetTitle($GOOEY,"","server Online " & @IPADDRESS1)
         TCPCloseSocket( $ConnectedSocket )
         $ConnectedSocket = -1
      EndIf
   EndIf
WEnd

GUIDelete($GOOEY)

Func OnAutoItExit()
   ;ON SCRIPT EXIT close opened sockets and shutdown TCP service
   ;----------------------------------------------------------------------
   If $ConnectedSocket > -1 Then
      TCPSend( $ConnectedSocket, "~~bye" )
      Sleep(2000)
      TCPRecv( $ConnectedSocket,  512 )
      TCPCloseSocket( $ConnectedSocket )
   EndIf
   TCPCloseSocket( $MainSocket )
   TCPShutDown()
EndFunc

Func SOCKET2IP($SHOCKET)
Local $sockaddr = DLLStructCreate("short;ushort;uint;char[8]")

   $a = DLLCall("Ws2_32.dll","int","getpeername","int",$SHOCKET,"ptr",DLLStructGetPtr($sockaddr), _
                                            "int_ptr",DLLStructGetSize($sockaddr))
   If Not @error And $a[0] = 0 Then
      $a = DLLCall("Ws2_32.dll","str","inet_ntoa","int",DLLStructGetData($sockaddr,3))
      If Not @error Then $a = $a[0]
   Else
      $a = 0
   EndIf

    ; release Struct not really needed as it is a local
   $sockaddr = 0

   Return $a
EndFunc
 
Автор
S

S1R1US

скрипт мне запили!
Сообщения
50
Репутация
6
firex
Проблема в том, что я не знаю как и куда прикрутить эту функцию, а также какую UDF для неё использовать.

Думалось, что проще было бы реализовать нечто вроде:
Код:
ControlFocus($Gui, "", $Edit)
ControlSend($Gui, "", $Edit, "^{END}")
GUICtrlSetData($Edit, $Data, 1)

Но я не могу интегрировать это в мой код, т. к. идёт пересылка по сокету. А не через
Код:
ControlSend
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
Код:
GUICtrlSetData($edit, GUICtrlRead($edit) & "~~Connection Lost" & @CRLF)

Подобные вещи заменяй на:

Код:
_GUICtrlEdit_AppendText($edit,"~~Connection Lost" & @CRLF )

А еще лучше сделай для этого отдельную функцию, скажем вот так:
Код:
Func _FxB_LogPrint($iMsg)
   _GUICtrlEdit_AppendText($hEdit[2], $iMsg & @CRLF)
EndFunc

(пример из своего чата)
 
Автор
S

S1R1US

скрипт мне запили!
Сообщения
50
Репутация
6
firex
Во наконец то руки дошли) сделал всё заработало. Спасибо! :IL_AutoIt_1:
 
Верх