#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon= ;程序图标
#AutoIt3Wrapper_UseX64=n ;是否编译为64位程序(y/n)
#AutoIt3Wrapper_OutFile= ;输出的Exe名称
#AutoIt3Wrapper_OutFile_x64= ;64位输出的Exe名称
#AutoIt3Wrapper_UseUpx=n ;是否使用UPX压缩(y/n) 注:开启压缩极易引起误报问题
#AutoIt3Wrapper_Res_Comment=http://www.autoitscript.com/autoit3/ ;程序注释
#AutoIt3Wrapper_Res_Description=AutoIt Team ;文件说明
#AutoIt3Wrapper_Res_Fileversion=1.0.0.40
#AutoIt3Wrapper_Res_Field=Productname|AutoIt v3 ;产品名称
#AutoIt3Wrapper_Res_ProductVersion=1.0 ;产品版本
#AutoIt3Wrapper_Res_LegalCopyright=©1999-2021 AutoIt Team ;版权
#AutoIt3Wrapper_Res_Language=2052 ;语言, 英语=2057/中文=2052
#AutoIt3Wrapper_Res_Field=OriginalFilename|AutoIt.exe ;原始文件名
#AutoIt3Wrapper_Res_Field=InternalName|AutoIt_exe ;内部名称
#AutoIt3Wrapper_Res_FileVersion_AutoIncrement=y ;自动更新版本 y/n/p=自动/不自动/询问
#AutoIt3Wrapper_Res_RequestedExecutionLevel=asInvoker ;请求权限: None/asInvoker/highestAvailable/requireAdministrator
#AutoIt3Wrapper_Run_Tidy=n ;编译前自动整理脚本(y/n)
#AutoIt3Wrapper_Res_HiDpi=p ;支持DPi感知
#Au3Stripper_Parameters=/sf=1 /sv=1
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#cs ____________________________________
欢迎使用 AutoIt v3 中文版 !
Au3版本: 3.3.14.5
脚本作者:
脚本功能:
更新日志:
联系方式:
#ce _______________脚本开始_________________
#include <Array.au3>
#include <WinAPISys.au3>
#include <WinAPIProc.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <GuiEdit.au3>
Opt("MustDeclareVars", 1)
Opt("GUIOnEventMode", 1)
Opt("GUICloseOnESC", 0)
Global Const $FD_READ = 1
Global Const $FD_WRITE = 2
Global Const $FD_ACCEPT = 8
Global Const $FD_CONNECT = 16
Global Const $FD_CLOSE = 32
Global Const $FD_SETSIZE = 32 ;定义监听客户端数量
Global Const $tagFd_set = "UINT fd_count;UINT fd_array[" & $FD_SETSIZE & "]"
Global $hDLL_WS2_32 = DllOpen("ws2_32.dll")
Global Const $FD_MAX_EVENTS = 10
Global $NetEvent = DllStructCreate("long lNetworkEvents;int iErrorCode[" & $FD_MAX_EVENTS & "];")
Global $UDP_Event = DllStructCreate("handle Event;")
Global $UDP_Socket
Global $UDP_port = 6800 ;定义监听端口
Global $TCP_MAX = 2
Global $TCP_port[$TCP_MAX] = [20001, 20002] ;定义监听端口
Global $TCP_Socket[$TCP_MAX]
Global $TCP_Event = DllStructCreate("handle Event[" & $TCP_MAX & "];")
Global $Client_Socket = DllStructCreate($tagFd_set)
Global $test, $hGUI, $idEdit, $idListview
Global $SendGUI, $Button1, $Input, $Num, $data
Global $fd_Array[$FD_SETSIZE][10]
Opt("GUIResizeMode", 1)
Global $HiDpi
If @Compiled Then
If _IsProcessDPIAware() Then
$HiDpi = _GetDpi()
Else
$HiDpi = 1
EndIf
Else
_SetProcessDPIAware()
$HiDpi = _GetDpi()
EndIf
TCPStartup()
$UDP_Socket = UDPOpen("255.255.255.255", $UDP_port, 1)
UDPSend($UDP_Socket, Binary("0x01000000A00F00000000000000000000")) ;发送广播消息,查询是否存在服务。
$data = UDPRecv($UDP_Socket, 4096, 1) ;接收消息,耗时 50毫秒。
UDPCloseSocket($UDP_Socket)
If $data <> "" Then
Exit MsgBox(262144 + 65536 + 64, "警告", "发现内网服务端:" & BinaryToString($data) & " 退出程序.")
EndIf
CreateGUI()
#Region 创建监听端口
For $i = 0 To $TCP_MAX - 1
$TCP_Socket[$i] = TCPListen("0.0.0.0", $TCP_port[$i], 1024)
If @error Then Exit MsgBox(262144 + 65536 + 64, "TCP端口冲突", "TCP端口被占用:" & $TCP_port[$i])
_Echo($idEdit, "监听TCP端口:" & $TCP_port[$i])
$TCP_Event.Event($i + 1) = _WinAPI_CreateEvent(0, True, False) ;创建事件对象, 为无信号,手动重置
_SockEventSelect($TCP_Socket[$i], $TCP_Event.Event($i + 1), $FD_ACCEPT) ;设置到事件模式
Next
$UDP_Socket = UDPBind("0.0.0.0", $UDP_port)
If @error Then Exit MsgBox(262144 + 65536 + 64, "UDP端口冲突", "UDP端口被占用:" & $UDP_port)
_Echo($idEdit, "监听UDP端口:" & $UDP_port)
$UDP_Event.Event(1) = _WinAPI_CreateEvent(0, True, False) ;创建事件对象, 为无信号,手动重置
_SockEventSelect($UDP_Socket[1], $UDP_Event.Event(1), $FD_READ) ;设置到事件模式
#EndRegion 创建监听端口
_Echo($idEdit, "启动完成。")
OnAutoItExitRegister("_Exit")
AdlibRegister("_Timeout", 1000 * 60) ;活动连接心跳检测
While 1
_TCP_Event($Client_Socket)
_UDP_Event()
_Client_Event($Client_Socket)
Sleep(5)
WEnd
Func _Data_Out($iSocket, $iDate)
If BinaryLen($iDate) < 20 Then
_TCPSend($iSocket, "x")
;_Echo($idEdit, "收到心跳包:" & $iDate)
Else
_Echo($idEdit, "收到数据:" & $iDate)
EndIf
EndFunc ;==>_Data_Out
Func _UDP_Event() ;处理UDP网路事件
Local $iObjects, $data, $aRet
Local $DateLen = 4096
$iObjects = _WinAPI_WaitForMultipleObjects(1, $UDP_Event, False, 0) ;检测信号状态,等待5毫秒
Switch $iObjects
Case 0
_WinAPI_ResetEvent($UDP_Event.Event($iObjects + 1)) ;设置指定事件对象为无信号状态
$aRet = DllCall("Ws2_32.dll", "int", "ioctlsocket", "uint", $UDP_Socket[1], "long", 0x4004667F, "ulong*", 0) ;查询接收缓冲区数据长度
If $aRet[0] = 0 Then $DateLen = $aRet[3]
$data = UDPRecv($UDP_Socket, $DateLen, 3)
If Not @error Then
If String($data[0]) == "0x01000000A00F00000000000000000000" Then
$UDP_Socket[2] = $data[1]
$UDP_Socket[3] = $data[2]
UDPSend($UDP_Socket, @IPAddress1 & ";" & $TCP_port[0] & ";" & $TCP_port[1])
EndIf
EndIf
Case -1 ;检测信号状态失败
EndSwitch
EndFunc ;==>_UDP_Event
Func _TCP_Event(ByRef $tFd_set) ;处理TCP接入请求事件
Local $iObjects, $iSocket, $NewIP, $iListItem, $Index
$iObjects = _WinAPI_WaitForMultipleObjects($TCP_MAX, $TCP_Event, False, 0) ;检测信号状态,等待5毫秒
Switch $iObjects
Case 0 To $TCP_MAX - 1
;_WinAPI_ResetEvent($TCP_Event.Event($iObjects + 1)) ;设置指定事件对象为无信号状态
;//添加的代码
If _WSAEnumNetworkEvents($TCP_Socket[$iObjects], $TCP_Event.Event($iObjects + 1)) Then ;择网络事件
If BitAND($NetEvent.lNetworkEvents(1), $FD_ACCEPT) Then
If $NetEvent.iErrorCode(3) = 0 Then
$iSocket = TCPAccept($TCP_Socket[$iObjects])
If $iSocket <> -1 Then
$NewIP = _SocketToIP($iSocket)
If $tFd_set.fd_count(1) >= $FD_SETSIZE Then
_Echo($idEdit, "!超出最大连接数:" & $FD_SETSIZE & " 断开新连接")
TCPCloseSocket($iSocket)
Else
_FD_SET($iSocket, $tFd_set)
$Index = _Array_SET($iSocket, $fd_Array)
$fd_Array[$Index][2] = GUICtrlCreateListViewItem($NewIP[0], $idListview)
$fd_Array[$Index][3] = $NewIP[0]
$fd_Array[$Index][4] = TimerInit()
_Echo($idEdit, "新连接,来自IP:" & $NewIP[0] & " 源端口:" & $NewIP[1] & " 目的端口:" & $NewIP[3] & " 连接数:" & $tFd_set.fd_count(1))
EndIf
EndIf
Else
ConsoleWrite("WSAEnumNetworkEvents failed with error code:" & $NetEvent.iErrorCode(3))
EndIf
EndIf
EndIf
;//添加的代码
Case -1 ;检测信号状态失败
EndSwitch
EndFunc ;==>_TCP_Event
Func _Timeout()
Local $i
For $i = $FD_SETSIZE - 1 To 0 Step -1
If $fd_Array[$i][4] == "" Then ContinueLoop
If TimerDiff($fd_Array[$i][4]) > 1000 * 10 Then ;活动连接无心跳10秒,关闭连接
GUICtrlDelete($fd_Array[$i][2])
TCPCloseSocket($fd_Array[$i][1])
_Echo($idEdit, "连接超时,来自IP:" & $fd_Array[$i][3])
_FD_CLR($fd_Array[$i][1], $Client_Socket)
_Array_CLR($fd_Array[$i][1], $fd_Array)
EndIf
Next
EndFunc ;==>_Timeout
Func _TCPRecv($iSocket, $iDataLen)
Local $DateLen
Local $Index = _Array_ISSET($iSocket, $fd_Array)
If $Index = -1 Then Return
$fd_Array[$Index][4] = TimerInit() ;写入时间戳
Local $iData = TCPRecv($iSocket, $iDataLen, 1)
If @error Then Return SetError(@error, @extended, "") ;错误处理 待完善
If IsBinary($fd_Array[$Index][5]) Then ;检查缓存
$fd_Array[$Index][5] = Binary($fd_Array[$Index][5] + $iData)
Else
$fd_Array[$Index][5] = $iData
EndIf
While 1
If BinaryLen($fd_Array[$Index][5]) < 4 Then ExitLoop
$DateLen = Int(BinaryMid($fd_Array[$Index][5], 1, 4))
If BinaryLen($fd_Array[$Index][5]) < $DateLen + 4 Then
ExitLoop
ElseIf BinaryLen($fd_Array[$Index][5]) = $DateLen + 4 Then
_Data_Out($iSocket, BinaryMid($fd_Array[$Index][5], 5))
$fd_Array[$Index][5] = ""
ExitLoop
EndIf
_Data_Out($iSocket, BinaryMid($fd_Array[$Index][5], 5, $DateLen))
$fd_Array[$Index][5] = BinaryMid($fd_Array[$Index][5], $DateLen + 5)
WEnd
EndFunc ;==>_TCPRecv
Func _TCPSend($iSocket, $dData)
If $dData == "" Then Return
If Not IsBinary($dData) Then $dData = StringToBinary($dData)
Local $dataLen = BinaryLen($dData)
Local $byte = Binary(Binary(Ptr($dataLen)) + $dData)
Local $iRet = TCPSend($iSocket, $byte)
If @error Then Return SetError(@error, 0, 0)
Return $iRet
EndFunc ;==>_TCPSend
Func _Echo($hID, $sText = "")
If Not StringIsASCII($sText) Then $sText = String($sText)
Local $LogTime = @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & " " & $sText & @CRLF
Local $hWnd = GUICtrlGetHandle($hID)
Local $Len = StringLen($LogTime)
Local $Text = $LogTime & GUICtrlRead($hID)
If _GUICtrlEdit_GetLineCount($hWnd) > 300 Then
$Len += _GUICtrlEdit_LineIndex($hWnd, 299)
$Text = StringLeft($Text, $Len)
EndIf
GUICtrlSetData($hID, $Text)
EndFunc ;==>_Echo
Func CreateGUI()
Local $Width = 880, $Height = 680, $idContextmenu
$hGUI = GUICreate("广播转发 - 支持" & $FD_SETSIZE & "接入", $Width, $Height + 48, -1, -1) ;创建窗口
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
GUICtrlCreateGroup("客户端列表", 5, 10, $Width - 10, 500)
$idListview = GUICtrlCreateListView("编号|", 10, 25, $Width - 20, 480, $LVS_SHOWSELALWAYS, $LVS_EX_FULLROWSELECT + $LVS_EX_GRIDLINES + $LVS_EX_DOUBLEBUFFER) ;,$LVS_SORTDESCENDING)
_GUICtrlListView_SetColumnWidth($idListview, 0, $LVSCW_AUTOSIZE_USEHEADER)
GUICtrlCreateGroup("消息日志", 5, 520, $Width - 10, 166)
$idEdit = GUICtrlCreateEdit("", 15, 540, $Width - 30, 136, 0x50210804, $WS_EX_STATICEDGE)
$idContextmenu = GUICtrlCreateContextMenu($idListview)
;创建菜单“所有客户机”主控件-全部
GUICtrlCreateMenuItem("关闭连接", $idContextmenu)
GUICtrlSetOnEvent(-1, "_Selected")
GUICtrlCreateMenuItem("发送消息", $idContextmenu)
GUICtrlSetOnEvent(-1, "_Selected_Send")
GUISetState(@SW_SHOW)
EndFunc ;==>CreateGUI
Func _Client_Event(ByRef $tFd_set) ;处理客户端的网路事件
Local $iSocket, $iData, $NewIP, $aRet, $Index, $DateLen
Local $count = $tFd_set.fd_count(1)
If $count < 1 Then Return
Local $Fd_Socket = DllStructCreate($tagFd_set)
Local $tFd_set_dat = DllStructCreate("byte[" & $count * 4 + 4 & "];", DllStructGetPtr($tFd_set))
Local $Fd_Socket_dat = DllStructCreate("byte[" & $count * 4 + 4 & "];", DllStructGetPtr($Fd_Socket))
DllStructSetData($Fd_Socket_dat, 1, DllStructGetData($tFd_set_dat, 1)) ;创建结构体副本
If _Select($Fd_Socket) Then ;查询是否有网络事件
For $i = 0 To $Fd_Socket.fd_count(1) - 1
$iSocket = $Fd_Socket.fd_array($i + 1)
If _FD_ISSET($iSocket, $Fd_Socket) Then ;检查套接字是否存在
$NewIP = _SocketToIP($iSocket) ;查询套接字的源地址-目标地址
Local $DateLen = 4096
$aRet = DllCall("Ws2_32.dll", "int", "ioctlsocket", "uint", $iSocket, "long", 0x4004667F, "ulong*", 0) ;查询套接字接收缓冲区中的数据长度
If $aRet[0] = 0 Then
If $aRet[3] > 0 Then
_TCPRecv($iSocket, $aRet[3])
Else
TCPCloseSocket($iSocket)
_FD_CLR($iSocket, $tFd_set)
$Index = _Array_ISSET($iSocket, $fd_Array) ;查询套接字在数组中的位置
If Not @error Then
GUICtrlDelete($fd_Array[$Index][2])
_Array_CLR($iSocket, $fd_Array) ;清理数组
EndIf
_Echo($idEdit, "断开连接,来自IP:" & $NewIP[0] & " 源端口:" & $NewIP[1] & " 目的端口:" & $NewIP[3])
EndIf
Else
_TCPRecv($iSocket, 4096)
EndIf
EndIf
Next
EndIf
EndFunc ;==>_Client_Event
Func _Select(ByRef $tFd_set)
Local $timeval = DllStructCreate("int tv_sec;int tv_usec")
Local $result = DllCall("Ws2_32.dll", "int", "select", "int", Null, "struct*", $tFd_set, "ptr", 0, "ptr", 0, "struct*", $timeval)
If $result[0] <= 0 Then Return False
Return True
EndFunc ;==>_Select
Func _Array_SET($iSocket, ByRef $tArray_set)
If Not IsArray($tArray_set) Then Return SetError(2, False, False)
If $tArray_set[0][0] = "" Then $tArray_set[0][0] = 0
Local $ROWS = UBound($tArray_set)
Local $iCount = $tArray_set[0][0]
For $i = 0 To $iCount - 1
If $tArray_set[$i][1] = $iSocket Then
ExitLoop
EndIf
Next
If $i = $iCount Then
If $iCount < $ROWS Then
$tArray_set[$i][1] = $iSocket
$tArray_set[0][0] = $iCount + 1
EndIf
EndIf
Return $tArray_set[0][0] - 1
EndFunc ;==>_Array_SET
Func _Array_CLR($iSocket, ByRef $tArray_set)
Local $COLUMNS = UBound($tArray_set, 2)
Local $iCount = $tArray_set[0][0]
For $i = 0 To $iCount - 1
If $tArray_set[$i][1] = $iSocket Then
While ($i < $iCount - 1)
For $s = 1 To $COLUMNS - 1
$tArray_set[$i][$s] = $tArray_set[$i + 1][$s]
Next
$i += 1
WEnd
For $s = 1 To $COLUMNS - 1
$tArray_set[$i][$s] = Null
Next
$tArray_set[0][0] = $iCount - 1
ExitLoop
EndIf
Next
EndFunc ;==>_Array_CLR
Func _Array_ISSET($iSocket, ByRef $tArray_set)
If Not IsArray($tArray_set) Then Return SetError(2, False, -1)
If $tArray_set[0][0] = "" Then $tArray_set[0][0] = 0
Local $Ret
Local $COLUMNS = UBound($tArray_set, 2)
Local $iCount = $tArray_set[0][0]
For $i = 0 To $iCount - 1
If $tArray_set[$i][1] = $iSocket Then
$Ret = $i
ExitLoop
EndIf
Next
If $Ret == "" Then Return SetError(2, False, -1)
Return $Ret
EndFunc ;==>_Array_ISSET
Func _FD_SET($iSocket, ByRef $tFd_set)
Local $iCount = DllStructGetData($tFd_set, "fd_count")
For $i = 0 To $iCount - 1
If DllStructGetData($tFd_set, "fd_Array", $i + 1) = $iSocket Then
ExitLoop
EndIf
Next
If $i = $iCount Then
If $iCount < $FD_SETSIZE Then
DllStructSetData($tFd_set, "fd_array", $iSocket, $i + 1)
DllStructSetData($tFd_set, "fd_count", $iCount + 1)
EndIf
EndIf
EndFunc ;==>_FD_SET
Func _FD_CLR($iSocket, ByRef $tFd_set)
Local $iCount = DllStructGetData($tFd_set, "fd_count")
For $i = 0 To $iCount - 1
If DllStructGetData($tFd_set, "fd_array", $i + 1) = $iSocket Then
While ($i < $iCount - 1)
DllStructSetData($tFd_set, "fd_array", DllStructGetData($tFd_set, "fd_array", $i + 2), $i + 1)
$i += 1
WEnd
DllStructSetData($tFd_set, "fd_array", 0, $i + 1)
DllStructSetData($tFd_set, "fd_count", $iCount - 1)
ExitLoop
EndIf
Next
EndFunc ;==>_FD_CLR
Func _FD_ISSET($iSocket, ByRef $tFd_set)
Local $aRet = DllCall($hDLL_WS2_32, "int", "__WSAFDIsSet", "UINT", $iSocket, "struct*", $tFd_set)
Return $aRet[0]
EndFunc ;==>_FD_ISSET
Func _WSAEnumNetworkEvents($hSocket, $hWnd)
Local $iRet = DllCall($hDLL_WS2_32, "int", "WSAEnumNetworkEvents", "uint", $hSocket, "hwnd", $hWnd, "struct*", $NetEvent)
If @error Then Return SetError(1, @error, False)
If $iRet[0] <> 0 Then
$iRet = DllCall($hDLL_WS2_32, "dword", "WSAGetLastError")
Return SetError(2, $iRet[0], False)
EndIf
Return True
EndFunc ;==>_WSAEnumNetworkEvents
Func _SockEventSelect($hSocket, $hWnd, $iEvent = 0)
Local $iRet = DllCall($hDLL_WS2_32, "int", "WSAEventSelect", "uint", $hSocket, "hwnd", $hWnd, "int", $iEvent)
If @error Then Return SetError(1, @error, False)
If $iRet[0] <> 0 Then
Return SetError(2, _WSAGetLastError(), False)
EndIf
Return True
EndFunc ;==>_SockEventSelect
Func _WSAGetLastError()
Local $iRet = DllCall($hDLL_WS2_32, "int", "WSAGetLastError")
If @error Then
SetExtended(1)
Return 0
EndIf
Return $iRet[0]
EndFunc ;==>_WSAGetLastError
Func _SocketToIP($hSocket)
Local $sockaddr, $aRet, $aArray[4], $error
$error = False
$sockaddr = DllStructCreate("short;ushort;uint;char[8]")
$aRet = DllCall($hDLL_WS2_32, "int", "getpeername", "int", $hSocket, _
"struct*", $sockaddr, "int*", DllStructGetSize($sockaddr))
If @error Or $aRet[0] <> 0 Then
$error = True
Else
$aRet = DllCall($hDLL_WS2_32, "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
If Not @error Then $aArray[0] = $aRet[0]
$aRet = DllCall($hDLL_WS2_32, "ushort", "ntohs", "ushort", DllStructGetData($sockaddr, 2))
If Not @error Then $aArray[1] = $aRet[0]
EndIf
$aRet = DllCall($hDLL_WS2_32, "int", "getsockname", "int", $hSocket, _
"struct*", $sockaddr, "int*", DllStructGetSize($sockaddr))
If @error Or $aRet[0] <> 0 Then
$error = True
Else
$aRet = DllCall($hDLL_WS2_32, "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
If Not @error Then $aArray[2] = $aRet[0]
$aRet = DllCall($hDLL_WS2_32, "ushort", "ntohs", "ushort", DllStructGetData($sockaddr, 2))
If Not @error Then $aArray[3] = $aRet[0]
EndIf
$sockaddr = 0
Return SetError($error, False, $aArray)
EndFunc ;==>_SocketToIP
Func _Selected()
Local $Column, $Num, $iSocket
$Column = _GUICtrlListView_GetSelectedCount($idListview)
If $Column <> 1 Then Return
$Num = _GUICtrlListView_GetSelectedIndices($idListview, False)
_Echo($idEdit, "关闭连接" & $fd_Array[$Num][3])
$iSocket = $fd_Array[$Num][1]
TCPCloseSocket($iSocket)
GUICtrlDelete($fd_Array[$Num][2])
_FD_CLR($iSocket, $Client_Socket)
_Array_CLR($iSocket, $fd_Array)
EndFunc ;==>_Selected
Func _Selected_Send()
Local $Column, $Num
Local $aHotKey[1][2]
$Column = _GUICtrlListView_GetSelectedCount($idListview)
If $Column <> 1 Then Return
$Num = _GUICtrlListView_GetSelectedIndices($idListview, False)
$SendGUI = GUICreate("发送数据窗口", 600, 160, -1, -1, Default, Default, $hGUI)
GUISetOnEvent($GUI_EVENT_CLOSE, "Close_GUI")
$Button1 = GUICtrlCreateButton("发送", 260, 112, 85, 25)
GUICtrlSetOnEvent($Button1, "_Button")
$Input = GUICtrlCreateInput("", 32, 48, 520, 32)
$aHotKey[0][0] = "{Enter}"
$aHotKey[0][1] = $Button1
GUISetAccelerators($aHotKey, $SendGUI)
GUISetState(@SW_SHOW, $SendGUI)
ControlFocus($SendGUI, "", $Input)
EndFunc ;==>_Selected_Send
Func _Button()
Local $Column, $iSocket, $iData, $Num
$Column = _GUICtrlListView_GetSelectedCount($idListview)
If $Column <> 1 Then Return
$Num = _GUICtrlListView_GetSelectedIndices($idListview, False)
$iData = GUICtrlRead($Input)
$iSocket = $fd_Array[$Num][1]
If $iData <> "" And $iSocket <> "" Then
_Echo($idEdit, "发送消息" & $iData)
_TCPSend($iSocket, $iData)
EndIf
EndFunc ;==>_Button
Func Close_GUI()
GUISetAccelerators(0, $SendGUI)
GUIDelete($SendGUI)
EndFunc ;==>Close_GUI
Func _Exit()
For $i = 0 To $TCP_MAX - 1
TCPCloseSocket($TCP_Socket[$i])
Next
For $i = 0 To $FD_SETSIZE - 1
If $fd_Array[$i][1] <> "" Then TCPCloseSocket($fd_Array[$i][1])
Next
UDPCloseSocket($UDP_Socket)
DllClose($hDLL_WS2_32)
TCPShutdown()
Exit
EndFunc ;==>_Exit
#Region DPI函数
Func _SetProcessDPIAware()
Local $aRet
If @OSBuild < 6000 Then Return ;判断系统版本 Windows Vista
If @OSBuild < 9600 Then ;判断系统版本 win8.1(9600)
$aRet = DllCall("User32.dll", "BOOL", "IsProcessDPIAware") ;检查进程是否支持DPI感知
Return $aRet[0]
If $aRet[0] = False Then
$aRet = DllCall('User32.dll', 'BOOL', 'SetProcessDPIAware') ;设置:系统DPI感知
If @error Then Return SetError(@error, 0, False)
Return
EndIf
Else
$aRet = DllCall("Shcore.dll", "BOOL", "GetProcessDpiAwareness", "HWND", 0, "int*", 0) ;检查进程是否支持DPI感知
If @error Then Return SetError(@error, 0, False)
If $aRet[2] <> 2 Then ;0不支持DPI感知 1,系统DPI感知 2,监视器DPI感知
$aRet = DllCall("Shcore.dll", "BOOL", "SetProcessDpiAwareness", "int", 2) ;设置:监视器DPI感知
If @error Then Return SetError(@error, 0, False)
Return
EndIf
EndIf
EndFunc ;==>_SetProcessDPIAware
Func _GetDpi()
Local $iDPI
If @OSBuild < 6000 Then Return 1 ;判断系统版本 Windows Vista
If @OSBuild < 9600 Then ;判断系统版本 win8.1(9600)
$iDPI = RegRead("HKCU\Control Panel\Desktop\WindowMetrics", "AppliedDPI")
Else
Local $hWnd = _WinAPI_MonitorFromWindow(_WinAPI_GetDesktopWindow())
Local $aRet = DllCall("Shcore.dll", "BOOL", "GetDpiForMonitor", "HANDLE", $hWnd, "int", 0, "int*", 0, "int*", 0)
If @error Then Return SetError(@error, 0, False)
$iDPI = $aRet[3]
EndIf
If $iDPI < 96 Or $iDPI > 480 Then $iDPI = 96
Return $iDPI / 96
EndFunc ;==>_GetDpi
Func _IsProcessDPIAware()
Local $aRet, $aDpi = 0
If @OSBuild < 6000 Then Return False ;判断系统版本 Windows Vista
If @OSBuild < 9600 Then ;判断系统版本 win8.1(9600)
$aRet = DllCall("User32.dll", "BOOL", "IsProcessDPIAware") ;检查进程是否支持DPI感知
If @error Then Return SetError(@error, 0, False)
$aDpi = $aRet[0]
Else
$aRet = DllCall("Shcore.dll", "BOOL", "GetProcessDpiAwareness", "HWND", 0, "int*", 0) ;检查进程是否支持DPI感知
If @error Then Return SetError(@error, 0, False)
$aDpi = $aRet[2]
EndIf
Return $aDpi
EndFunc ;==>_IsProcessDPIAware
#EndRegion DPI函数