Leaderboard
Popular Content
Showing content with the highest reputation since 11/12/2025 in all areas
-
WinSockUDF - TCP/UDP Networking Library for AutoIt
WildByDesign and one other reacted to water for a topic
Added this UDF to the Wiki2 points -
WinSockUDF - TCP/UDP Networking Library for AutoIt
argumentum and one other reacted to Trong for a topic
It was all my fault, I fixed it! I didn't know that the dark theme of the forum didn't invert the text colors (it seems unintelligent) Thank you all for your feedback2 points -
WinCred UDF - Windows Credential Management API
argumentum and one other reacted to DonChunior for a topic
Description WinCred is a User Defined Function (UDF) library for AutoIt that provides a complete interface to the Windows Credential Management API. This UDF allows you to create, read, update, and delete credentials stored in the Windows Credential Manager, which is the same secure storage system used by Windows itself for storing passwords and other sensitive information. Features Create and modify credentials using _WinCred_CredWrite Read credentials from the user's credential set with _WinCred_CredRead Delete credentials using _WinCred_CredDelete Support for all credential types (Generic, Domain Password, Certificates, etc.) Configurable persistence options (Session, Local Machine, Enterprise) Full Unicode support Comprehensive error handling with detailed error codes Complete example scripts for all functions Fully documented following AutoIt UDF standards Functions The UDF provides three main functions: _WinCred_CredWrite - Creates a new credential or modifies an existing credential in the user's credential set _WinCred_CredRead - Reads a credential from the user's credential set and returns an array with all credential information _WinCred_CredDelete - Deletes a credential from the user's credential set All functions follow AutoIt's standard error handling mechanism. For detailed syntax, parameters, and return values, please refer to the function documentation in the UDF file. Constants All constants are defined in WinCredConstants.au3, including credential types ($CRED_TYPE_*), persistence options ($CRED_PERSIST_*), and flags ($CRED_PRESERVE_CREDENTIAL_BLOB). See the constants file for a complete list. Quick Start Example #include "WinCred.au3" ; Create a credential Local $sTargetName = "MyApp-Credential" Local $sUserName = "MyUsername" Local $vPassword = Binary("MySecretPassword") If _WinCred_CredWrite($sTargetName, $CRED_TYPE_GENERIC, $sUserName, $vPassword) Then ConsoleWrite("Credential created successfully!" & @CRLF) Else ConsoleWrite("Error creating credential: " & @error & @CRLF) EndIf ; Read the credential Local $aCredential = _WinCred_CredRead($sTargetName, $CRED_TYPE_GENERIC) If Not @error Then ConsoleWrite("TargetName: " & $aCredential[0] & @CRLF) ConsoleWrite("UserName: " & $aCredential[2] & @CRLF) ConsoleWrite("Blob Size: " & BinaryLen($aCredential[3]) & " bytes" & @CRLF) EndIf ; Delete the credential _WinCred_CredDelete($sTargetName, $CRED_TYPE_GENERIC) Example Scripts The UDF includes complete example scripts in the Examples directory: _WinCred_CredWrite.au3 - Demonstrates creating credentials with different persistence settings _WinCred_CredRead.au3 - Shows how to read credentials and display all available information _WinCred_CredDelete.au3 - Demonstrates deleting credentials and verifying deletion All examples are fully commented and follow AutoIt best practices. Security Notes Credentials are stored securely in the Windows Credential Manager The CredentialBlob should contain binary data (use Binary() function) For sensitive data, consider encrypting the blob before storing Documentation Full function documentation is included in the UDF file following AutoIt UDF standards. The UDF is compatible with AutoIt's built-in help file system. License This UDF is released under the MIT License. See the LICENSE file for details. Changelog See CHANGELOG.md for a complete list of changes. Links GitHub Repository: https://github.com/DonChunior/WinCred-UDF Microsoft Documentation: https://learn.microsoft.com/en-us/windows/win32/api/wincred/2 points -
Bug in map ( and how to avoid it )
Musashi and one other reacted to AspirinJunkie for a topic
It seems that this is less about index collisions. The real problem is obviously that memory areas are being used across multiple map instances. Whether this occurs exclusively when using string indices in conjunction with integer indices or in other cases as well, we cannot know here and now. Without having the source code for the implementation, we can only speculate about what is happening in the background based on the behavior. And so far, it seems to me that the memory areas for the buckets of the hash table are not completely cleaned up when dereferencing the map variable, and on the other hand, these areas are used when initializing a map variable without being fully prepared for use (e.g., memory area zeros or something like that). There may well be a clever idea behind this, for example, to increase performance or something like that—we don't know. However, the current implementation is undoubtedly a bug, and worse still, a bug whose consequences cannot really be assessed at present. Therefore, we cannot simply dismiss the issue with blanket statements such as “don't use integer keys” or something similar. This naturally raises the question of how to deal with it. It has been clearly stated that bug reports should not be created for maps. Nevertheless, the bug tracker is full of tickets for maps, and they are being processed as normal. That's why I would have liked to discuss the whole thing in advance in the forum, preferably with the developers involved (actually, I wanted to do just that in the German forum first, but you had already posted the thread here...). In my opinion, the “AutoIt General Help and Support” forum is not the right place for this, but rather “AutoIt Technical Discussion.” However, it may well be that the bug has already been fixed and has been resolved in the course of the following ticket: https://www.autoitscript.com/trac/autoit/ticket/3948 The phenomenon described there is quite similar.2 points -
WinRT - UI Gallery (Xaml Islands)
argumentum and one other reacted to MattyD for a topic
In order not to pollute other threads, here's one dedicated to Windows.UI controls and examples. These are for use with Xaml Islands, NOT WinUI3 - although porting them across shouldn't be too demanding. Both methods have their pros and cons - but I'd say the XAML Island approach is bit more robust at this point in time. Don't forget to update your manifests to make this work! (background/details in this thread) Download PS. More than happy for this to be a community thing if anyone else wishes to contribute2 points -
It was mentioned here how AI bots are intensively hitting the site. I suppose they also grab all the codes they can take...2 points
-
WinRT - WinUI3
WildByDesign and one other reacted to MattyD for a topic
Hi all, Updated libraries based on the new Version 1.8 of WindowsAppSDK are here. Until now we've been on 1.7.x The v1.8 runtime can be installed from here: (Remembering that we require the x64 version.) A copy of the latest bootstrapper dll is included in the zip - but if you need to manually update it later for whatever reason, it has moved. So you'll now find it here: https://www.nuget.org/packages/Microsoft.WindowsAppSdk.Foundation/ download package (on the right) > extract contents > then you'll find it under .\runtimes\win-x64\native2 points -
AutoIt v3.3.18.0 has been released - mainly a UDF release. Thanks to @jpm and the MVPs who were responsible for the majority of code in this version. Download it here. Complete list of changes: History2 points
-
WinSockUDF - TCP/UDP Networking Library for AutoIt Version: 1.1 | Author: Dao Van Trong - TRONG.PRO | AutoIt: 3.3.14.2+ 📖 Overview WinSockUDF is a powerful, production-ready TCP/UDP networking library for AutoIt that brings enterprise-level networking capabilities to your scripts. Built on top of the Windows Sockets API (Winsock2), it provides asynchronous, event-driven communication with advanced features that go far beyond AutoIt's built-in networking functions. This library is designed for developers who need reliable, high-performance network communication in their AutoIt applications - whether you're building chat systems, file transfer utilities, remote administration tools, or IoT device controllers. ⚡ Key Features Core Networking ✅ Asynchronous Event-Driven Architecture - True non-blocking I/O with elegant callback system ✅ Full Winsock2 API Access - Direct Windows Sockets implementation for maximum performance ✅ TCP Server & Client - Production-ready server with multi-client support ✅ UDP Support - Connectionless datagram communication (SendTo/RecvFrom) ✅ Multiple Simultaneous Connections - Handle hundreds of clients with ease Advanced Features 🔒 Binary Data Transfer - Safe transmission with automatic Base64 encoding/decoding 🎯 Smart Connection Management - Automatic reconnection, timeouts, and error recovery 📡 Broadcasting - Send messages to all connected clients instantly 🔍 Client Management - Track, query, and control individual client connections ⚙️ Flexible Event System - Register custom callbacks for all network events Developer Experience 📚 Comprehensive Error Handling - Detailed @error/@extended codes for debugging 🎨 Clean API Design - Intuitive function names and consistent parameter patterns 📝 Well Documented - Complete function reference with examples 🚀 Production Ready - Battle-tested in real-world applications 📦 Installation Method 1: Quick Start Download WinSockUDF.au3 from this repository Place it in your AutoIt include directory (usually C:\Program Files (x86)\AutoIt3\Include) Include it in your script: #include <WinSockUDF.au3> Method 2: Project-Local Copy WinSockUDF.au3 to your project folder Include with relative path: #include "WinSockUDF.au3" Requirements: AutoIt v3.3.14.2 or higher Windows OS (XP or later) No external dependencies required Quick Start TCP Server Example #include "WinSockUDF.au3" _TCP_Startup() ; Create server on port 8080 $hServer = _TCP_Server_Create(8080) ; Register event callbacks _TCP_Server_OnNewClient($hServer, "OnNewClient") _TCP_Server_OnReceive($hServer, "OnReceive") _TCP_Server_OnDisconnect($hServer, "OnDisconnect") ; Event loop While 1 Sleep(10) WEnd Func OnNewClient($hClient, $iError) ConsoleWrite("New client connected: " & $hClient & @CRLF) _TCP_Send($hClient, "Welcome to server!" & @CRLF) EndFunc Func OnReceive($hClient, $sData, $iError) ConsoleWrite("Received: " & $sData & @CRLF) _TCP_Send($hClient, "Echo: " & $sData) EndFunc Func OnDisconnect($hClient, $iError) ConsoleWrite("Client disconnected: " & $hClient & @CRLF) EndFunc TCP Client Example #include "WinSockUDF.au3" _TCP_Startup() ; Connect to server $hClient = _TCP_Client_Create("127.0.0.1", 8080) ; Register event callbacks _TCP_Client_OnConnect($hClient, "OnConnect") _TCP_Client_OnReceive($hClient, "OnReceive") _TCP_Client_OnDisconnect($hClient, "OnDisconnect") ; Event loop While 1 Sleep(10) WEnd Func OnConnect($hSocket, $iError) If $iError Then ConsoleWrite("Connection failed: " & $iError & @CRLF) Else ConsoleWrite("Connected successfully!" & @CRLF) _TCP_Send($hSocket, "Hello Server!") EndIf EndFunc Func OnReceive($hSocket, $sData, $iError) ConsoleWrite("Received: " & $sData & @CRLF) EndFunc Func OnDisconnect($hSocket, $iError) ConsoleWrite("Disconnected from server" & @CRLF) EndFunc Function Reference Initialization Functions Function Description _TCP_Startup() Initialize Winsock and async system _TCP_Shutdown() Close all connections and free resources TCP Server Functions Function Description _TCP_Server_Create($iPort[, $sIP = "0.0.0.0"[, $iMaxPending = 5]]) Create TCP server _TCP_Server_Stop($hSocket) Stop server and close all clients _TCP_Server_ClientList() Get array of connected clients _TCP_Server_ClientIP($hSocket) Get client IP address _TCP_Server_DisconnectClient($hSocket) Disconnect specific client _TCP_Server_Broadcast($vData) Send data to all clients _TCP_Server_OnNewClient($hServer, $sCallback) Register new client callback _TCP_Server_OnReceive($hServer, $sCallback) Register receive callback _TCP_Server_OnSend($hServer, $sCallback) Register send ready callback _TCP_Server_OnDisconnect($hServer, $sCallback) Register disconnect callback TCP Client Functions Function Description _TCP_Client_Create($sIP, $iPort[, $sSourceIP = ""[, $iSourcePort = 0[, $iTimeout = 0]]]) Create TCP client connection _TCP_Client_Stop($hSocket) Close client connection _TCP_Client_OnConnect($hClient, $sCallback) Register connect callback _TCP_Client_OnReceive($hClient, $sCallback) Register receive callback _TCP_Client_OnSend($hClient, $sCallback) Register send ready callback _TCP_Client_OnDisconnect($hClient, $sCallback) Register disconnect callback Common TCP Functions Function Description _TCP_Send($hSocket, $vData[, $iFlag = 0]) Send data through socket _TCP_Recv($hSocket, $iMaxLen[, $iFlag = 0]) Receive data from socket _TCP_Send_Ex($hSocket, $vData[, $iFlag = 0]) Send with automatic Base64 encoding _TCP_Recv_Ex($hSocket, $iMaxLen[, $iFlag = 0]) Receive with automatic Base64 decoding _TCP_NameToIP($sName) Convert hostname to IP address _TCP_GetIPs([$sServerName = ""]) Get local and public IP addresses UDP Functions Function Description _UDP_Startup() Initialize UDP system _UDP_Shutdown() Shutdown UDP system _UDP_Bind([$sSourceIP = ""[, $iSourcePort = 0]]) Create and bind UDP socket _UDP_SendTo($sIP, $iPort, $vData[, $hSocket = 0]) Send UDP packet _UDP_RecvFrom($hSocket, $iMaxLen[, $iFlag = 0]) Receive UDP packet _UDP_CloseSocket($vSocket) Close UDP socket Base64 Functions Function Description _Base64Encode($bInput[, $bNoCRLF = True]) Encode binary data to Base64 string _Base64Decode($sInput[, $bReturnBinary = False[, $iDecodeType = 1]]) Decode Base64 string _Base64EncodeStr($sInput[, $iEncodeType = 4[, $bNoCRLF = True]]) Encode string to Base64 _Base64DecodeStr($sInput[, $iDecodeType = 4]) Decode Base64 to string Path Utility Functions Function Description _PathWithSlash($sPath) Add trailing backslash to path _PathRemoveTrail($sPath) Remove trailing backslashes from path Constants Data Flags $TCP_DEFAULT_DATA = 0 ; Default string data $TCP_BINARY_DATA = 1 ; Binary data mode $TCP_EOT_DATA = 2 ; End-of-transmission marker Event Types $TCP_EVENT_SEND = 1 ; Send ready event $TCP_EVENT_RECEIVE = 2 ; Data received event $TCP_EVENT_CONNECT = 4 ; Connection established $TCP_EVENT_DISCONNECT = 8 ; Connection closed $TCP_EVENT_NEWCLIENT = 16 ; New client connected (server) Advanced Features Binary File Transfer Use _TCP_Send_Ex() and _TCP_Recv_Ex() for automatic Base64 encoding/decoding of binary data: ; Send binary file Local $bData = FileRead("image.jpg") _TCP_Send_Ex($hSocket, $bData) ; Receive binary file Local $bData = _TCP_Recv_Ex($hSocket, 8192, $TCP_BINARY_DATA) FileWrite("received.jpg", $bData) Multiple Server Support The library supports running multiple servers on different ports simultaneously with independent callback handlers. Connection Timeout Client connections support timeout parameter: ; Wait up to 5 seconds for connection $hClient = _TCP_Client_Create("192.168.1.100", 8080, "", 0, 5000) Error Handling All functions set @error on failure: -1 = General error (check @extended for WSA error code) -2 = Failed to load Winsock DLL -4 = Invalid parameters or socket not found -5 = Connection failed -6 = Timeout Example: $hServer = _TCP_Server_Create(8080) If @error Then ConsoleWrite("Failed to create server. Error: " & @error & ", Extended: " & @extended & @CRLF) Exit EndIf 📚 Example Applications This repository includes three complete, production-ready example applications: TCP Chat System - Full-featured chat room with authentication, private messaging, and user management UDP Chat Application - Lightweight UDP-based chat demonstrating connectionless communication Lab Manager System - Professional client-server remote administration tool with system monitoring Each example includes both client and server implementations with complete source code. 💡 Use Cases 💬 Chat Applications - Real-time messaging systems with multi-user support 📁 File Transfer Tools - Binary file sharing with Base64 encoding 🖥️ Remote Administration - Control and monitor computers over network 🎮 Game Servers - Multiplayer game networking and matchmaking 🌐 IoT Communication - Device-to-device communication and control 🔌 API Servers - Custom protocol implementations and microservices 📊 Data Collection - Sensor data aggregation and monitoring systems 🔔 Notification Systems - Push notification and alert distribution Note: This library uses direct Winsock API calls for advanced networking features. Make sure to call _TCP_Startup() before using any TCP/UDP functions and _TCP_Shutdown() when done. UDF: ; #INDEX# ======================================================================================================================= ; Title .........: WinSockUDF ; AutoIt Version : 3.3.14.2+ ; Language ......: English ; Description ...: Advanced TCP/UDP networking library with async events, error handling, full Winsock2 API support ; Author(s) .....: Dao Van Trong - TRONG.PRO ; Version .......: 1.1 ; =============================================================================================================================== #include-once ; #CONSTANTS# =================================================================================================================== Global Const $TCP_DEFAULT_DATA = 0 Global Const $TCP_BINARY_DATA = 1 Global Const $TCP_EOT_DATA = 2 ; Async Events Global Const $TCP_EVENT_SEND = 1 Global Const $TCP_EVENT_RECEIVE = 2 Global Const $TCP_EVENT_CONNECT = 4 Global Const $TCP_EVENT_DISCONNECT = 8 Global Const $TCP_EVENT_NEWCLIENT = 16 ; Winsock Events (internal) Global Const $FD_READ = 1 Global Const $FD_WRITE = 2 Global Const $FD_OOB = 4 Global Const $FD_ACCEPT = 8 Global Const $FD_CONNECT = 16 Global Const $FD_CLOSE = 32 ; =============================================================================================================================== ; #VARIABLES# =================================================================================================================== Global $__TCP_hWs2_32 = -1 Global $__TCP_AsyncWindow = 0 Global $__TCP_Sockets[1][11] ; [socket, msgID, onRecv, onSend, onConnect, onDisconnect, onNewClient, ip, port, isServer, parentServer] Global $__TCP_Initialized = False ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ; Initialization ; _TCP_Startup ; _TCP_Shutdown ; ; Server Functions ; _TCP_Server_Create ; _TCP_Server_Stop ; _TCP_Server_ClientList ; _TCP_Server_ClientIP ; _TCP_Server_DisconnectClient ; _TCP_Server_Broadcast ; _TCP_Server_OnNewClient ; _TCP_Server_OnReceive ; _TCP_Server_OnSend ; _TCP_Server_OnDisconnect ; ; Client Functions ; _TCP_Client_Create ; _TCP_Client_Stop ; _TCP_Client_OnConnect ; _TCP_Client_OnReceive ; _TCP_Client_OnSend ; _TCP_Client_OnDisconnect ; ; Common Functions ; _TCP_Send ; _TCP_Recv ; _TCP_Send_Ex ; _TCP_Recv_Ex ; _TCP_RegisterEvent ; _TCP_NameToIP ; _TCP_GetIPs ; _TCP_OnConnect (alias for Client) ; _TCP_OnDisconnect (universal) ; _TCP_OnReceive (universal) ; _TCP_OnSend (universal) ; ; UDP Functions ; _UDP_Startup ; _UDP_Shutdown ; _UDP_Bind ; _UDP_SendTo ; _UDP_RecvFrom ; _UDP_CloseSocket ; ; Base64 Functions ; _Base64Encode ; _Base64Decode ; _Base64EncodeStr ; _Base64DecodeStr ; ; Path Functions ; _PathWithSlash ; _PathRemoveTrail ; ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Startup ; Description ...: Initialize Winsock and async system ; Syntax ........: _TCP_Startup() ; Return values .: Success - 1, Failure - 0 and sets @error ; =============================================================================================================================== Func _TCP_Startup() If $__TCP_Initialized Then Return 1 Local $iResult = TCPStartup() If @error Then Return SetError(@error, 0, 0) $__TCP_hWs2_32 = DllOpen("Ws2_32.dll") If $__TCP_hWs2_32 = -1 Then Return SetError(-2, 0, 0) $__TCP_AsyncWindow = GUICreate("TCP_AsyncWindow_" & Random(1000, 9999, 1)) $__TCP_Initialized = True Return SetError(0, 0, 1) EndFunc ;==>_TCP_Startup ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Shutdown ; Description ...: Close all connections and free resources ; Syntax ........: _TCP_Shutdown() ; Return values .: Success - 1 ; =============================================================================================================================== Func _TCP_Shutdown() If Not $__TCP_Initialized Then Return 1 ; Close all sockets For $i = UBound($__TCP_Sockets) - 1 To 0 Step -1 If $__TCP_Sockets[$i][0] Then ___TCP_CloseSocket($__TCP_Sockets[$i][0]) EndIf Next ReDim $__TCP_Sockets[1][11] If $__TCP_hWs2_32 <> -1 Then DllClose($__TCP_hWs2_32) $__TCP_hWs2_32 = -1 TCPShutdown() $__TCP_Initialized = False Return 1 EndFunc ;==>_TCP_Shutdown ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Server_Create ; Description ...: Create TCP server with async support ; Syntax ........: _TCP_Server_Create($iPort[, $sIP = "0.0.0.0"[, $iMaxPending = 5]]) ; Parameters ....: $iPort - Port to listen on ; $sIP - [optional] IP address (default = "0.0.0.0" - all interfaces) ; $iMaxPending - [optional] Max pending connections (default = 5) ; Return values .: Success - Socket handle ; Failure - -1 and sets @error ; =============================================================================================================================== Func _TCP_Server_Create($iPort, $sIP = "0.0.0.0", $iMaxPending = 5) If Not $__TCP_Initialized Then If Not _TCP_Startup() Then Return SetError(@error, 0, -1) EndIf Local $hSocket = ___TCP_Socket() If @error Then Return SetError(@error, 0, -1) ; Bind socket Local $tSockAddr = ___TCP_SockAddr($sIP, $iPort) If @error Then ___TCP_CloseSocket($hSocket) Return SetError(@error, 0, -1) EndIf Local $aRet = DllCall($__TCP_hWs2_32, "int", "bind", "uint", $hSocket, "ptr", DllStructGetPtr($tSockAddr), "int", DllStructGetSize($tSockAddr)) If @error Or $aRet[0] <> 0 Then ___TCP_CloseSocket($hSocket) Return SetError(-1, ___TCP_WSAGetLastError(), -1) EndIf ; Listen $aRet = DllCall($__TCP_hWs2_32, "int", "listen", "uint", $hSocket, "int", $iMaxPending) If @error Or $aRet[0] <> 0 Then ___TCP_CloseSocket($hSocket) Return SetError(-1, ___TCP_WSAGetLastError(), -1) EndIf ; Setup async Local $iMsgID = 0x0400 + UBound($__TCP_Sockets) If Not ___TCP_AsyncSelect($hSocket, $__TCP_AsyncWindow, $iMsgID, $FD_ACCEPT) Then ___TCP_CloseSocket($hSocket) Return SetError(@error, @extended, -1) EndIf GUIRegisterMsg($iMsgID, "___TCP_Server_OnAccept") ; Store socket info ReDim $__TCP_Sockets[UBound($__TCP_Sockets) + 1][11] Local $idx = UBound($__TCP_Sockets) - 1 $__TCP_Sockets[$idx][0] = $hSocket $__TCP_Sockets[$idx][1] = $iMsgID $__TCP_Sockets[$idx][7] = $sIP $__TCP_Sockets[$idx][8] = $iPort $__TCP_Sockets[$idx][9] = True ; isServer $__TCP_Sockets[$idx][10] = 0 ; parentServer Return $hSocket EndFunc ;==>_TCP_Server_Create ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Server_Stop ; Description ...: Stop server and close all client connections ; Syntax ........: _TCP_Server_Stop($hSocket) ; Parameters ....: $hSocket - Server socket handle ; Return values .: Success - 1 ; Failure - 0 and sets @error ; =============================================================================================================================== Func _TCP_Server_Stop($hSocket) Local $iServerIdx = ___TCP_FindSocket($hSocket) If $iServerIdx < 0 Then Return SetError(-4, 0, 0) ; Close all clients of this server For $i = UBound($__TCP_Sockets) - 1 To 0 Step -1 If $i <> $iServerIdx And $__TCP_Sockets[$i][0] Then If Not $__TCP_Sockets[$i][9] Then ; Not a server ___TCP_CloseSocket($__TCP_Sockets[$i][0]) ___TCP_ArrayDelete($__TCP_Sockets, $i) EndIf EndIf Next ; Close server socket ___TCP_CloseSocket($hSocket) ___TCP_ArrayDelete($__TCP_Sockets, $iServerIdx) Return 1 EndFunc ;==>_TCP_Server_Stop ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Client_Create ; Description ...: Create TCP client connection with timeout and async support ; Syntax ........: _TCP_Client_Create($sIP, $iPort[, $sSourceIP = ""[, $iSourcePort = 0[, $iTimeout = 0]]]) ; Parameters ....: $sIP - Server IP address ; $iPort - Server port ; $sSourceIP - [optional] Local IP to bind (default = "") ; $iSourcePort - [optional] Local port to bind (default = 0) ; $iTimeout - [optional] Connection timeout in ms (0 = async without waiting) ; Return values .: Success - Socket handle ; Failure - -1 and sets @error ; =============================================================================================================================== Func _TCP_Client_Create($sIP, $iPort, $sSourceIP = "", $iSourcePort = 0, $iTimeout = 0) If Not $__TCP_Initialized Then If Not _TCP_Startup() Then Return SetError(@error, 0, -1) EndIf ; Validate parameters If Not ($iPort > 0 And $iPort < 65535) Then Return SetError(-4, 0, -1) If Not ($iSourcePort >= 0 And $iSourcePort < 65535) Then Return SetError(-4, 0, -1) Local $hSocket = ___TCP_Socket() If @error Then Return SetError(@error, 0, -1) ; Bind source if specified If $sSourceIP <> "" Or $iSourcePort > 0 Then Local $tSockAddr = ___TCP_SockAddr($sSourceIP <> "" ? $sSourceIP : "0.0.0.0", $iSourcePort) If @error Then ___TCP_CloseSocket($hSocket) Return SetError(@error, 0, -1) EndIf Local $aRet = DllCall($__TCP_hWs2_32, "int", "bind", "uint", $hSocket, "ptr", DllStructGetPtr($tSockAddr), "int", DllStructGetSize($tSockAddr)) If @error Or $aRet[0] <> 0 Then ___TCP_CloseSocket($hSocket) Return SetError(-1, ___TCP_WSAGetLastError(), -1) EndIf EndIf ; Store socket info BEFORE async setup ReDim $__TCP_Sockets[UBound($__TCP_Sockets) + 1][11] Local $idx = UBound($__TCP_Sockets) - 1 $__TCP_Sockets[$idx][0] = $hSocket $__TCP_Sockets[$idx][7] = $sIP $__TCP_Sockets[$idx][8] = $iPort $__TCP_Sockets[$idx][9] = False ; isClient $__TCP_Sockets[$idx][10] = 0 ; parentServer ; Setup async - IMPORTANT: Do this before connect Local $iMsgID = 0x0400 + $idx $__TCP_Sockets[$idx][1] = $iMsgID If Not ___TCP_AsyncSelect($hSocket, $__TCP_AsyncWindow, $iMsgID, BitOR($FD_READ, $FD_WRITE, $FD_CONNECT, $FD_CLOSE)) Then ___TCP_CloseSocket($hSocket) ___TCP_ArrayDelete($__TCP_Sockets, $idx) Return SetError(@error, @extended, -1) EndIf GUIRegisterMsg($iMsgID, "___TCP_Client_OnSocketEvent") ; Connect Local $tSockAddr = ___TCP_SockAddr($sIP, $iPort) If @error Then ___TCP_CloseSocket($hSocket) ___TCP_ArrayDelete($__TCP_Sockets, $idx) Return SetError(@error, 0, -1) EndIf Local $aRet = DllCall($__TCP_hWs2_32, "int", "connect", "uint", $hSocket, "ptr", DllStructGetPtr($tSockAddr), "int", DllStructGetSize($tSockAddr)) ; For async sockets, connect() returns SOCKET_ERROR with WSAEWOULDBLOCK Local $iError = ___TCP_WSAGetLastError() ; Check if connected immediately (rare for TCP) If Not @error And $aRet[0] = 0 Then ; Connected immediately - call connect callback if set Return $hSocket EndIf ; WSAEWOULDBLOCK (10035) is normal for async connect If $iError <> 10035 And $iError <> 0 Then ___TCP_CloseSocket($hSocket) ___TCP_ArrayDelete($__TCP_Sockets, $idx) Return SetError(-1, $iError, -1) EndIf ; Wait for connection if timeout specified If $iTimeout > 0 Then Local $hTimer = TimerInit() Local $bConnected = False While TimerDiff($hTimer) < $iTimeout Sleep(10) ; Check if socket still exists (might have been connected via callback) Local $iCheckIdx = ___TCP_FindSocket($hSocket) If $iCheckIdx >= 0 Then ; Try to check connection status Local $tErr = DllStructCreate("int") Local $aCheck = DllCall($__TCP_hWs2_32, "int", "getsockopt", _ "uint", $hSocket, "int", 0xFFFF, "int", 0x1007, _ "ptr", DllStructGetPtr($tErr), "int*", DllStructGetSize($tErr)) ; SOL_SOCKET, SO_ERROR If Not @error And $aCheck[0] = 0 Then Local $iSockErr = DllStructGetData($tErr, 1) If $iSockErr = 0 Then ; Connected successfully $bConnected = True ExitLoop ElseIf $iSockErr <> 10035 Then ; Not WSAEWOULDBLOCK ; Connection error ___TCP_CloseSocket($hSocket) ___TCP_ArrayDelete($__TCP_Sockets, $iCheckIdx) Return SetError(-1, $iSockErr, -1) EndIf EndIf Else ; Socket was removed (probably connected and then disconnected) ExitLoop EndIf WEnd ; Check timeout If Not $bConnected And TimerDiff($hTimer) >= $iTimeout Then Local $iCheckIdx = ___TCP_FindSocket($hSocket) If $iCheckIdx >= 0 Then ___TCP_CloseSocket($hSocket) ___TCP_ArrayDelete($__TCP_Sockets, $iCheckIdx) EndIf Return SetError(-6, 0, -1) ; Timeout EndIf EndIf Return $hSocket EndFunc ;==>_TCP_Client_Create ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Client_Stop ; Description ...: Close client connection ; Syntax ........: _TCP_Client_Stop($hSocket) ; Parameters ....: $hSocket - Client socket handle ; Return values .: Success - 1 ; Failure - 0 and sets @error ; =============================================================================================================================== Func _TCP_Client_Stop($hSocket) Local $idx = ___TCP_FindSocket($hSocket) If $idx < 0 Then Return SetError(-4, 0, 0) ___TCP_Shutdown($hSocket) ___TCP_CloseSocket($hSocket) ___TCP_ArrayDelete($__TCP_Sockets, $idx) Return 1 EndFunc ;==>_TCP_Client_Stop ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Send ; Description ...: Send data through socket ; Syntax ........: _TCP_Send($hSocket, $vData[, $iFlag = 0]) ; Parameters ....: $hSocket - Socket handle ; $vData - Data to send (string or binary) ; $iFlag - [optional] $TCP_DEFAULT_DATA (0) or $TCP_EOT_DATA (2) ; Return values .: Success - Number of bytes sent ; Failure - -1 and sets @error ; =============================================================================================================================== Func _TCP_Send($hSocket, $vData, $iFlag = 0) If BitAND($iFlag, $TCP_EOT_DATA) Then $vData = String($vData) & Chr(3) Local $iResult = TCPSend($hSocket, $vData) Return SetError(@error, 0, $iResult) EndFunc ;==>_TCP_Send ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Recv ; Description ...: Receive data from socket ; Syntax ........: _TCP_Recv($hSocket, $iMaxLen[, $iFlag = 0]) ; Parameters ....: $hSocket - Socket handle ; $iMaxLen - Max bytes to receive ; $iFlag - [optional] $TCP_DEFAULT_DATA (0), $TCP_BINARY_DATA (1), or $TCP_EOT_DATA (2) ; Return values .: Success - Data received ; Failure - "" and sets @error/@extended ; Remarks .......: @extended = 1 if connection closed, = 2 if EOT reached ; =============================================================================================================================== Func _TCP_Recv($hSocket, $iMaxLen, $iFlag = 0) If Not $__TCP_Initialized Then Return SetError(-1, 0, "") Local $tBuf If BitAND($iFlag, $TCP_BINARY_DATA) Then $tBuf = DllStructCreate("byte[" & $iMaxLen & "]") Else $tBuf = DllStructCreate("char[" & $iMaxLen & "]") EndIf If Not ___TCP_SetNonBlocking($hSocket) Then Return SetError(@error, 0, "") Local $aRet = DllCall($__TCP_hWs2_32, "int", "recv", "uint", $hSocket, "ptr", DllStructGetPtr($tBuf), "int", $iMaxLen, "int", 0) If @error Then Return SetError(-1, 0, "") If $aRet[0] = -1 Or $aRet[0] = 4294967295 Then Local $iError = ___TCP_WSAGetLastError() If $iError = 0 Or $iError = 10035 Then Return SetError(0, 0, "") ; WSAEWOULDBLOCK - no data Return SetError($iError, 0, "") EndIf If $aRet[0] = 0 Then Return SetError(0, 1, "") ; Connection closed Local $sResult = DllStructGetData($tBuf, 1) If BitAND($iFlag, $TCP_EOT_DATA) Then If StringRight($sResult, 1) = Chr(3) Then $sResult = StringTrimRight($sResult, 1) Return SetError(0, 2, $sResult) ; EOT reached EndIf EndIf Return SetError(0, 0, $sResult) EndFunc ;==>_TCP_Recv ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Server_OnNewClient ; Description ...: Register callback when new client connects ; Syntax ........: _TCP_Server_OnNewClient($hServerSocket, $sFunction) ; Parameters ....: $hServerSocket - Server socket handle ; $sFunction - Callback function name: Func OnNewClient($hClientSocket, $iError) ; Return values .: Success - 1 ; Failure - 0 and sets @error ; Example .......: _TCP_Server_OnNewClient($hServer, "OnNewClient") ; Func OnNewClient($hClient, $iError) ; If $iError Then ConsoleWrite("Accept error: " & $iError & @CRLF) ; Else ConsoleWrite("New client: " & $hClient & @CRLF) ; EndFunc ; =============================================================================================================================== Func _TCP_Server_OnNewClient($hServerSocket, $sFunction) Return _TCP_RegisterEvent($hServerSocket, $TCP_EVENT_NEWCLIENT, $sFunction) EndFunc ;==>_TCP_Server_OnNewClient ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Server_OnReceive ; Description ...: Register callback when server receives data from client ; Syntax ........: _TCP_Server_OnReceive($hServerSocket, $sFunction) ; Parameters ....: $hServerSocket - Server socket handle ; $sFunction - Callback function name: Func OnReceive($hClientSocket, $sData, $iError) ; Return values .: Success - 1 ; Failure - 0 and sets @error ; Example .......: _TCP_Server_OnReceive($hServer, "OnReceive") ; Func OnReceive($hClient, $sData, $iError) ; If Not $iError Then _TCP_Send($hClient, "Echo: " & $sData) ; EndFunc ; =============================================================================================================================== Func _TCP_Server_OnReceive($hServerSocket, $sFunction) Return _TCP_RegisterEvent($hServerSocket, $TCP_EVENT_RECEIVE, $sFunction) EndFunc ;==>_TCP_Server_OnReceive ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Server_OnSend ; Description ...: Register callback when server is ready to send data ; Syntax ........: _TCP_Server_OnSend($hServerSocket, $sFunction) ; Parameters ....: $hServerSocket - Server socket handle ; $sFunction - Callback function name: Func OnSend($hClientSocket, $iError) ; Return values .: Success - 1 ; Failure - 0 and sets @error ; Example .......: _TCP_Server_OnSend($hServer, "OnSend") ; Func OnSend($hClient, $iError) ; If Not $iError Then ConsoleWrite("Ready to send on: " & $hClient & @CRLF) ; EndFunc ; =============================================================================================================================== Func _TCP_Server_OnSend($hServerSocket, $sFunction) Return _TCP_RegisterEvent($hServerSocket, $TCP_EVENT_SEND, $sFunction) EndFunc ;==>_TCP_Server_OnSend ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Server_OnDisconnect ; Description ...: Register callback when client disconnects ; Syntax ........: _TCP_Server_OnDisconnect($hServerSocket, $sFunction) ; Parameters ....: $hServerSocket - Server socket handle ; $sFunction - Callback function name: Func OnDisconnect($hClientSocket, $iError) ; Return values .: Success - 1 ; Failure - 0 and sets @error ; Example .......: _TCP_Server_OnDisconnect($hServer, "OnDisconnect") ; Func OnDisconnect($hClient, $iError) ; ConsoleWrite("Client disconnected: " & $hClient & @CRLF) ; EndFunc ; =============================================================================================================================== Func _TCP_Server_OnDisconnect($hServerSocket, $sFunction) Return _TCP_RegisterEvent($hServerSocket, $TCP_EVENT_DISCONNECT, $sFunction) EndFunc ;==>_TCP_Server_OnDisconnect ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Client_OnConnect ; Description ...: Register callback when client connection succeeds/fails ; Syntax ........: _TCP_Client_OnConnect($hClientSocket, $sFunction) ; Parameters ....: $hClientSocket - Client socket handle ; $sFunction - Callback function name: Func OnConnect($hSocket, $iError) ; Return values .: Success - 1 ; Failure - 0 and sets @error ; Example .......: _TCP_Client_OnConnect($hClient, "OnConnect") ; Func OnConnect($hSocket, $iError) ; If $iError Then ConsoleWrite("Connect failed: " & $iError & @CRLF) ; Else ConsoleWrite("Connected successfully!" & @CRLF) ; EndFunc ; =============================================================================================================================== Func _TCP_Client_OnConnect($hClientSocket, $sFunction) Return _TCP_RegisterEvent($hClientSocket, $TCP_EVENT_CONNECT, $sFunction) EndFunc ;==>_TCP_Client_OnConnect ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Client_OnReceive ; Description ...: Register callback when client receives data from server ; Syntax ........: _TCP_Client_OnReceive($hClientSocket, $sFunction) ; Parameters ....: $hClientSocket - Client socket handle ; $sFunction - Callback function name: Func OnReceive($hSocket, $sData, $iError) ; Return values .: Success - 1 ; Failure - 0 and sets @error ; Example .......: _TCP_Client_OnReceive($hClient, "OnReceive") ; Func OnReceive($hSocket, $sData, $iError) ; If Not $iError Then ConsoleWrite("Received: " & $sData & @CRLF) ; EndFunc ; =============================================================================================================================== Func _TCP_Client_OnReceive($hClientSocket, $sFunction) Return _TCP_RegisterEvent($hClientSocket, $TCP_EVENT_RECEIVE, $sFunction) EndFunc ;==>_TCP_Client_OnReceive ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Client_OnSend ; Description ...: Register callback when client is ready to send data ; Syntax ........: _TCP_Client_OnSend($hClientSocket, $sFunction) ; Parameters ....: $hClientSocket - Client socket handle ; $sFunction - Callback function name: Func OnSend($hSocket, $iError) ; Return values .: Success - 1 ; Failure - 0 and sets @error ; Example .......: _TCP_Client_OnSend($hClient, "OnSend") ; Func OnSend($hSocket, $iError) ; If Not $iError Then ConsoleWrite("Ready to send" & @CRLF) ; EndFunc ; =============================================================================================================================== Func _TCP_Client_OnSend($hClientSocket, $sFunction) Return _TCP_RegisterEvent($hClientSocket, $TCP_EVENT_SEND, $sFunction) EndFunc ;==>_TCP_Client_OnSend ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Client_OnDisconnect ; Description ...: Register callback when client disconnects ; Syntax ........: _TCP_Client_OnDisconnect($hClientSocket, $sFunction) ; Parameters ....: $hClientSocket - Client socket handle ; $sFunction - Callback function name: Func OnDisconnect($hSocket, $iError) ; Return values .: Success - 1 ; Failure - 0 and sets @error ; Example .......: _TCP_Client_OnDisconnect($hClient, "OnDisconnect") ; Func OnDisconnect($hSocket, $iError) ; ConsoleWrite("Disconnected from server" & @CRLF) ; EndFunc ; =============================================================================================================================== Func _TCP_Client_OnDisconnect($hClientSocket, $sFunction) Return _TCP_RegisterEvent($hClientSocket, $TCP_EVENT_DISCONNECT, $sFunction) EndFunc ;==>_TCP_Client_OnDisconnect ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_OnConnect ; Description ...: Alias of _TCP_Client_OnConnect for simpler syntax ; Syntax ........: _TCP_OnConnect($hSocket, $sFunction) ; Parameters ....: $hSocket - Socket handle ; $sFunction - Callback function name ; Return values .: Success - 1 ; Failure - 0 and sets @error ; =============================================================================================================================== Func _TCP_OnConnect($hSocket, $sFunction) Return _TCP_Client_OnConnect($hSocket, $sFunction) EndFunc ;==>_TCP_OnConnect ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_OnReceive ; Description ...: Universal callback for both client and server ; Syntax ........: _TCP_OnReceive($hSocket, $sFunction) ; Parameters ....: $hSocket - Socket handle (client or server) ; $sFunction - Callback function name ; Return values .: Success - 1 ; Failure - 0 and sets @error ; Remarks .......: Can be used for both client and server sockets ; =============================================================================================================================== Func _TCP_OnReceive($hSocket, $sFunction) Return _TCP_RegisterEvent($hSocket, $TCP_EVENT_RECEIVE, $sFunction) EndFunc ;==>_TCP_OnReceive ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_OnSend ; Description ...: Universal callback for both client and server ; Syntax ........: _TCP_OnSend($hSocket, $sFunction) ; Parameters ....: $hSocket - Socket handle (client or server) ; $sFunction - Callback function name ; Return values .: Success - 1 ; Failure - 0 and sets @error ; =============================================================================================================================== Func _TCP_OnSend($hSocket, $sFunction) Return _TCP_RegisterEvent($hSocket, $TCP_EVENT_SEND, $sFunction) EndFunc ;==>_TCP_OnSend ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_OnDisconnect ; Description ...: Universal callback for both client and server ; Syntax ........: _TCP_OnDisconnect($hSocket, $sFunction) ; Parameters ....: $hSocket - Socket handle (client or server) ; $sFunction - Callback function name ; Return values .: Success - 1 ; Failure - 0 and sets @error ; =============================================================================================================================== Func _TCP_OnDisconnect($hSocket, $sFunction) Return _TCP_RegisterEvent($hSocket, $TCP_EVENT_DISCONNECT, $sFunction) EndFunc ;==>_TCP_OnDisconnect ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_RegisterEvent ; Description ...: Internal function to register event callbacks ; Syntax ........: _TCP_RegisterEvent($hSocket, $iEvent, $sFunction) ; Parameters ....: $hSocket - Socket handle ; $iEvent - Event type constant ; $sFunction - Callback function name ; Return values .: Success - 1 ; Failure - 0 and sets @error ; Remarks .......: This is an internal function. Use specific _TCP_*_On* functions instead ; =============================================================================================================================== Func _TCP_RegisterEvent($hSocket, $iEvent, $sFunction) Local $idx = ___TCP_FindSocket($hSocket) If $idx < 0 Then Return SetError(-4, 0, 0) Switch $iEvent Case $TCP_EVENT_SEND $__TCP_Sockets[$idx][3] = $sFunction Case $TCP_EVENT_RECEIVE $__TCP_Sockets[$idx][2] = $sFunction Case $TCP_EVENT_CONNECT $__TCP_Sockets[$idx][4] = $sFunction Case $TCP_EVENT_DISCONNECT $__TCP_Sockets[$idx][5] = $sFunction Case $TCP_EVENT_NEWCLIENT $__TCP_Sockets[$idx][6] = $sFunction Case Else Return SetError(-4, 0, 0) EndSwitch Return 1 EndFunc ;==>_TCP_RegisterEvent ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Server_ClientList ; Description ...: Get list of client sockets ; Syntax ........: _TCP_Server_ClientList() ; Return values .: Array of client sockets, [0] = count ; =============================================================================================================================== Func _TCP_Server_ClientList() Local $aClients[1] = [0] For $i = 0 To UBound($__TCP_Sockets) - 1 If $__TCP_Sockets[$i][0] And Not $__TCP_Sockets[$i][9] Then ; Not a server socket ReDim $aClients[UBound($aClients) + 1] $aClients[UBound($aClients) - 1] = $__TCP_Sockets[$i][0] $aClients[0] += 1 EndIf Next Return $aClients EndFunc ;==>_TCP_Server_ClientList ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Server_ClientIP ; Description ...: Get IP address of client ; Syntax ........: _TCP_Server_ClientIP($hSocket) ; Parameters ....: $hSocket - Client socket handle ; Return values .: Success - IP address string ; Failure - "" and sets @error ; =============================================================================================================================== Func _TCP_Server_ClientIP($hSocket) Local $tSockAddr = DllStructCreate("short;ushort;uint;char[8]") Local $aRet = DllCall($__TCP_hWs2_32, "int", "getpeername", "int", $hSocket, "ptr", DllStructGetPtr($tSockAddr), "int*", DllStructGetSize($tSockAddr)) If @error Or $aRet[0] <> 0 Then Return SetError(-1, 0, "") $aRet = DllCall($__TCP_hWs2_32, "str", "inet_ntoa", "int", DllStructGetData($tSockAddr, 3)) If @error Then Return SetError(-1, 0, "") Return $aRet[0] EndFunc ;==>_TCP_Server_ClientIP ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Server_Broadcast ; Description ...: Send data to all clients ; Syntax ........: _TCP_Server_Broadcast($vData) ; Parameters ....: $vData - Data to broadcast ; Return values .: Number of clients sent to ; =============================================================================================================================== Func _TCP_Server_Broadcast($vData) Local $iCount = 0 For $i = 0 To UBound($__TCP_Sockets) - 1 If $__TCP_Sockets[$i][0] And Not $__TCP_Sockets[$i][9] Then TCPSend($__TCP_Sockets[$i][0], $vData) $iCount += 1 EndIf Next Return $iCount EndFunc ;==>_TCP_Server_Broadcast ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Server_DisconnectClient ; Description ...: Disconnect a client ; Syntax ........: _TCP_Server_DisconnectClient($hSocket) ; Parameters ....: $hSocket - Client socket handle ; Return values .: Success - 1 ; Failure - 0 and sets @error ; =============================================================================================================================== Func _TCP_Server_DisconnectClient($hSocket) Return _TCP_Client_Stop($hSocket) EndFunc ;==>_TCP_Server_DisconnectClient ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_NameToIP ; Description ...: Convert hostname to IP address ; Syntax ........: _TCP_NameToIP($sName) ; Parameters ....: $sName - Hostname ; Return values .: Success - IP address ; Failure - "" and sets @error ; =============================================================================================================================== Func _TCP_NameToIP($sName) Local $sIP = TCPNameToIP($sName) Return SetError(@error, 0, $sIP) EndFunc ;==>_TCP_NameToIP ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_GetIPs ; Description ...: Get local and public IP addresses ; Syntax ........: _TCP_GetIPs([$sServerName = ""]) ; Parameters ....: $sServerName - [optional] Server to check public IP ; Return values .: Success - Array [localIP, publicIP] ; Failure - -1 and sets @error ; =============================================================================================================================== Func _TCP_GetIPs($sServerName = "") If Not $__TCP_Initialized Then If Not _TCP_Startup() Then Return SetError(@error, 0, -1) EndIf Local $aServers[][2] = [["www.myexternalip.com/raw"], ["checkip.dyndns.org/"], ["bot.whatismyipaddress.com/"]] If $sServerName <> "" Then ReDim $aServers[UBound($aServers) + 1][2] $aServers[UBound($aServers) - 1][0] = $sServerName EndIf Local $sLocalIP = "", $sPublicIP = "" Local $hSocket = ___TCP_Socket() If @error Then Return SetError(@error, 0, -1) For $i = 0 To UBound($aServers) - 1 Local $sHost = StringRegExp($aServers[$i][0], "^([^/]+)", 1) If @error Then ContinueLoop $sHost = $sHost[0] Local $sServerIP = TCPNameToIP($sHost) If $sServerIP = "" Then ContinueLoop ; Connect Local $tSockAddr = ___TCP_SockAddr($sServerIP, 80) If @error Then ContinueLoop ___TCP_SetNonBlocking($hSocket) DllCall($__TCP_hWs2_32, "int", "connect", "uint", $hSocket, "ptr", DllStructGetPtr($tSockAddr), "int", DllStructGetSize($tSockAddr)) ; Wait for connection If Not ___TCP_WaitForConnect($hSocket, 2000) Then ___TCP_CloseSocket($hSocket) $hSocket = ___TCP_Socket() ContinueLoop EndIf ; Get local IP If $sLocalIP = "" Then Local $tLocalAddr = DllStructCreate("short;ushort;uint;char[8]") Local $aRet = DllCall($__TCP_hWs2_32, "int", "getsockname", "uint", $hSocket, "ptr", DllStructGetPtr($tLocalAddr), "int*", DllStructGetSize($tLocalAddr)) If Not @error And $aRet[0] = 0 Then $aRet = DllCall($__TCP_hWs2_32, "ptr", "inet_ntoa", "ulong", DllStructGetData($tLocalAddr, 3)) If Not @error And $aRet[0] <> Null Then $sLocalIP = DllStructGetData(DllStructCreate("char[15]", $aRet[0]), 1) EndIf EndIf EndIf ; Get public IP Local $sRequest = "GET /" & StringRegExpReplace($aServers[$i][0], "^[^/]+/?", "") & " HTTP/1.1" & @CRLF & _ "Host: " & $sHost & @CRLF & _ "Connection: close" & @CRLF & @CRLF TCPSend($hSocket, $sRequest) Sleep(500) Local $sRecv = "" Local $hTimer = TimerInit() While TimerDiff($hTimer) < 3000 Local $sChunk = _TCP_Recv($hSocket, 2048) If @extended = 1 Then ExitLoop ; Connection closed $sRecv &= $sChunk If $sChunk = "" Then Sleep(10) WEnd Local $aIP = StringRegExp($sRecv, "((?:\d{1,3}\.){3}\d{1,3})", 3) If Not @error And UBound($aIP) > 0 Then $sPublicIP = $aIP[0] ExitLoop EndIf ___TCP_CloseSocket($hSocket) $hSocket = ___TCP_Socket() Next ___TCP_CloseSocket($hSocket) If $sLocalIP = "" Or $sPublicIP = "" Then Return SetError(-6, 0, -1) Local $aResult[2] = [$sLocalIP, $sPublicIP] Return $aResult EndFunc ;==>_TCP_GetIPs ; #UDP FUNCTIONS# =============================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name ..........: _UDP_Startup ; Description ...: Initialize UDP system ; Syntax ........: _UDP_Startup() ; Return values .: Success - 1 ; Failure - 0 and sets @error ; =============================================================================================================================== Func _UDP_Startup() Local $iResult = UDPStartup() Return SetError(@error, 0, $iResult) EndFunc ;==>_UDP_Startup ; #FUNCTION# ==================================================================================================================== ; Name ..........: _UDP_Shutdown ; Description ...: Shutdown UDP system ; Syntax ........: _UDP_Shutdown() ; Return values .: Success - 1 ; Failure - 0 and sets @error ; =============================================================================================================================== Func _UDP_Shutdown() Local $iResult = UDPShutdown() Return SetError(@error, 0, $iResult) EndFunc ;==>_UDP_Shutdown ; #FUNCTION# ==================================================================================================================== ; Name ..........: _UDP_Bind ; Description ...: Create and bind UDP socket ; Syntax ........: _UDP_Bind([$sSourceIP = ""[, $iSourcePort = 0]]) ; Parameters ....: $sSourceIP - [optional] Local IP to bind (default = "") ; $iSourcePort - [optional] Local port to bind (default = 0) ; Return values .: Success - Socket handle ; Failure - -1 and sets @error ; =============================================================================================================================== Func _UDP_Bind($sSourceIP = "", $iSourcePort = 0) If Not $__TCP_Initialized Then If Not _TCP_Startup() Then Return SetError(@error, 0, -1) EndIf If Not ($iSourcePort >= 0 And $iSourcePort < 65535) Then Return SetError(-4, 0, -1) Local $aRet = DllCall($__TCP_hWs2_32, "uint", "socket", "int", 2, "int", 2, "int", 17) ; AF_INET, SOCK_DGRAM, IPPROTO_UDP If @error Then Return SetError(-1, 0, -1) If $aRet[0] = 4294967295 Or $aRet[0] = -1 Then Return SetError(-1, ___TCP_WSAGetLastError(), -1) Local $hSocket = $aRet[0] ; Bind if IP or port specified If $sSourceIP <> "" Or $iSourcePort > 0 Then Local $tSockAddr = ___TCP_SockAddr($sSourceIP <> "" ? $sSourceIP : "0.0.0.0", $iSourcePort) If @error Then ___TCP_CloseSocket($hSocket) Return SetError(@error, 0, -1) EndIf $aRet = DllCall($__TCP_hWs2_32, "int", "bind", "uint", $hSocket, "ptr", DllStructGetPtr($tSockAddr), "int", DllStructGetSize($tSockAddr)) If @error Or $aRet[0] <> 0 Then ___TCP_CloseSocket($hSocket) Return SetError(-1, ___TCP_WSAGetLastError(), -1) EndIf EndIf Return $hSocket EndFunc ;==>_UDP_Bind ; #FUNCTION# ==================================================================================================================== ; Name ..........: _UDP_SendTo ; Description ...: Send UDP packet to specified address ; Syntax ........: _UDP_SendTo($sIP, $iPort, $vData[, $hSocket = 0]) ; Parameters ....: $sIP - Destination IP address ; $iPort - Destination port ; $vData - Data to send (string or binary) ; $hSocket - [optional] Socket handle (0 = create temporary socket) ; Return values .: Success - Array [bytes_sent, socket_handle] ; Failure - -1 and sets @error ; =============================================================================================================================== Func _UDP_SendTo($sIP, $iPort, $vData, $hSocket = 0) If Not $__TCP_Initialized Then If Not _TCP_Startup() Then Return SetError(@error, 0, -1) EndIf If Not ($iPort > 0 And $iPort < 65535) Then Return SetError(-4, 0, -1) Local $bCloseAfter = False If $hSocket = 0 Then $hSocket = _UDP_Bind() If @error Then Return SetError(@error, 0, -1) $bCloseAfter = True EndIf Local $tSockAddr = ___TCP_SockAddr($sIP, $iPort) If @error Then If $bCloseAfter Then ___TCP_CloseSocket($hSocket) Return SetError(@error, 0, -1) EndIf Local $tBuf, $iLen If IsBinary($vData) Then $iLen = BinaryLen($vData) $tBuf = DllStructCreate("byte[" & $iLen & "]") DllStructSetData($tBuf, 1, $vData) Else $vData = String($vData) $iLen = StringLen($vData) $tBuf = DllStructCreate("char[" & $iLen & "]") DllStructSetData($tBuf, 1, $vData) EndIf ___TCP_SetNonBlocking($hSocket) Local $aRet = DllCall($__TCP_hWs2_32, "int", "sendto", _ "uint", $hSocket, "ptr", DllStructGetPtr($tBuf), "int", $iLen, "int", 0, _ "ptr", DllStructGetPtr($tSockAddr), "int", DllStructGetSize($tSockAddr)) If @error Or $aRet[0] = -1 Or $aRet[0] = 4294967295 Then Local $iError = ___TCP_WSAGetLastError() If $bCloseAfter Then ___TCP_CloseSocket($hSocket) Return SetError($iError, 0, -1) EndIf Local $aResult[2] = [$aRet[0], $hSocket] If $bCloseAfter Then ___TCP_CloseSocket($hSocket) Return $aResult EndFunc ;==>_UDP_SendTo ; #FUNCTION# ==================================================================================================================== ; Name ..........: _UDP_RecvFrom ; Description ...: Receive UDP packet ; Syntax ........: _UDP_RecvFrom($hSocket, $iMaxLen[, $iFlag = 0]) ; Parameters ....: $hSocket - Socket handle ; $iMaxLen - Max bytes to receive ; $iFlag - [optional] 0 = string, 1 = binary ; Return values .: Success - Array [data, source_ip, source_port] ; Failure - -1 and sets @error ; =============================================================================================================================== Func _UDP_RecvFrom($hSocket, $iMaxLen, $iFlag = 0) If Not $__TCP_Initialized Then Return SetError(-1, 0, -1) If $iMaxLen < 1 Then Return SetError(-4, 0, -1) If $iFlag <> 0 And $iFlag <> 1 Then Return SetError(-4, 0, -1) ___TCP_SetNonBlocking($hSocket) Local $tSockAddr = DllStructCreate("short;ushort;uint;char[8]") Local $tBuf If $iFlag = 1 Then $tBuf = DllStructCreate("byte[" & $iMaxLen & "]") Else $tBuf = DllStructCreate("char[" & $iMaxLen & "]") EndIf Local $aRet = DllCall($__TCP_hWs2_32, "int", "recvfrom", _ "uint", $hSocket, "ptr", DllStructGetPtr($tBuf), "int", $iMaxLen, "int", 0, _ "ptr", DllStructGetPtr($tSockAddr), "int*", DllStructGetSize($tSockAddr)) If @error Then Return SetError(-1, 0, -1) If $aRet[0] = -1 Or $aRet[0] = 4294967295 Then Local $iError = ___TCP_WSAGetLastError() If $iError = 0 Or $iError = 10035 Then Return SetError(0, 0, -1) ; WSAEWOULDBLOCK Return SetError($iError, 0, -1) EndIf Local $aResult[3] $aResult[0] = DllStructGetData($tBuf, 1) $aRet = DllCall($__TCP_hWs2_32, "ptr", "inet_ntoa", "ulong", DllStructGetData($tSockAddr, 3)) If @error Or $aRet[0] = Null Then Return SetError(-1, 0, -1) $aResult[1] = DllStructGetData(DllStructCreate("char[15]", $aRet[0]), 1) $aRet = DllCall($__TCP_hWs2_32, "ushort", "ntohs", "ushort", DllStructGetData($tSockAddr, 2)) If @error Then Return SetError(-1, 0, -1) $aResult[2] = $aRet[0] Return $aResult EndFunc ;==>_UDP_RecvFrom ; #FUNCTION# ==================================================================================================================== ; Name ..........: _UDP_CloseSocket ; Description ...: Close UDP socket ; Syntax ........: _UDP_CloseSocket($vSocket) ; Parameters ....: $vSocket - Socket handle or array from _UDP_SendTo ; Return values .: Success - 1 ; Failure - 0 and sets @error ; =============================================================================================================================== Func _UDP_CloseSocket($vSocket) Local $hSocket If IsArray($vSocket) And UBound($vSocket) = 2 Then $hSocket = $vSocket[1] Else $hSocket = $vSocket EndIf If $hSocket < 1 Then Return SetError(-4, 0, 0) Local $aRet = DllCall($__TCP_hWs2_32, "int", "closesocket", "uint", $hSocket) If @error Or $aRet[0] <> 0 Then Return SetError(___TCP_WSAGetLastError(), 0, 0) EndIf Return 1 EndFunc ;==>_UDP_CloseSocket ; #INTERNAL FUNCTIONS# ========================================================================================================== Func ___TCP_Socket() Local $aRet = DllCall($__TCP_hWs2_32, "uint", "socket", "int", 2, "int", 1, "int", 6) ; AF_INET, SOCK_STREAM, IPPROTO_TCP If @error Then Return SetError(-1, 0, -1) If $aRet[0] = 4294967295 Or $aRet[0] = -1 Then Return SetError(-1, ___TCP_WSAGetLastError(), -1) Return $aRet[0] EndFunc ;==>___TCP_Socket Func ___TCP_CloseSocket($hSocket) DllCall($__TCP_hWs2_32, "int", "closesocket", "uint", $hSocket) Return TCPCloseSocket($hSocket) EndFunc ;==>___TCP_CloseSocket Func ___TCP_Shutdown($hSocket) DllCall($__TCP_hWs2_32, "int", "shutdown", "uint", $hSocket, "int", 2) ; SD_BOTH EndFunc ;==>___TCP_Shutdown Func ___TCP_SockAddr($sIP, $iPort) Local $tAddr = DllStructCreate("short sin_family;ushort sin_port;uint S_addr;char sin_zero[8]") If @error Then Return SetError(-1, 0, False) DllStructSetData($tAddr, "sin_family", 2) ; AF_INET Local $aRet = DllCall($__TCP_hWs2_32, "ushort", "htons", "ushort", $iPort) If @error Then Return SetError(-1, 0, False) DllStructSetData($tAddr, "sin_port", $aRet[0]) If $sIP = "" Or $sIP = "0.0.0.0" Then DllStructSetData($tAddr, "S_addr", 0x00000000) Else $aRet = DllCall($__TCP_hWs2_32, "ulong", "inet_addr", "str", $sIP) If @error Or $aRet[0] = -1 Or $aRet[0] = 4294967295 Then Return SetError(-4, 0, False) DllStructSetData($tAddr, "S_addr", $aRet[0]) EndIf Return $tAddr EndFunc ;==>___TCP_SockAddr Func ___TCP_SetNonBlocking($hSocket) Local $aRet = DllCall($__TCP_hWs2_32, "int", "ioctlsocket", "uint", $hSocket, "long", 0x8004667e, "ulong*", 1) ; FIONBIO If @error Or $aRet[0] <> 0 Then Return SetError(-1, ___TCP_WSAGetLastError(), False) Return True EndFunc ;==>___TCP_SetNonBlocking Func ___TCP_AsyncSelect($hSocket, $hWnd, $iMsg, $iEvents) ; WSAAsyncSelect automatically sets socket to non-blocking mode Local $aRet = DllCall($__TCP_hWs2_32, "int", "WSAAsyncSelect", _ "uint", $hSocket, "hwnd", $hWnd, "uint", $iMsg, "int", $iEvents) If @error Or $aRet[0] <> 0 Then Return SetError(-1, ___TCP_WSAGetLastError(), False) Return True EndFunc ;==>___TCP_AsyncSelect Func ___TCP_WaitForConnect($hSocket, $iTimeout) Local $tFdWrite = DllStructCreate("uint fd_count;uint fd_array[64]") Local $tFdExcept = DllStructCreate("uint fd_count;uint fd_array[64]") Local $tTimeval = DllStructCreate("long tv_sec;long tv_usec") DllStructSetData($tFdWrite, "fd_count", 1) DllStructSetData($tFdWrite, "fd_array", $hSocket, 1) DllStructSetData($tFdExcept, "fd_count", 1) DllStructSetData($tFdExcept, "fd_array", $hSocket, 1) DllStructSetData($tTimeval, "tv_sec", Floor($iTimeout / 1000)) DllStructSetData($tTimeval, "tv_usec", Mod($iTimeout, 1000) * 1000) Local $aRet = DllCall($__TCP_hWs2_32, "int", "select", _ "int", 0, "ptr", 0, "ptr", DllStructGetPtr($tFdWrite), _ "ptr", DllStructGetPtr($tFdExcept), "ptr", DllStructGetPtr($tTimeval)) If @error Then Return SetError(-1, 0, False) If $aRet[0] = 0 Then Return SetError(-6, 0, False) ; Timeout If $aRet[0] = -1 Then Return SetError(-1, ___TCP_WSAGetLastError(), False) ; Check if connected or error If DllStructGetData($tFdWrite, "fd_count") = 1 Then Return True If DllStructGetData($tFdExcept, "fd_count") = 1 Then Local $tErr = DllStructCreate("int") $aRet = DllCall($__TCP_hWs2_32, "int", "getsockopt", _ "uint", $hSocket, "int", 0xFFFF, "int", 0x1007, _ "ptr", DllStructGetPtr($tErr), "int*", DllStructGetSize($tErr)) ; SOL_SOCKET, SO_ERROR If Not @error And $aRet[0] = 0 Then Return SetError(DllStructGetData($tErr, 1), 0, False) EndIf EndIf Return SetError(-5, 0, False) ; Not connected EndFunc ;==>___TCP_WaitForConnect Func ___TCP_WSAGetLastError() Local $aRet = DllCall($__TCP_hWs2_32, "int", "WSAGetLastError") If @error Then Return 0 Return $aRet[0] EndFunc ;==>___TCP_WSAGetLastError Func ___TCP_FindSocket($hSocket) For $i = 0 To UBound($__TCP_Sockets) - 1 If $__TCP_Sockets[$i][0] = $hSocket Then Return $i Next Return -1 EndFunc ;==>___TCP_FindSocket Func ___TCP_LoWord($iValue) Return BitAND($iValue, 0xFFFF) EndFunc ;==>___TCP_LoWord Func ___TCP_HiWord($iValue) Return BitShift($iValue, 16) EndFunc ;==>___TCP_HiWord Func ___TCP_ArrayDelete(ByRef $aArray, $iElement) If Not IsArray($aArray) Then Return SetError(1, 0, 0) Local $iUBound = UBound($aArray, 1) - 1 If $iUBound < 0 Then Return 0 If $iElement < 0 Then $iElement = 0 If $iElement > $iUBound Then $iElement = $iUBound Switch UBound($aArray, 0) Case 1 For $i = $iElement To $iUBound - 1 $aArray[$i] = $aArray[$i + 1] Next ReDim $aArray[$iUBound] Case 2 Local $iSubMax = UBound($aArray, 2) - 1 For $i = $iElement To $iUBound - 1 For $j = 0 To $iSubMax $aArray[$i][$j] = $aArray[$i + 1][$j] Next Next ReDim $aArray[$iUBound][$iSubMax + 1] Case Else Return SetError(3, 0, 0) EndSwitch Return $iUBound EndFunc ;==>___TCP_ArrayDelete ; #ASYNC EVENT HANDLERS# ======================================================================================================== Func ___TCP_Server_OnAccept($hWnd, $iMsgID, $wParam, $lParam) Local $hSocket = $wParam Local $iError = ___TCP_HiWord($lParam) Local $iEvent = ___TCP_LoWord($lParam) Abs($hWnd) ; Suppress AU3Check warning ; Find server socket Local $iServerIdx = -1 For $i = 0 To UBound($__TCP_Sockets) - 1 If $__TCP_Sockets[$i][1] = $iMsgID Then $iServerIdx = $i ExitLoop EndIf Next If $iServerIdx < 0 Then Return If $iEvent = $FD_ACCEPT Then If Not $iError Then Local $hClient = TCPAccept($hSocket) If $hClient < 0 Then Return ; Setup client async Local $iClientMsgID = 0x0400 + UBound($__TCP_Sockets) ___TCP_AsyncSelect($hClient, $__TCP_AsyncWindow, $iClientMsgID, BitOR($FD_READ, $FD_WRITE, $FD_CLOSE)) GUIRegisterMsg($iClientMsgID, "___TCP_Server_OnClientEvent") ; Store client ReDim $__TCP_Sockets[UBound($__TCP_Sockets) + 1][11] Local $idx = UBound($__TCP_Sockets) - 1 $__TCP_Sockets[$idx][0] = $hClient $__TCP_Sockets[$idx][1] = $iClientMsgID $__TCP_Sockets[$idx][7] = _TCP_Server_ClientIP($hClient) $__TCP_Sockets[$idx][9] = False ; isClient $__TCP_Sockets[$idx][10] = $hSocket ; parentServer ; Call callback If $__TCP_Sockets[$iServerIdx][6] <> "" Then Call($__TCP_Sockets[$iServerIdx][6], $hClient, $iError) EndIf Else ; Error accepting If $__TCP_Sockets[$iServerIdx][6] <> "" Then Call($__TCP_Sockets[$iServerIdx][6], 0, $iError) EndIf EndIf EndIf EndFunc ;==>___TCP_Server_OnAccept Func ___TCP_Server_OnClientEvent($hWnd, $iMsgID, $wParam, $lParam) Local $hSocket = $wParam Local $iError = ___TCP_HiWord($lParam) Local $iEvent = ___TCP_LoWord($lParam) Abs($hWnd) Local $iClientIdx = -1 For $i = 0 To UBound($__TCP_Sockets) - 1 If $__TCP_Sockets[$i][1] = $iMsgID Then $iClientIdx = $i ; BUG FIX: Don't override the actual socket handle from $wParam ; $hSocket = $__TCP_Sockets[$i][0] ; This was causing socket mismatch! ExitLoop EndIf Next If $iClientIdx < 0 Then Return ; Find parent server for this client - CRITICAL FIX for multi-server support Local $iServerIdx = -1 Local $hParentServer = $__TCP_Sockets[$iClientIdx][10] If $hParentServer > 0 Then ; Find the parent server by socket handle For $i = 0 To UBound($__TCP_Sockets) - 1 If $__TCP_Sockets[$i][0] = $hParentServer And $__TCP_Sockets[$i][9] Then $iServerIdx = $i ExitLoop EndIf Next EndIf If $iServerIdx < 0 Then Return Switch $iEvent Case $FD_READ Local $sData = TCPRecv($hSocket, 4096) If $__TCP_Sockets[$iServerIdx][2] <> "" Then Call($__TCP_Sockets[$iServerIdx][2], $hSocket, $sData, $iError) EndIf Case $FD_WRITE If $__TCP_Sockets[$iServerIdx][3] <> "" Then Call($__TCP_Sockets[$iServerIdx][3], $hSocket, $iError) EndIf Case $FD_CLOSE If $__TCP_Sockets[$iServerIdx][5] <> "" Then Call($__TCP_Sockets[$iServerIdx][5], $hSocket, $iError) EndIf ___TCP_Shutdown($hSocket) ___TCP_CloseSocket($hSocket) ___TCP_ArrayDelete($__TCP_Sockets, $iClientIdx) EndSwitch EndFunc ;==>___TCP_Server_OnClientEvent Func ___TCP_Client_OnSocketEvent($hWnd, $iMsgID, $wParam, $lParam) Local $hSocket = $wParam Local $iError = ___TCP_HiWord($lParam) Local $iEvent = ___TCP_LoWord($lParam) Abs($hWnd) Local $iClientIdx = -1 For $i = 0 To UBound($__TCP_Sockets) - 1 If $__TCP_Sockets[$i][1] = $iMsgID Then $iClientIdx = $i ; BUG FIX: Don't override the actual socket handle from $wParam ; $hSocket = $__TCP_Sockets[$i][0] ; This was causing socket mismatch! ExitLoop EndIf Next If $iClientIdx < 0 Then Return Switch $iEvent Case $FD_CONNECT ; Connection completed (success or failure) If $__TCP_Sockets[$iClientIdx][4] <> "" Then Call($__TCP_Sockets[$iClientIdx][4], $hSocket, $iError) EndIf Case $FD_READ Local $sData = TCPRecv($hSocket, 4096) If $__TCP_Sockets[$iClientIdx][2] <> "" Then Call($__TCP_Sockets[$iClientIdx][2], $hSocket, $sData, $iError) EndIf Case $FD_WRITE If $__TCP_Sockets[$iClientIdx][3] <> "" Then Call($__TCP_Sockets[$iClientIdx][3], $hSocket, $iError) EndIf Case $FD_CLOSE If $__TCP_Sockets[$iClientIdx][5] <> "" Then Call($__TCP_Sockets[$iClientIdx][5], $hSocket, $iError) EndIf ___TCP_Shutdown($hSocket) ___TCP_CloseSocket($hSocket) ___TCP_ArrayDelete($__TCP_Sockets, $iClientIdx) EndSwitch EndFunc ;==>___TCP_Client_OnSocketEvent ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Send_Ex ; Description ...: Send data through socket with automatic Base64 encoding ; Syntax ........: _TCP_Send_Ex($hSocket, $vData[, $iFlag = 0]) ; Parameters ....: $hSocket - Socket handle ; $vData - Data to send (string or binary) - auto Base64 encoded ; $iFlag - [optional] $TCP_DEFAULT_DATA (0) or $TCP_EOT_DATA (2) ; Return values .: Success - Number of bytes sent ; Failure - -1 and sets @error ; =============================================================================================================================== Func _TCP_Send_Ex($hSocket, $vData, $iFlag = 0) ; Auto encode to Base64 Local $sEncoded = _Base64Encode($vData) If @error Then Return SetError(@error, 0, -1) If BitAND($iFlag, $TCP_EOT_DATA) Then $sEncoded = $sEncoded & Chr(3) Local $iResult = TCPSend($hSocket, $sEncoded) Return SetError(@error, 0, $iResult) EndFunc ;==>_TCP_Send_Ex ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TCP_Recv_Ex ; Description ...: Receive data from socket with automatic Base64 decoding ; Syntax ........: _TCP_Recv_Ex($hSocket, $iMaxLen[, $iFlag = 0]) ; Parameters ....: $hSocket - Socket handle ; $iMaxLen - Max bytes to receive (after decoding) ; $iFlag - [optional] $TCP_DEFAULT_DATA (0), $TCP_BINARY_DATA (1), or $TCP_EOT_DATA (2) ; Return values .: Success - Data received (decoded from Base64) ; Failure - "" and sets @error/@extended ; Remarks .......: @extended = 1 if connection closed, = 2 if EOT reached ; Data is automatically decoded from Base64 ; =============================================================================================================================== Func _TCP_Recv_Ex($hSocket, $iMaxLen, $iFlag = 0) If Not $__TCP_Initialized Then Return SetError(-1, 0, "") ; Calculate buffer size for Base64 (encoded is ~33% larger) Local $iBase64MaxLen = Int($iMaxLen * 1.35) + 100 Local $tBuf = DllStructCreate("char[" & $iBase64MaxLen & "]") If Not ___TCP_SetNonBlocking($hSocket) Then Return SetError(@error, 0, "") Local $aRet = DllCall($__TCP_hWs2_32, "int", "recv", "uint", $hSocket, "ptr", DllStructGetPtr($tBuf), "int", $iBase64MaxLen, "int", 0) If @error Then Return SetError(-1, 0, "") If $aRet[0] = -1 Or $aRet[0] = 4294967295 Then Local $iError = ___TCP_WSAGetLastError() If $iError = 0 Or $iError = 10035 Then Return SetError(0, 0, "") ; WSAEWOULDBLOCK - no data Return SetError($iError, 0, "") EndIf If $aRet[0] = 0 Then Return SetError(0, 1, "") ; Connection closed Local $sBase64Result = DllStructGetData($tBuf, 1) ; Check for EOT marker Local $bHasEOT = False If BitAND($iFlag, $TCP_EOT_DATA) Then If StringRight($sBase64Result, 1) = Chr(3) Then $sBase64Result = StringTrimRight($sBase64Result, 1) $bHasEOT = True EndIf EndIf ; Auto decode from Base64 Local $sDecoded = _Base64Decode($sBase64Result, True) ; Convert to binary if requested If BitAND($iFlag, $TCP_BINARY_DATA) Then $sDecoded = Binary($sDecoded) EndIf If $bHasEOT Then Return SetError(0, 2, $sDecoded) ; EOT reached EndIf Return SetError(0, 0, $sDecoded) EndFunc ;==>_TCP_Recv_Ex ; #FUNCTION# ==================================================================================================================== ; Name ..........: _Base64Encode ; Description ...: Encode binary data to Base64 string ; Syntax ........: _Base64Encode($bInput[, $bNoCRLF = True]) ; Parameters ....: $bInput - Binary data to encode (can also accept ASCII string directly) ; $bNoCRLF - [optional] True: no line breaks, False: add CRLF every 76 chars (default = True) ; Return values .: Success - Base64 encoded string ; Failure - "" and sets @error ; Remarks .......: For ASCII strings, you can use this function directly. For UTF-8 strings, use _Base64EncodeStr() instead ; Author ........: Dao Van Trong - TRONG.PRO ; =============================================================================================================================== Func _Base64Encode($bInput, $bNoCRLF = True) $bInput = Binary($bInput) Local $iFlags = 1 ; CRYPT_STRING_BASE64 If $bNoCRLF Then $iFlags = 0x40000001 ; CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF Local $tInput = DllStructCreate("byte[" & BinaryLen($bInput) & "]") DllStructSetData($tInput, 1, $bInput) ; Get required buffer size Local $aResult = DllCall("Crypt32.dll", "bool", "CryptBinaryToStringW", _ "struct*", $tInput, _ "dword", DllStructGetSize($tInput), _ "dword", $iFlags, _ "ptr", 0, _ "dword*", 0) If @error Or Not $aResult[0] Then Return SetError(1, 0, "") Local $iSize = $aResult[5] Local $tOutput = DllStructCreate("wchar[" & $iSize & "]") ; Perform encoding $aResult = DllCall("Crypt32.dll", "bool", "CryptBinaryToStringW", _ "struct*", $tInput, _ "dword", DllStructGetSize($tInput), _ "dword", $iFlags, _ "struct*", $tOutput, _ "dword*", $iSize) If @error Or Not $aResult[0] Then Return SetError(2, 0, "") Return DllStructGetData($tOutput, 1) EndFunc ;==>_Base64Encode ; #FUNCTION# ==================================================================================================================== ; Name ..........: _Base64Decode ; Description ...: Decode Base64 string to binary or string ; Syntax ........: _Base64Decode($sInput[, $bReturnBinary = False[, $iDecodeType = 1]]) ; Parameters ....: $sInput - Base64 string to decode ; $bReturnBinary - [optional] False: return string, True: return binary (default = False) ; $iDecodeType - [optional] 1: ASCII, 4: UTF-8 (default = 1, only used when $bReturnBinary = False) ; Return values .: Success - Binary data or string ; Failure - Binary("") and sets @error ; Remarks .......: For ASCII-only data, use default parameters. For UTF-8 data, use $iDecodeType = 4. For binary data, use $bReturnBinary = True ; Author ........: Dao Van Trong - TRONG.PRO ; =============================================================================================================================== Func _Base64Decode($sInput, $bReturnBinary = False, $iDecodeType = 1) If ($iDecodeType > 4) Or ($iDecodeType < 1) Then $iDecodeType = 4 ; Remove all whitespace and CRLF $sInput = StringRegExpReplace($sInput, "\s", "") If ($sInput = "") Then Return SetError(1, 0, ($bReturnBinary ? Binary("") : "")) Local $iFlags = 1 ; CRYPT_STRING_BASE64 ; Get required buffer size Local $aResult = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", _ "wstr", $sInput, _ "dword", StringLen($sInput), _ "dword", $iFlags, _ "ptr", 0, _ "dword*", 0, _ "ptr", 0, _ "ptr", 0) If @error Or Not $aResult[0] Then Return SetError(2, 0, ($bReturnBinary ? Binary("") : "")) Local $iSize = $aResult[5] Local $tOutput = DllStructCreate("byte[" & $iSize & "]") ; Perform decoding $aResult = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", _ "wstr", $sInput, _ "dword", StringLen($sInput), _ "dword", $iFlags, _ "struct*", $tOutput, _ "dword*", $iSize, _ "ptr", 0, _ "ptr", 0) If @error Or Not $aResult[0] Then Return SetError(3, 0, ($bReturnBinary ? Binary("") : "")) Local $bBinary = DllStructGetData($tOutput, 1) If $bReturnBinary Then Return $bBinary Else ; Convert binary to string with specified encoding Return BinaryToString($bBinary, $iDecodeType) EndIf EndFunc ;==>_Base64Decode ; #FUNCTION# ==================================================================================================================== ; Name ..........: _Base64EncodeStr ; Description ...: Encode string to Base64 ; Syntax ........: _Base64EncodeStr($sInput[, $iEncodeType = 4[, $bNoCRLF = True]]) ; Parameters ....: $sInput - String to encode ; $iEncodeType - [optional] 1: ASCII, 4: UTF-8 (default = 4) ; $bNoCRLF - [optional] True: no line breaks, False: add CRLF (default = True) ; Return values .: Success - Base64 encoded string ; Failure - "" and sets @error ; Author ........: Dao Van Trong - TRONG.PRO ; =============================================================================================================================== Func _Base64EncodeStr($sInput, $iEncodeType = 4, $bNoCRLF = True) If ($iEncodeType > 4) Or ($iEncodeType < 1) Then $iEncodeType = 4 Local $bBinary = StringToBinary($sInput, $iEncodeType) Return _Base64Encode($bBinary, $bNoCRLF) EndFunc ;==>_Base64EncodeStr ; #FUNCTION# ==================================================================================================================== ; Name ..........: _Base64DecodeStr ; Description ...: Decode Base64 string to text string ; Syntax ........: _Base64DecodeStr($sInput[, $iDecodeType = 4]) ; Parameters ....: $sInput - Base64 string to decode ; $iDecodeType - [optional] 1: ASCII, 4: UTF-8 (default = 4) ; Return values .: Success - Text string ; Failure - "" and sets @error ; Author ........: Dao Van Trong - TRONG.PRO ; =============================================================================================================================== Func _Base64DecodeStr($sInput, $iDecodeType = 4) Return _Base64Decode($sInput, False, $iDecodeType) EndFunc ;==>_Base64DecodeStr ; #FUNCTION# ==================================================================================================================== ; Name ..........: _PathWithSlash ; Description ...: Add single backslash to path if not present ; Syntax ........: _PathWithSlash($sPath) ; Parameters ....: $sPath - Path string ; Return values .: Path with trailing backslash ; Author ........: Dao Van Trong - TRONG.PRO ; =============================================================================================================================== Func _PathWithSlash($sPath) Return _PathRemoveTrail($sPath) & '\' EndFunc ;==>_PathWithSlash ; #FUNCTION# ==================================================================================================================== ; Name ..........: _PathRemoveTrail ; Description ...: Remove trailing backslashes from path ; Syntax ........: _PathRemoveTrail($sPath) ; Parameters ....: $sPath - Path string ; Return values .: Path without trailing backslashes ; Author ........: Dao Van Trong - TRONG.PRO ; =============================================================================================================================== Func _PathRemoveTrail($sPath) $sPath = StringStripWS($sPath, 3) While (StringRight($sPath, 1) == '\') $sPath = StringTrimRight($sPath, 1) WEnd Return $sPath EndFunc ;==>_PathRemoveTrail1 point
-
WinSockUDF - TCP/UDP Networking Library for AutoIt
WildByDesign reacted to argumentum for a topic
If this forum had better themes and more formatting options I would agree but unfortunately none of that is there and a user is somewhat limited. On the other hand this post was formatted by AI and he just pasted it. Maybe pasting without formatting would do what you ask but would loose much of it's nice looking presentation. P.S.: It suck to come from the future @WildByDesign and having to wait for the past to catch up1 point -
WinSockUDF - TCP/UDP Networking Library for AutoIt
WildByDesign reacted to argumentum for a topic
1 point -
WinSockUDF - TCP/UDP Networking Library for AutoIt
WildByDesign reacted to water for a topic
Workaround: Use Ctrl+a to select all text of the page and make it readable1 point -
WinSockUDF - TCP/UDP Networking Library for AutoIt
WildByDesign reacted to argumentum for a topic
Poor coding does Change what you need 🤯1 point -
WinSockUDF - TCP/UDP Networking Library for AutoIt
WildByDesign reacted to water for a topic
Do you run the "AutoIt (Dark)" theme? The dark mode caused the unreadable text.1 point -
ntfy (notify) yourself and/or everyone
ioa747 reacted to argumentum for a topic
How would you like to run: curl -d "Finished running my script. All good." ntfy.sh/Testing_AutoIt_script or ConsoleWrite(ntfy_send("**All good**, all the time 😃") & @TAB & @error & @TAB & @extended & @CRLF) Func ntfy_send($sMsg, $sTopicName = "Testing_AutoIt_script") Local Static $iErr = 0, $oErr If IsObj($sMsg) Then If $sMsg.retcode Then $iErr = "0x" & Hex($sMsg.retcode, 8) Return EndIf If ObjEvent("AutoIt.Error") = "" Then $oErr = ObjEvent("AutoIt.Error", "ntfy_send") Local $sUrl = "https://ntfy.sh/" & $sTopicName Local $oHTTP = ObjCreate("winhttp.winhttprequest.5.1") $oHTTP.Open("POST", $sUrl, False) ; Open the connection using POST method (synchronous = False) $oHTTP.SetRequestHeader("Markdown", "yes") ; Set Markdown ON $oHTTP.SetRequestHeader("Tags", "heavy_check_mark,PC:" & "@ComputerName") ; https://docs.ntfy.sh/publish/#tags-emojis $oHTTP.Send($sMsg) ; Send the request If ObjEvent("AutoIt.Error") = "ntfy_send" Then $oErr = ObjEvent("AutoIt.Error", "") If $iErr Then Return SetError(2, $iErr, "oHTTP.Send FAILED") Return SetError(Int($oHTTP.Status <> 200), $oHTTP.Status, ($oHTTP.Status = 200 ? StringReplace($oHTTP.ResponseText, @LF, "") : $oHTTP.StatusText)) EndFunc ;==>ntfy_send and be notified in your phone, browser or ...basically any possible way ?!, meet ntfy.sh 🤩 Ok. How would you like to have your own AutoIt receiver for these notifications 🤯 For that you'll need the curl DLL, the curl UDF and something like this: #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** Opt("TrayAutoPause", 0) ; Script pauses when click on tray icon = OFF/0 Opt("TrayOnEventMode", 0) ; Enable/disable OnEvent functions notifications for the tray = OFF/0 Opt("GUICloseOnESC", 0) ; When ESC is pressed on a GUI the $GUI_EVENT_CLOSE message is sent = ON/1 If Not FileGetSize(@ScriptDir & '\curl-ca-bundle.crt') Then MsgBox(262144 + 64, @ScriptName, "The curl stuff needs to be in the same folder for this example", 30) Exit EndIf If Not @AutoItX64 Then MsgBox(262144 + 64, @ScriptName, "It needs to run x64", 30) Exit EndIf #include "Curl.au3" ; https://www.autoitscript.com/forum/topic/207859-curl-udf-libcurl-with-x64-support #include <GuiEdit.au3> ;_GUICtrlEdit_AppendText() ; GUI stuff #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form= Global $Form1 = GUICreate("Form1", 565, 425) Global $Group1 = GUICtrlCreateGroup("MyTopic", 8, 8, 305, 49) Global $Input1 = GUICtrlCreateInput("Testing_AutoIt_script", 16, 24, 281, 21) GUICtrlCreateGroup("", -99, -99, 1, 1) Global $Button1 = GUICtrlCreateButton("Gather all in cache", 320, 16, 131, 25) Global $Button2 = GUICtrlCreateButton("Listen ( start )", 464, 16, 91, 25) Global $Group2 = GUICtrlCreateGroup("Dump", 8, 96, 545, 321) Global $Edit1 = GUICtrlCreateEdit("", 16, 120, 529, 289) GUICtrlCreateGroup("", -99, -99, 1, 1) Global $Label1 = GUICtrlCreateLabel("last ""keepalive""", 8, 64, 548, 33, $SS_CENTER) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### Global $g_nfty_CurlPeeked, $g_nfty_ListenStop = 1 Global $__g_nfty_RunningHandles, $__g_nfty_Curl = 0, $__g_nfty_Multi = 0 OnAutoItExitRegister(nfty_Listen_Cleanup) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE If $g_nfty_ListenStop = 1 Then GUIDelete() Exit EndIf GUICtrlSetState($Button2, $GUI_DISABLE) GUICtrlSetData($Button2, "Listen ( stoping )") $g_nfty_ListenStop = 2 Case $Button1 $g_nfty_ListenStop = 0 nfty_Listen_Start(GUICtrlRead($Input1), "?poll=1&since=all") nfty_Listen_Perform() Case $Button2 If $g_nfty_ListenStop Then GUICtrlSetState($Button1, $GUI_DISABLE) GUICtrlSetState($Button2, $GUI_DISABLE) $g_nfty_ListenStop = 0 GUICtrlSetData($Button2, "Listen ( starting )") nfty_Listen_Start(GUICtrlRead($Input1)) If @error Then $g_nfty_ListenStop = 1 GUICtrlSetData($Button2, "Listen ( start )") GUICtrlSetState($Button1, $GUI_ENABLE) GUICtrlSetState($Button2, $GUI_ENABLE) Else GUICtrlSetData($Button2, "Listen ( stop )") GUICtrlSetState($Button2, $GUI_ENABLE) EndIf Else GUICtrlSetState($Button2, $GUI_DISABLE) GUICtrlSetData($Button2, "Listen ( stoping )") $g_nfty_ListenStop = 2 EndIf EndSwitch Switch $g_nfty_ListenStop Case 1 ; was never running ContinueLoop Case 0 ; not stopped - is running nfty_Listen_Perform() Case 2 ; request to stop nfty_Listen_Cleanup() $g_nfty_ListenStop = 1 GUICtrlSetData($Button2, "Listen ( start )") GUICtrlSetState($Button1, $GUI_ENABLE) GUICtrlSetState($Button2, $GUI_ENABLE) EndSwitch WEnd Func nfty_Listen_Start($sTopic, $suffix = "") $__g_nfty_Curl = Curl_Easy_Init() If Not $__g_nfty_Curl Then $g_nfty_ListenStop = 0 Return SetError(1, 0, 1) EndIf Curl_Easy_Setopt($__g_nfty_Curl, $CURLOPT_URL, "https://ntfy.sh/" & $sTopic & "/json" & $suffix) ;~ Curl_Easy_Setopt($Curl, $CURLOPT_USERAGENT, "AutoIt/Curl") Curl_Easy_Setopt($__g_nfty_Curl, $CURLOPT_FOLLOWLOCATION, 1) Curl_Easy_Setopt($__g_nfty_Curl, $CURLOPT_ACCEPT_ENCODING, "") Curl_Easy_Setopt($__g_nfty_Curl, $CURLOPT_WRITEFUNCTION, Curl_DataWriteCallback_nfty()) Curl_Easy_Setopt($__g_nfty_Curl, $CURLOPT_WRITEDATA, $__g_nfty_Curl) Curl_Easy_Setopt($__g_nfty_Curl, $CURLOPT_TCP_KEEPALIVE, 1) If $suffix Then Curl_Easy_Setopt($__g_nfty_Curl, $CURLOPT_TIMEOUT, 10) ; 10 sec timeout ;peer verification curl_easy_setopt($__g_nfty_Curl, $CURLOPT_CAINFO, @ScriptDir & '\curl-ca-bundle.crt') ; ;~ Curl_Easy_Setopt($__g_nfty_Curl, $CURLOPT_SSL_VERIFYPEER, 0) $__g_nfty_Multi = Curl_Multi_Init() If Not $__g_nfty_Multi Then $g_nfty_ListenStop = 0 nfty_Listen_Cleanup() Return SetError(2, 0, 2) EndIf Curl_Multi_Add_Handle($__g_nfty_Multi, $__g_nfty_Curl) EndFunc ;==>nfty_Listen_Start Func nfty_Listen_Perform() Local Static $MsgsInQueue, $hTimer = 0 If TimerDiff($hTimer) < 100 Then Return ; no need to ask so often $hTimer = TimerInit() ; let's restart the timer Curl_Multi_Perform($__g_nfty_Multi, $__g_nfty_RunningHandles) Local $CURLMsg = Curl_Multi_Info_Read($__g_nfty_Multi, $MsgsInQueue) If DllStructGetData($CURLMsg, "msg") = $CURLMSG_DONE Then Local $__g_nfty_Curl = DllStructGetData($CURLMsg, "easy_handle") Local $Code = DllStructGetData($CURLMsg, "data") If $Code = $CURLE_OK Then ;~ ConsoleWrite('@@(' & @ScriptLineNumber & ') : ' & @MIN & ':' & @SEC & '.' & @MSEC & @TAB & "Content Type: " & Curl_Easy_GetInfo($__g_nfty_Curl, $CURLINFO_CONTENT_TYPE) & @LF) ;~ ConsoleWrite('@@(' & @ScriptLineNumber & ') : ' & @MIN & ':' & @SEC & '.' & @MSEC & @TAB & "Download Size: " & Curl_Easy_GetInfo($__g_nfty_Curl, $CURLINFO_SIZE_DOWNLOAD) & @LF) ;~ ConsoleWrite('@@(' & @ScriptLineNumber & ') : ' & @MIN & ':' & @SEC & '.' & @MSEC & @TAB & '- Header >' & BinaryToString(Curl_Data_Get($__g_nfty_Curl + 1)) & '<' & @CRLF) ;~ ConsoleWrite('@@(' & @ScriptLineNumber & ') : ' & @MIN & ':' & @SEC & '.' & @MSEC & @TAB & '- Html >' & BinaryToString(Curl_Data_Get($__g_nfty_Curl)) & '<' & @CRLF) Else ConsoleWrite('@@(' & @ScriptLineNumber & ') : ' & @MIN & ':' & @SEC & '.' & @MSEC & @TAB & Curl_Easy_StrError($Code) & @LF) EndIf nfty_Listen_Cleanup() $g_nfty_ListenStop = 1 EndIf EndFunc ;==>nfty_Listen_Perform Func nfty_Listen_Cleanup() If $__g_nfty_Multi Then Curl_Multi_Remove_Handle($__g_nfty_Multi, $__g_nfty_Curl) Curl_Multi_Cleanup($__g_nfty_Multi) $__g_nfty_Multi = 0 EndIf Curl_Easy_Cleanup($__g_nfty_Curl) Curl_Data_Cleanup($__g_nfty_Curl) Curl_Data_Cleanup($__g_nfty_Curl + 1) $__g_nfty_Curl = 0 EndFunc ;==>nfty_Listen_Cleanup Func Curl_DataWriteCallback_nfty() Static $Ptr = DllCallbackGetPtr(DllCallbackRegister(__Curl_DataWriteCallback_nfty, (@AutoItX64 ? "uint_ptr" : "uint_ptr:cdecl"), "ptr;uint_ptr;uint_ptr;ptr")) Return $Ptr EndFunc ;==>Curl_DataWriteCallback_nfty Func __Curl_DataWriteCallback_nfty($Ptr, $Size, $Nmemb, $Handle) Local $Length = $Size * $Nmemb, $Data = __Curl_Peek("byte[" & $Length & "]", $Ptr) $g_nfty_CurlPeeked = StringReplace(BinaryToString($Data), @LF, @CRLF) If StringInStr($g_nfty_CurlPeeked, ',"event":"open","topic":"') Or StringInStr($g_nfty_CurlPeeked, ',"event":"keepalive","topic":"') Then ; not important GUICtrlSetData($Label1, @MIN & ":" & @SEC & " >" & StringStripCR($g_nfty_CurlPeeked) & "<") Else _GUICtrlEdit_AppendText($Edit1, $g_nfty_CurlPeeked & @CRLF) EndIf Return $Length EndFunc ;==>__Curl_DataWriteCallback_nfty Do place your scripts in the bin folder where libcurl-x64.dll is at, or this example will not work as is. This is just an example. FAQ: Q: Why the curl UDF ?, why not ... A: Because "the page" never finishes the download ( and is not meant to finish ). Couldn't find a way to peek into the message other than this. Q: Can you ... A: Maybe. But am busy, and not all that good at all these. If you code that you wish it had, do share it in the forum. ( Think GPLv2 ) Q: I sent a message but my receiver script wasn't running at the time / Lost internet for X hours. A: Text messages are likely to be available for up to 12 hours ( for what I read ). Just click "Gather all in cache" in this example. Q: How can I ... A: ntfy has excellent documentation. Read it. Q: Can I make my messages private ? A: Yes you can. Read the offers they have available for the service.1 point -
1 point
-
A simple fast IPC based on Windows Messaging
WildByDesign reacted to Nine for a topic
After seeing a number of threads talking about how to exchange efficiently messages between processes (Inter Process Communication), I decided to create a framework using Windows Messages WM_COPYDATA. What is new with this UDF you ask ? Well it will depends how familiar you are with IPC. One thing is sure, the simplicity of use and the fabulous speed are amazing. This is based on a Clients-Server approach. You can have an unlimited number of clients talking with a single server. You will have to define the protocol of communication between them, but the code you have to create is incredibly low. The UDF proposes 2 simple message properties of communication. The first (called data) is based on a number. You can decide what value 1,2,3, etc. means between your client and server. Server will react upon the value of the data field. Second, there is a string field where you can inscribe additional information on request, and where the server will respond to client request (if necessary). Version 2025-11-17 * Added support to x64 server and/or x64 clients * Added support to AutoIt version 3.3.18.0 Version 2020-06-27 * Allows processes with different levels of privilege to communicate with each other Here are the functions that I have wrapped around this : Func _WCD_CreateServer Func _WCD_CreateClient Func _WCD_GetServerHandle Func _WCD_IsServerAvailable Func _WCD_Send Func _WCD_WM_COPYDATA_CLIENT_HANDLER Func _WCD_Client_GetResponse Func _WCD_WM_COPYDATA_SERVER_HANDLER Func _WCD_Server_PeekRequest Func _WCD_Server_GetRequest Func _WCD_Server_IsRequestAvail Here an example of the server : #include <Constants.au3> #include <GUIConstants.au3> #include "WCD_IPC.au3" Opt ("MustDeclareVars", 1) $_WCD_Verbose = False ; make it True if you want to follow the convos. False is by default. Local $hServer = _WCD_CreateServer () Local $aReq, $iData While True If _WCD_Server_IsRequestAvail () Then $aReq = _WCD_Server_GetRequest () $iData = @extended Switch $iData Case 1 ; who are you _WCD_Send($hServer, $aReq[0], $iData, @ComputerName) Case 2 Switch Number($aReq[1]) Case 1 _WCD_Send($hServer, $aReq[0], $iData, @IPAddress1) Case 2 _WCD_Send($hServer, $aReq[0], $iData, @IPAddress2) Case 3 _WCD_Send($hServer, $aReq[0], $iData, @IPAddress3) Case 4 _WCD_Send($hServer, $aReq[0], $iData, @IPAddress4) Case Else _WCD_Send($hServer, $aReq[0], $iData, "Invalid parameter") EndSwitch EndSwitch EndIf Sleep (100) WEnd And the client : #include <Constants.au3> #include <GUIConstants.au3> #include "WCD_IPC.au3" Opt ("MustDeclareVars", 1) $_WCD_Verbose = True ; as for the server, you can decide to make client verbose or not Global $hWnd = _WCD_CreateClient ("Test WCD Client") Global $hWndServer = _WCD_GetServerHandle () _WCD_Send($hWnd, $hWndServer, 1) ; simple request - who are you ? Local $sString = WaitForResponse () ConsoleWrite ($sString & @CRLF) _WCD_Send($hWnd, $hWndServer, 2, "5") ; adding text to a more complex request $sString = WaitForResponse () ConsoleWrite ($sString & @CRLF) Func WaitForResponse () Local $sResp While _WCD_IsServerAvailable () $sResp = _WCD_Client_GetResponse () If $sResp <> "" Then Return $sResp Sleep (100) WEnd EndFunc As always, let me know if you got issues, comments, suggestions. I will be glad to answer. WCD_IPC.zip1 point -
A simple fast IPC based on Windows Messaging
argumentum reacted to Nine for a topic
New version available.1 point -
As usually I love your answer my friend. As always, I really liked your answer, my friend. All is clear for me. Thanks. So. @Parsix In your opinion, does this example fully meet your needs for using Au3Stripper with the @trancexx script , I mean all the possibilities of the /SO /PE /RM parameters?1 point
-
I am just supporting the au3stripper questions in this thread. So without looking at the details it is pretty simple to me: Does the original script work?: if Yes: Does au3stripper run cleanly without any warnings? if Yes: The stripped script should work as the original if No: You are responsible and "don't come crying to me" when you override the default to continue with force! 😉1 point
-
A simple fast IPC based on Windows Messaging
WildByDesign reacted to Nine for a topic
Ahhh. Thank you very much. I was able to replicate your issue. The problem is the structure alignment in 64 bits. I'll do some tests and make an update in a few...1 point -
Guiscape -- A new GUI builder project!
jaberwacky reacted to MattyD for a topic
no worries at all! what I think is happening is: $NC_CLICKED is control Id of the dummy, which fires on WM_NCLBUTTONDOWN. The dummy's data is set to the hwnd param of the WM_ message. Fair enough... But then we handle events based on $event.Form - which is the dummy's parent. I guess Form1 is the last window built with GUICreate() before we setup the dummy, so that ends up owning the control. To find the hWnd of the captured WM_NCLBUTTONDOWN message, we need to: GuiCtrlRead($NC_CLICKED).1 point -
Something like this ? #include "Json.au3" ConsoleWrite("- Test8() : " & Test8() & @CRLF) Func Test8() ; Your three JSON strings Local $Json1 = '{"name":"John","age":30,"locations":[]}' Local $Json2 = '{"City":"Paris","Country":"France"}' Local $Json3 = '{"City":"London","Country":"England"}' ; Decode Local $obj1 = Json_Decode($Json1) Json_ObjPut($obj1,"locations", Json_Decode("[" & $Json2 & "," & $Json3 & "]")) Local $final = Json_Encode($obj1, $JSON_PRETTY_PRINT) ConsoleWrite($final & @CRLF) EndFunc ;==>Test81 point
-
1- you can put sleep anywhere / everywhere. It doesn't hurt except can slow down the script. You need to test and decide. 2- having a single delay ($iTimeOut) is a very bad idea. Sometimes, it requires more time, sometimes it requires less. You need to test and decide. 3- it is not because you paste something that it will be pasted instantly in the field. It may take some time. You need to test and decide.1 point
-
Guiscape -- A new GUI builder project!
WildByDesign reacted to jaberwacky for a topic
Thank you! Check out the latest update. I didn't do much with your code tonight, but I did use your code from today to fix the window closing issues. I also removed the garish colors from the tab items (I put it in there for debugging (took me about 16 hours to get that ironed out.)) I also came up with a hack for a weird issue. So, when a title bar is clicked a message is sent to a dummy control. Inside of the dummy control function (GUIObjectEvents) the $hwnd is correct for each form. Click form1 title bar and you get the form1 hwnd. Click on form2 title bar and you get form2 hwnd. However, inside of the GUIObjectsHandler only form1 hwnd is there regardless of which form I click. I dunno. I had a long day so I'm callling it for tonight. Thank you again MattyD ... Your code saved me from hours of banging my forehead on the desk. I could not have come up with the code that you did.1 point -
IPC - Medium Integrity to High Integrity Process
Nine reacted to WildByDesign for a topic
@Nine I was doing some testing with your WCD IPC UDF and I was very impressed with it. It really is quite simple yet such a genius idea and very efficient as well. Testing with your scripts worked perfectly. But it didn't work when I integrated it into my script. Is it possible that it didn't work with my script because my script is already a GUI script? I checked with System Informer and there wasn't a window titled "WCDServer". It would've shown there whether it was hidden or not. EDIT: I figured out the problem. I was using _WinAPI_SetWindowText to set the title for the AutoIt window specifically but it was changing the title from "WCDServer" to the other title that I was using previously. This is something that I can work around. Your UDF is the perfect solution to my problem. Thank you.1 point -
Guiscape -- A new GUI builder project!
jaberwacky reacted to MattyD for a topic
Actually, maybe this would be better... Case $WM_DESTROY _WinAPI_RemoveWindowSubclass($hwnd, $pWndProc, $iIdSubclass) $iRet = _WinAPI_DefSubclassProc($hwnd, $iMsg, $wParam, $lParam) And we must do this before exiting. GUIDelete($Guiscape.Canvas.Hwnd)1 point -
Guiscape -- A new GUI builder project!
jaberwacky reacted to MattyD for a topic
Perhaps add this to WndProc? - it should allow you exit cleanly Case $WM_DESTROY _WinAPI_RemoveWindowSubclass($hwnd, $pWndProc, $iIdSubclass) GUIDelete($hWnd)1 point -
Guiscape -- A new GUI builder project!
MattyD reacted to jaberwacky for a topic
Check it out! https://github.com/matthewrg/Guiscape1 point -
You're probably missing the proper vc_redist dll's since you're on such old OS. https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-1701 point
-
Bug in map ( and how to avoid it )
WildByDesign reacted to AspirinJunkie for a topic
First, I pared down the script to the essentials: For $i = 1 To 20 ; create new(!) map, add one element to the string index "c" (which calculated position in the internal list is index 8) Global $m1[] $m1["c"] = 1 ; check if there`s a value at the index 8 (shouldn`t) If $m1[8] Then ConsoleWrite($m1[8] & @CRLF) ; create another map and add value at the same integer index as the one $m1 checked Global $m2[] $m2[8] = 1 Next I made the following observations: 1. It does not occur with all string indexes, but only with some. It is noticeable that each string index has a fixed associated integer index. If you use a different integer index, the phenomenon does not occur. So far, I have found the following combinations in which the phenomenon occurs: | String-Index | Integer-Index | | ------------ | ------------- | | "[" | 0 | | "<" | 1 | | "" | 5 | | "c" | 8 | | "D" | 9 | | "%" | 10 | | "k" | 16 | | "L" | 17 | | "-" | 18 | | "s" | 24 | | "T" | 25 | | "{" | 32 | | "\" | 33 | | "=" | 34 | These relationships can be explained well using hash index collisions. AutoIt uses the DJB2 hash function in its maps. If you use this for the letters and then scale it to the table size using modulo, you get exactly the corresponding integer indices. Only the table size is obviously not fixed, as the index sometimes fits for 32 elements and sometimes for 64. For example: “c” has a DJB2 hash value of 177672. If we assume that the map in AutoIt has 32 elements at that point, the index for “c” is calculated as 177672 % 32 = 8. This also works for the other string indexes. E.g., “D” --> 177641 % 32 = 9 or “” --> 5381 % 32 = 5. Only the size of the hash table is obviously variable, as some fit for a size of 32 elements and some for 64. However, thanks to the bug, we can learn a lot about the internal structure of AutoIt maps. They are DJB2-based hash tables that start with 32 or 64 elements. 2. This behavior only occurs when the map $m2 is created and an element is created with the same integer index as in $m1. If only this index is set, a match is reported very often. If other indexes are also set, the match does not occur as frequently. One possible explanation for this behavior is as follows: A hash table is essentially an array with a specific size. This size is fundamentally independent of the number of elements it contains (resizing makes sense but is not mandatory). In this case, a map is obviously initially populated with either 32 or 64 elements. When a value is added to the hash table, the hash value of the key is calculated and this calculated value is mapped to the array size using modulo. If the key is “c”, for example, the DJB2 hash (the hash algorithm used in AutoIt) is 177672. To obtain an index for our array in the map, we have to reduce this hash value to the range 32 or 64. This is easy to do using the modulo operator. And with 177672 % 32, we get 8 as the result. The value for the key “c” is therefore stored in the internal array at index 8. However, since several keys could end up at index 8, we need to create a way to hold multiple elements there. For each index, a list is created (a “bucket”) that contains all elements whose key matches this index. The key and value of these elements are then simply stored one after the other in the bucket itself. When a value is queried, the index is first calculated and then this bucket is traversed linearly to see if the specific key is contained in it. In AutoIt, these buckets do not necessarily seem to be used only by one map instance. At some point, two maps share a bucket, resulting in a phenomenon like the one we see here. So you would have to take a closer look at the initialization of the map to see exactly where the problem lies.1 point -
IPC - Medium Integrity to High Integrity Process
WildByDesign reacted to Nine for a topic
Look at my Fast and simple WCD IPC. It is working well between processes with different levels of privilege.1 point -
Guiscape -- A new GUI builder project!
MattyD reacted to jaberwacky for a topic
I'm taking the hi word, that's not the same as $hwnd? Let me test it ... :forehead smack: Durrrrr .... thank you!1 point -
Guiscape -- A new GUI builder project!
jaberwacky reacted to MattyD for a topic
looks like a malformed window handle to me... around about line 70: GUICtrlSendToDummy($dummy, _WinAPI_MakeLong($NC_CLICKED, $hwnd)) so you're sending part of a window handle (the hi word part), and a in the lo work you have $NC_CLICKED.1 point -
Sudden Spike in zPlayer Downloads — Any Idea Why?
CYCho reacted to argumentum for a topic
...If, there are very many distributed workloads and the "master" overwhelmed itself, then you see what you just witnessed. All this is painfully stupid. More bandwidth than brains. Idea: we should offer torrents ( in a throttle ). With a bit of luck they can feed each other the files 🤪1 point -
StringReplace it replaces the same string in all the strings founded
Musashi reacted to pixelsearch for a topic
@Musashi hello I think OP wants to replace each "%" (preceded with digits & eventual dot) with "\%" while keeping a log of each replacement using _FileWriteToLine . But maybe not all "%" must be processed, as we'll see in the script below. @Delai I tried another approach, because the way you scripted it (by splitting the sentence) makes it hard to find the position you need in the original sentence, when comes the replacement part. Local $sLineIn, $sLineOut, $sPattern, $nMode, $iOffset, $aArray $sLineIn = "This % sign for test (not preceded with digits) . " & _ "En un estudio sobre la presencia de mujeres en las empresas tecnológicas se observa que el 20 % de los operarios, " & _ "el 40 % de los ingenieros y el 30 % de los directivos son mujeres. Se sabe que en estas empresas el 20 % de las plantillas " & _ "son directivos, el 35 % son ingenieros y el resto son operarios. Se elige un trabajador al azar de una de estas empresas." $sPattern = '(?U).*\d*\.?\d+ *(%).*' $nMode = 2 ; $STR_REGEXPARRAYFULLMATCH $iOffset = 1 While 1 $aArray = StringRegExp($sLineIn, $sPattern, $nMode, $iOffset) If @error Then $sLineOut &= StringMid($sLineIn, $iOffset) ExitLoop EndIf $iOffset = @extended $sLineOut &= StringTrimRight($aArray[0], 1) & "\%" ; your _FileWriteToLine here WEnd MsgBox(0, "$sLineOut", $sLineOut) Hope it helps1 point -
Avoid "AutoIt Error" message box in unknown errors
WildByDesign reacted to argumentum for a topic
The wrapper I put together ( @trancexx's code ) works just fine in 32 and 64 bit. I have not seen it fail.1 point -
If you're running this script in a loop, then you are not leaving enough time to the last click to complete.1 point
-
No, but... Your last MouseClick is not followed by a Sleep. Probably the reason.1 point
-
SciTE on Windows 11 Doesn't have Alt-Space Menu
RichardL reacted to argumentum for a topic
You ought to see me pressing Alt + space then C. People see me doing that, and is like am a god or something Maybe Co-Pilot took it ? 🤔1 point -
WinRT Object Libraries
WildByDesign reacted to MattyD for a topic
Ok, so it's far from perfect - but I've finally thrown everything together for a v1.5 release. It's just as "point in time" upload I guess, because there has been a ton of dev since v1.4. For those following along there shouldn't be too many surprises, we now have: - Added a bunch of libraries that were missing in 1.4. I believe there we a ton of statics interfaces that were missed. - Added _WinRT_SwitchInterface($pObj, $sIID), which is a QueryInterface, and Release call in one. (tidies code quite a lot!) - Added Windows.UI libraries (native XAML libs) - Added WindowsAppSDK v1.8 libraries (WinUI3 libs) - Removed _WinRT_Col* funcs. That was a glorified VectorView wrapper - so just use the IVectorView lib! - Added support for paramatised interfaces. You can also determine PIIDs yourselves if need be. Local $sIID_IVector_1_IAudioEffectDefinition_ = _WinRT_GetParameterizedTypeInstanceIID("Windows.Foundation.Collections.IVector`1<Windows.Media.Effects.IAudioEffectDefinition>") _WinRT_SwitchInterface($pInNode_EffectDefs, $sIID_IVector_1_IAudioEffectDefinition_) -Added support for creating delegates (the "type" param is optional - but some objects won't let you register the delegate without specifying this) Local $pFileCompletedDgt = _WinRT_CreateDelegate("_FileCompleted", "Windows.Foundation.TypedEventHandler`2<Windows.Media.Audio.AudioFileInputNode, Object>") Local $iFileCompletedTkn = IAudioFileInputNode_AddHdlrFileCompleted($pAG_InNode, $pFileCompletedDgt) ;.... IAudioFileInputNode_RemoveHdlrFileCompleted($pAG_InNode, $iFileCompletedTkn) _WinRT_DestroyDelegate($pFileCompletedDgt) ;.... Func _FileCompleted($pThis, $pObj, $pArgs) ConsoleWrite("File Completed" & @CRLF) EndFunc - Updated class explorer And probably a bunch of other things that I've forgotten about over the last year!1 point -
AutoIt Snippets
ioa747 reacted to WildByDesign for a topic
System Tray Menu Auto-Light/Dark Mode: If your system theme is a light mode theme, it will make the system tray menu light. Dark theme will show dark tray menu. I used to apply dark mode to the system tray menu before by creating a GUI that was never shown. But now I realized that I don't have to create that GUI and simply get the handle for the hidden AutoIt window and apply to that handle. #NoTrayIcon #include <MsgBoxConstants.au3> #include <StringConstants.au3> #include <TrayConstants.au3> #include <SendMessage.au3> #include <WindowsNotifsConstants.au3> Global $hTray = _GetHwndFromPID(@AutoItPID) Global $bIsDarkMode = _WinAPI_ShouldAppsUseDarkMode() ; DPI Awareness DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext" , "HWND", "DPI_AWARENESS_CONTEXT" -2) Opt("TrayMenuMode", 3) Example() Func Example() ; Create a tray item with the radio item parameter selected. TrayCreateItem("Radio 1", -1, -1, $TRAY_ITEM_RADIO) TrayItemSetState(-1, $TRAY_CHECKED) TrayCreateItem("Radio 2", -1, -1, $TRAY_ITEM_RADIO) TrayCreateItem("Radio 3", -1, -1, $TRAY_ITEM_RADIO) TrayCreateItem("") ; Create a separator line. Local $idExit = TrayCreateItem("Exit") TraySetState($TRAY_ICONSTATE_SHOW) ; Show the tray menu. If $bIsDarkMode Then DarkMode($hTray, True) While 1 Switch TrayGetMsg() Case $idExit ; Exit the loop. ExitLoop EndSwitch WEnd EndFunc ;==>Example ;-------------------------------------------------------------------------------------------------------------------------------- ; https://www.autoitscript.com/forum/topic/211475-darkmode-udf-for-autoits-win32guis/#comment-1530103 ;-------------------------------------------------------------------------------------------------------------------------------- Func DarkMode($hWnd, $bDarkMode = True) ; DarkMode Local Enum $DWMWA_USE_IMMERSIVE_DARK_MODE = (@OSBuild <= 18985) ? 19 : 20 Local $iRet = _WinAPI_DwmSetWindowAttribute_unr($hWnd, $DWMWA_USE_IMMERSIVE_DARK_MODE, $bDarkMode) If Not $iRet Then Return SetError(1, 0, -1) _SetCtrlColorMode($hWnd, $bDarkMode) EndFunc ;==>DarkMode ;-------------------------------------------------------------------------------------------------------------------------------- Func _SetCtrlColorMode($hWnd, $bDarkMode = True, $sName = Default) ; 'Explorer', 'CFD', 'DarkMode_ItemsView', etc. If $sName = Default Then $sName = $bDarkMode ? 'DarkMode_Explorer' : 'Explorer' $bDarkMode = Not Not $bDarkMode ; https://www.vbforums.com/showthread.php?900444-Windows-10-Dark-Mode-amp-VB6-apps If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) Local Enum $eDefault, $eAllowDark, $eForceDark, $eForceLight, $eMax ; enum PreferredAppMode DllCall('uxtheme.dll', 'bool', 133, 'hwnd', $hWnd, 'bool', $bDarkMode) ; fnAllowDarkModeForWindow = 133 DllCall('uxtheme.dll', 'int', 135, 'int', ($bDarkMode ? $eForceDark : $eForceLight)) ; fnAllowDarkModeForApp = 135 _WinAPI_SetWindowTheme_unr($hWnd, $sName) ; https://www.autoitscript.com/forum/index.php?showtopic=211475&view=findpost&p=1530103 DllCall('uxtheme.dll', 'none', 104) ; fnRefreshImmersiveColorPolicyState = 104 ; not needed ? _SendMessage($hWnd, $WM_THEMECHANGED, 0, 0) ; not needed ? EndFunc ;==>_SetCtrlColorMode ;-------------------------------------------------------------------------------------------------------------------------------- Func _WinAPI_SetWindowTheme_unr($hWnd, $sName = Null, $sList = Null) ; #include <WinAPITheme.au3> ; unthoughtful unrestricting mod. ;Causes a window to use a different set of visual style information than its class normally uses Local $sResult = DllCall('UxTheme.dll', 'long', 'SetWindowTheme', 'hwnd', $hWnd, 'wstr', $sName, 'wstr', $sList) If @error Then Return SetError(@error, @extended, 0) If $sResult[0] Then Return SetError(10, $sResult[0], 0) Return 1 EndFunc ;==>_WinAPI_SetWindowTheme_unr ;-------------------------------------------------------------------------------------------------------------------------------- Func _WinAPI_DwmSetWindowAttribute_unr($hWnd, $iAttribute, $iData) ; #include <WinAPIGdi.au3> ; unthoughtful unrestricting mod. ;Sets the value of the specified attributes for non-client rendering to apply to the window Local $aCall = DllCall('dwmapi.dll', 'long', 'DwmSetWindowAttribute', 'hwnd', $hWnd, 'dword', $iAttribute, _ 'dword*', $iData, 'dword', 4) If @error Then Return SetError(@error, @extended, 0) If $aCall[0] Then Return SetError(10, $aCall[0], 0) Return 1 EndFunc ;==>_WinAPI_DwmSetWindowAttribute_unr ;-------------------------------------------------------------------------------------------------------------------------------- Func _WinAPI_ShouldAppsUseDarkMode() Local $fnShouldAppsUseDarkMode = 132 Local $aResult = DllCall('UxTheme.dll', 'bool', $fnShouldAppsUseDarkMode) If @error Then Return SetError(@error, @extended, False) Return $aResult[0] EndFunc ;==>_WinAPI_ShouldAppsUseDarkMode ;-------------------------------------------------------------------------------------------------------------------------------- ; Function for getting HWND from PID Func _GetHwndFromPID($PID) $hWnd = 0 $winlist = WinList() For $i = 1 To $winlist[0][0] If $winlist[$i][0] <> "" Then $iPID2 = WinGetProcess($winlist[$i][1]) If $iPID2 = $PID Then $hWnd = $winlist[$i][1] ExitLoop EndIf EndIf Next Return $hWnd EndFunc ;==>_GetHwndFromPID1 point -
my question is why don't you do it like that? (Unless you want it to wait for you to press enter manually) ; ----------------------------------------------- #include <AutoItConstants.au3> ; ----------------------------------------------- Global $iTimeOut = 100 Global $iX = 711, $iY = 80 ; For F12 ; ----------------------------------------------- UpdateScenesF12($iX, $iY) ; ----------------------------------------------- Func UpdateScenesF12($iX, $iY) ConsoleWrite("UpdateScenes(" & $iX & ", " & $iY & ")" & @CRLF) Local $hSAC_MAIN = "[CLASS:SAC_MAIN]" Local $hSAC_SCENES = "[CLASS:SAC_SCENES]" Local $hSAC_SCENEPROPERTIES = "[CLASS:SAC_SCENEPROPERTIES]" ; ----------------------------------------------- WinActivate($hSAC_MAIN) WinActivate($hSAC_SCENES) ; ----------------------------------------------- ; <<<<==== Script Intervention ====>>>> Send("{End}") ; Select [End Of List] ; ----------------------------------------------- Sleep($iTimeOut) MouseClick($MOUSE_CLICK_LEFT, 188, 118, 1, 0) ; Select [New], the [Enter Scene Name] dialog is displayed. ; ----------------------------------------------- Send("{CTRLDOWN}") Send("v") ; Enter Scene Name Send("{CTRLUP}") ; ---------------------- ;~ Send("{ENTER}") ; Select [Ok], the [Enter Scene Name] dialog is exited...and the [Scene Properties] dialog is displayed Sleep($iTimeOut) MouseClick($MOUSE_CLICK_LEFT, 134, 163, 2, 0) ; Perform mouse click ⚠️ ; ----------------------------------------------- Sleep($iTimeOut) WinMove($hSAC_SCENEPROPERTIES, "", $iX, $iY) ; The [Scene Properties] dialog is repositioned ; ----------------------------------------------- Sleep($iTimeOut) MouseMove(1000, 550, 0) ; The mouse is positioned within the [Scene Properties] dialog EndFunc ;==>UpdateScenesF12 ; ----------------------------------------------- Edit: ; ----------------------------------------------- #include <AutoItConstants.au3> ; ----------------------------------------------- Global $iTimeOut = 100 Global $iX = 711, $iY = 80 ; For F12 ; Set the hotkey for [Enter] to trigger MouseClickAction HotKeySet("{ENTER}", "MouseClickAction") ; ----------------------------------------------- UpdateScenesF12($iX, $iY) ; ----------------------------------------------- Func UpdateScenesF12($iX, $iY) ; Various script stuff ; ----------------------------------------------- ; When [ENTER] is selected [for the [OK] button] then ; Wait for [Enter] to be pressed and handled by MouseClickAction While $bActive Sleep(100) ; Keeps the loop alive, waiting for the [Enter] hotkey action WEnd MouseClick($MOUSE_CLICK_LEFT, 134, 163, 2, 0) Exit script EndFunc ;==>UpdateScenesF12 ; ----------------------------------------------- Func MouseClickAction() HotKeySet("{ENTER}") ; Disable hotkey to prevent repeated clicks ;~ Send("{ENTER}") ; if you want to deliver the Enter key too MouseClick($MOUSE_CLICK_LEFT, 134, 163, 2, 0) ; Perform mouse click $bActive = False ; Exit loop in UpdateScenesF12 EndFunc Or alternately ; ----------------------------------------------- #include <AutoItConstants.au3> ; ----------------------------------------------- Global $iTimeOut = 100 Global $iX = 711, $iY = 80 ; For F12 ; ----------------------------------------------- UpdateScenesF12($iX, $iY) ; ----------------------------------------------- Func UpdateScenesF12($iX, $iY) ; Various script stuff ; ----------------------------------------------- ; When [ENTER] is selected [for the [OK] button] then WinWaitClose("the window that closes the ok") MouseClick($MOUSE_CLICK_LEFT, 134, 163, 2, 0) Exit script EndFunc ;==>UpdateScenesF12 ; -----------------------------------------------1 point
-
GetKeyPress
mr-es335 reacted to argumentum for a topic
#include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> Example() Func Example() GUICreate("Custom MsgBox", 225, 80) GUICtrlCreateLabel("Please select a button.", 10, 10) Local $idButton_Yes = GUICtrlCreateButton("Yes", 10, 50, 65, 25) Local $idButton_No = GUICtrlCreateButton("No", 80, 50, 65, 25) Local $idButton_Exit = GUICtrlCreateButton("Exit", 150, 50, 65, 25) ; Set GUIAccelerators for the button controlIDs, these being Ctrl + y and Ctrl + n Local $aAccelKeys[2][2] = [["^y", $idButton_Yes], ["^n", $idButton_No]] GUISetAccelerators($aAccelKeys) GUISetState(@SW_SHOW) ; Display the GUI. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE MsgBox($MB_SYSTEMMODAL, "You selected", "Close") ExitLoop Case $idButton_Yes MsgBox($MB_SYSTEMMODAL, "You selected", "Yes") ; Displays if the button was selected or the hotkey combination Ctrl + y was pressed. Case $idButton_No MsgBox($MB_SYSTEMMODAL, "You selected", "No") ; Displays if the button was selected or the hotkey combination Ctrl + n was pressed. Case $idButton_Exit MsgBox($MB_SYSTEMMODAL, "You selected", "Exit") ExitLoop EndSwitch WEnd GUIDelete() ; Delete the GUI. EndFunc ;==>Example ..is in the help file.1 point -
@Parsix Here is my entire modified code: ;~ https://www.autoitscript.com/forum/topic/154081-avoid-autoit-error-message-box-in-unknown-errors/page/4/#findComment-1547350 #Region - AutoIt3Wrapper directives section ; General section #AutoIt3Wrapper_UseX64=n #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Compression=4 ; Au3Check section #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 6 -w 7 ; Au3Stripper section #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/so /pe #AutoIt3Wrapper_Au3Stripper_OnError=C #EndRegion - AutoIt3Wrapper directives section #include <WinApi.au3> #Region - exmaple AddHookApi("user32.dll", "MessageBoxW", "Intercept_MessageBoxW", "int", "hwnd;wstr;wstr;uint") MsgBox(0, 'Test', 'Some normal MsgBox text') DllStructCreate("byte[123456789097]") ; This is a deliberate action intended to display an error, as this script demonstrates how to change error handling - interact with MsgBox's title and text. #EndRegion - exmaple #Region @trancexx - https://www.autoitscript.com/forum/topic/154081-avoid-autoit-error-message-box-in-unknown-errors/#findComment-1111917 Func Intercept_MessageBoxW($hWnd, $sText, $sTitle, $iType) If $sTitle = 'AutoIt' Then $sTitle = 'TESTING: ' & StringReplace($sTitle, "AutoIt", @ScriptName) Local $aCall = DllCall("user32.dll", "int", "MessageBoxW", _ "hwnd", $hWnd, _ "wstr", $sText, _ "wstr", $sTitle, _ "uint", $iType) If @error Or Not $aCall[0] Then Return 0 Return $aCall[0] EndFunc ;==>Intercept_MessageBoxW ; The magic is down below Func AddHookApi($sModuleName, $vFunctionName, $vNewFunction, $sRet = "", $sParams = "") Local Static $pImportDirectory, $hInstance Local Const $IMAGE_DIRECTORY_ENTRY_IMPORT = 1 If Not $pImportDirectory Then $hInstance = _WinAPI_GetModuleHandle(0) $pImportDirectory = ImageDirectoryEntryToData($hInstance, $IMAGE_DIRECTORY_ENTRY_IMPORT) If @error Then Return SetError(1, 0, 0) EndIf Local $iIsInt = IsInt($vFunctionName) Local $iRestore = Not IsString($vNewFunction) Local $tIMAGE_IMPORT_MODULE_DIRECTORY Local $pDirectoryOffset = $pImportDirectory Local $tModuleName Local $iInitialOffset, $iInitialOffset2 Local $iOffset2 Local $tBufferOffset2, $iBufferOffset2 Local $tBuffer, $tFunctionOffset, $pOld, $fMatch, $pModuleName, $pFuncName Local Const $PAGE_READWRITE = 0x04 While 1 $tIMAGE_IMPORT_MODULE_DIRECTORY = DllStructCreate("dword RVAOriginalFirstThunk;" & _ "dword TimeDateStamp;" & _ "dword ForwarderChain;" & _ "dword RVAModuleName;" & _ "dword RVAFirstThunk", _ $pDirectoryOffset) If Not DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") Then ExitLoop $pModuleName = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAModuleName") $tModuleName = DllStructCreate("char Name[" & _WinAPI_StringLenA($pModuleName) & "]", $pModuleName) If DllStructGetData($tModuleName, "Name") = $sModuleName Then ; function from this module $iInitialOffset = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") $iInitialOffset2 = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAOriginalFirstThunk") If $iInitialOffset2 = $hInstance Then $iInitialOffset2 = $iInitialOffset $iOffset2 = 0 While 1 $tBufferOffset2 = DllStructCreate("dword_ptr", $iInitialOffset2 + $iOffset2) $iBufferOffset2 = DllStructGetData($tBufferOffset2, 1) If Not $iBufferOffset2 Then ExitLoop If $iIsInt Then If BitAND($iBufferOffset2, 0xFFFFFF) = $vFunctionName Then $fMatch = True ; wanted function Else $pFuncName = $hInstance + $iBufferOffset2 + 2 ; 2 is size od "word", see line below... $tBuffer = DllStructCreate("word Ordinal; char Name[" & _WinAPI_StringLenA($pFuncName) & "]", $hInstance + $iBufferOffset2) If DllStructGetData($tBuffer, "Name") == $vFunctionName Then $fMatch = True ; wanted function EndIf If $fMatch Then $tFunctionOffset = DllStructCreate("ptr", $iInitialOffset + $iOffset2) VirtualProtect(DllStructGetPtr($tFunctionOffset), DllStructGetSize($tFunctionOffset), $PAGE_READWRITE) If @error Then Return SetError(3, 0, 0) $pOld = DllStructGetData($tFunctionOffset, 1) If $iRestore Then DllStructSetData($tFunctionOffset, 1, $vNewFunction) Else DllStructSetData($tFunctionOffset, 1, DllCallbackGetPtr(DllCallbackRegister($vNewFunction, $sRet, $sParams))) EndIf Return $pOld EndIf $iOffset2 += DllStructGetSize($tBufferOffset2) WEnd ExitLoop EndIf $pDirectoryOffset += 20 ; size of $tIMAGE_IMPORT_MODULE_DIRECTORY WEnd Return SetError(4, 0, 0) EndFunc ;==>AddHookApi Func VirtualProtect($pAddress, $iSize, $iProtection) Local $aCall = DllCall("kernel32.dll", "bool", "VirtualProtect", "ptr", $pAddress, "dword_ptr", $iSize, "dword", $iProtection, "dword*", 0) If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>VirtualProtect Func ImageDirectoryEntryToData($hInstance, $iDirectoryEntry) ; Get pointer to data Local $pPointer = $hInstance ; Start processing passed binary data. 'Reading' PE format follows. Local $tIMAGE_DOS_HEADER = DllStructCreate("char Magic[2];" & _ "word BytesOnLastPage;" & _ "word Pages;" & _ "word Relocations;" & _ "word SizeofHeader;" & _ "word MinimumExtra;" & _ "word MaximumExtra;" & _ "word SS;" & _ "word SP;" & _ "word Checksum;" & _ "word IP;" & _ "word CS;" & _ "word Relocation;" & _ "word Overlay;" & _ "char Reserved[8];" & _ "word OEMIdentifier;" & _ "word OEMInformation;" & _ "char Reserved2[20];" & _ "dword AddressOfNewExeHeader", _ $pPointer) Local $sMagic = DllStructGetData($tIMAGE_DOS_HEADER, "Magic") ; Check if it's valid format If Not ($sMagic == "MZ") Then Return SetError(1, 0, 0) ; MS-DOS header missing. Btw 'MZ' are the initials of Mark Zbikowski in case you didn't know. ; Move pointer $pPointer += DllStructGetData($tIMAGE_DOS_HEADER, "AddressOfNewExeHeader") ; move to PE file header ; In place of IMAGE_NT_SIGNATURE structure Local $tIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $pPointer) ; Check signature If DllStructGetData($tIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then ; IMAGE_NT_SIGNATURE Return SetError(2, 0, 0) ; wrong signature. For PE image should be "PE\0\0" or 17744 dword. EndIf ; Move pointer $pPointer += 4 ; size of $tIMAGE_NT_SIGNATURE structure ; In place of IMAGE_FILE_HEADER structure ; Move pointer $pPointer += 20 ; size of $tIMAGE_FILE_HEADER structure ; Determine the type Local $tMagic = DllStructCreate("word Magic;", $pPointer) Local $iMagic = DllStructGetData($tMagic, 1) Local $tIMAGE_OPTIONAL_HEADER If $iMagic = 267 Then ; x86 version ; Move pointer $pPointer += 96 ; size of $tIMAGE_OPTIONAL_HEADER ElseIf $iMagic = 523 Then ; x64 version ; Move pointer $pPointer += 112 ; size of $tIMAGE_OPTIONAL_HEADER Else Return SetError(3, 0, 0) ; unsupported module type EndIf ; Validate input by checking available number of structures that are in the module Local Const $IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16 ; predefined value that PE modules always use (AutoIt certainly) If $iDirectoryEntry > $IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1 Then Return SetError(4, 0, 0) ; invalid input ; Calculate the offset to wanted entry (every entry is 8 bytes) $pPointer += 8 * $iDirectoryEntry ; At place of correst directory entry Local $tIMAGE_DIRECTORY_ENTRY = DllStructCreate("dword VirtualAddress; dword Size", $pPointer) ; Collect data Local $pAddress = DllStructGetData($tIMAGE_DIRECTORY_ENTRY, "VirtualAddress") If $pAddress = 0 Then Return SetError(5, 0, 0) ; invalid input ; $pAddress is RVA, add it to base address Return $hInstance + $pAddress EndFunc ;==>ImageDirectoryEntryToData #EndRegion @trancexx - https://www.autoitscript.com/forum/topic/154081-avoid-autoit-error-message-box-in-unknown-errors/#findComment-1111917 Please note that I also modified this line: Func Intercept_MessageBoxW($hWnd, $sText, $sTitle, $iType) If $sTitle = 'AutoIt' Then $sTitle = 'TESTING: ' & StringReplace($sTitle, "AutoIt", @ScriptName) ... ... "wstr", $sTitle, _ ... ... EndIf1 point
-
This is a deliberate action intended to display an error, as this script demonstrates how to change error handling - interact with MsgBox's title and text.1 point
-
WinRT - WinUI3
WildByDesign reacted to MattyD for a topic
sure thing. - yeah, there are no window handles per se - apart from the WinID of the main window. Everything is done on objects. so that colour change would be something like: $pBrush = CreateSolidBrush("Red") IBorder_SetBackground($apBorders[0], $pBrush) IUnknown_Release($pBrush) In the Sept 3rd. example, to keep things tidy I release the border objects once they're created. So you'd need either need to change the background before releasing, or get the border object back by some other means. Via its parent for example - in this case the grid object (before it too is released!). As for triggering the color change - In this example, once we get into the main loop everything is event based. When we hit the following line the script won't continue until the dispatch loop is broken with _WinUI3_PostQuitMessage. IDispatcherQueue3_RunEventLoop($pDispatchQ) The general idea is to create a bunch of handlers with _WinRT_CreateDelegate(). But if you'd rather work within a while loop, it is possible to create your own dispatcher with _WinUI3_GetMsg / _WinUI3_DispatchMessage. I think there are probably examples of this early in the thread!1 point -
Yep, that could work well. Only drawback is the true use of the dead key misconverted into an accented characters. But it is less an issue when you know what you are doing...1 point
-
I have already posted the script in the German forum, but I would like to make it available here as well. Highlighting the active tab item in SciTE Individual: Frame color Text color Background color Text color if not saved Marker "Inactive item unsaved" Marker position "Inactive item unsaved" optionally 'top' / 'bottom' / 'none' Active item marking can be deactivated (if only unsaved marking is desired). The active item then receives the same marking as the inactive item when "unsaved". Colors can be loaded as a scheme via INI The compiled script can be ended with CMDLine parameter "/Exit". Since Windows 10, the windows have a very "flat" look. One of the consequences of this is that it is not immediately apparent which item is active in a Tab-Ctrl. When programming in SciTE, I usually have many tabs open at the same time. To make the active tab more visible, I draw it with a colored frame. In addition, unsaved tabs are marked separately with coloring of the top or bottom edge. The colors used for this can be stored individually as a scheme in an INI file. Some schemes are predefined at the beginning of the script. Just try out what you like best. I start the script via the autostart folder when Windows starts. Here are a few pictures: Active Tab Active Tab, unsaved Active Tab, BG: blue / Text: white ... BG: green / Text: white Active Tab, left & right idle unsaved Tabs Active Tab unsaved too ;-- TIME_STAMP 2023-03-23 10:16:34 v 0.5 #cs v 0.5 [fixed] Flickering, a variable assignment was incorrect [fixed] Marking has failed by using keys ("F6", "Shift+F6") to change the buffer selection v 0.4 [added] Exit via CMDLine with parameter "/Exit" [added] Optionally adjustable via INI [appearance]: - Mark active item: rect_highlight=true/false - Position of the marker for "Inactive item unsaved": idlepos=top/bottom/none v 0.3 [added] Separate marker (colored line top) for "Inactive item unsaved". v 0.2 [added] Separate marking (text color) for unsaved files. [added] Loading of colors from an INI (color schemes) possible #ce #include <FontConstants.au3> #include <GuiTab.au3> #include <Misc.au3> #include <WinAPIGdi.au3> #include <WinAPISys.au3> #include <WinAPIMisc.au3> #include <WindowsConstants.au3> Opt('TrayIconHide', 1) If $CMDLINE[0] And $CMDLINE[1] = '/Exit' Then ; CMD-Line: "@ScriptName.exe /Exit" Local $aProcessList = ProcessList(@ScriptName) For $i = 1 To $aProcessList[0][0] Step 1 If $aProcessList[$i][1] <> @AutoItPID Then ProcessClose($aProcessList[$i][1]) Next EndIf _Singleton(@ScriptName) ;~ HotKeySet("!{F8}", _End) ; <Alt><F8> Beenden OnAutoItExitRegister(_End) Global $sINI = StringFormat("%s\%s.ini", @ScriptDir, StringTrimRight(@ScriptName, 4)) Global $gm_SciTE[] $gm_SciTE.ExistsLast = 0 $gm_SciTE.ExistsCurr = 0 #cs The colors can be defined in an INI file in the script folder. If INI is not available, default colors are loaded. INI-Name = Name_of_the_Exe.ini [appearance] ; rect_highlight=true/false "false" does NOT highlight the active item, default: "true". rect_highlight=true ; idlepos=top/bottom/none "none" does NOT mark unsaved inactive files, default: "top". idlepos=top [scheme] ; Specify which of the defined schemes should be active. current=default ; One section for each scheme. [default] rect=0xCC483F text=0x800020 bg=0xFFFFFF unsaved=0x3030FF idle=0x3030FF [blue_invers] rect=0xCC483F text=0xFFF0F0 bg=0x800020 unsaved=0xA9A5F7 idle=0xA9A5F7 [green_invers] rect=0x005F00 text=0xEDFFED bg=0x409340 unsaved=0x1DE6B5 idle=0x1DE6B5 #ce ; appearance $gm_SciTE.bHighlight = (_IniOrDefault($sINI, 'rect_highlight', 'true', 'appearance') = 'true') $gm_SciTE.IdlePos = _IniOrDefault($sINI, 'idlepos', 'top', 'appearance') ; scheme: default (blue): $gm_SciTE.RectColor = _IniOrDefault($sINI, 'rect' , 0xCC483F) ; BGR $gm_SciTE.TextColor = _IniOrDefault($sINI, 'text' , 0x800020) ; BGR $gm_SciTE.BGColor = _IniOrDefault($sINI, 'bg' , 0xFFFFFF) ; BGR $gm_SciTE.TextColorUnsaved = _IniOrDefault($sINI, 'unsaved', 0x3030FF) ; BGR $gm_SciTE.IdleUnsaved = _IniOrDefault($sINI, 'idle' , 0x3030FF) ; BGR _CheckSciTE() ; the effect takes place immediately AdlibRegister(_CheckSciTE, 750) While True Sleep(5000) WEnd Func _End() AdlibUnRegister(_CheckSciTE) ;~ MsgBox(0, 'SciTE TabItem', 'Beendet!') Exit EndFunc Func _CheckSciTE() If ProcessExists("SciTE.exe") Then $gm_SciTE.ExistsCurr = 1 If $gm_SciTE.ExistsLast = 0 Then $gm_SciTE.ExistsLast = 1 If $gm_SciTE.bHighlight Then _DrawTabItem() AdlibRegister(_MouseHoversTab, 150) EndIf _MarkUnsavedIdleTab() Else $gm_SciTE.ExistsCurr = 0 If $gm_SciTE.ExistsLast = 1 Then $gm_SciTE.ExistsLast = 0 If $gm_SciTE.bHighlight Then AdlibUnRegister(_MouseHoversTab) EndIf EndIf EndFunc Func _MouseHoversTab() Local Static $iHoverLast = 1 ; when starting the program, exit from the item must be simulated Local $mTab = _SciTE_GetActiveTabInfo() If @error Then Return Local $tPoint = _WinAPI_GetMousePos(True, $mTab.hTab) Local $tRect = $mTab.RectItem Local $isHover = _WinAPI_PtInRect($tRect, $tPoint) If $isHover = 1 And $iHoverLast = 0 Then $iHoverLast = 1 ElseIf $isHover = 0 And $iHoverLast = 1 Then $iHoverLast = 0 Return _DrawTabItem() EndIf EndFunc Func _MarkUnsavedIdleTab() If $gm_SciTE.IdlePos = 'none' Then Return Local $hTab = __GetHwnd_SciTeTabCtrl() If @error Then Return SetError(1) Local $iActive = _GUICtrlTab_GetCurFocus($hTab) For $i = 0 To _GUICtrlTab_GetItemCount($hTab) -1 If $i = $iActive And $gm_SciTE.bHighlight Then ContinueLoop If StringRight(_GUICtrlTab_GetItemText($hTab, $i), 1) = '*' Then _DrawMarkerUnsaved($hTab, $i) EndIf Next EndFunc Func _DrawMarkerUnsaved($_hTab, $_iItem) Local $tRect = _GUICtrlTab_GetItemRectEx($_hTab, $_iItem) Local $tRectDraw = DllStructCreate("struct; long Left;long Top;long Right;long Bottom; endstruct") If $gm_SciTE.IdlePos = 'top' Then $tRectDraw.Left = $tRect.Left $tRectDraw.Top = $tRect.Top -1 $tRectDraw.Right = $tRect.Right $tRectDraw.Bottom = $tRect.Top Else $tRectDraw.Left = $tRect.Left $tRectDraw.Top = $tRect.Bottom +2 $tRectDraw.Right = $tRect.Right $tRectDraw.Bottom = $tRect.Bottom +3 EndIf Local $hDC = _WinAPI_GetDC($_hTab) Local $hPen = _WinAPI_CreatePen($PS_SOLID, 2, $gm_SciTE.IdleUnsaved) Local $hOldPen = _WinAPI_SelectObject($hDC, $hPen) _WinAPI_Rectangle($hDC, $tRectDraw) _WinAPI_SelectObject($hDC, $hOldPen) _WinAPI_DeleteObject($hPen) _WinAPI_ReleaseDC(0, $hDC) EndFunc Func _DrawTabItem() Local $mTab = _SciTE_GetActiveTabInfo() If @error Then Return Local $hDC = _WinAPI_GetDC($mTab.hTab) Local $hFont = _WinAPI_CreateFont(14.5, 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, _ $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Lucida Sans Unicode Standard') Local $hOldFont = _WinAPI_SelectObject($hDC, $hFont) Local $tRect = $mTab.RectItem ; extract to variable - otherwise no ByRef access possible Local $dY = (@OSVersion = "Win_7" ? 2 : 1) _WinAPI_InflateRect($tRect, 2, $dY) ; enlarge rectangle _WinAPI_OffsetRect($tRect, 0, 1) ; move rectangle down by 1px ; draw and fill rect Local $hPen = _WinAPI_CreatePen($PS_SOLID, 2, $gm_SciTE.RectColor) Local $hBrush = _WinAPI_CreateSolidBrush($gm_SciTE.BGColor) Local $hOldPen = _WinAPI_SelectObject($hDC, $hPen) Local $hOldBrush = _WinAPI_SelectObject($hDC, $hBrush) _WinAPI_Rectangle($hDC, $tRECT) ; draw text If StringRight($mTab.Item, 1) = '*' Then _WinAPI_SetTextColor($hDC, $gm_SciTE.TextColorUnsaved) Else _WinAPI_SetTextColor($hDC, $gm_SciTE.TextColor) EndIf _WinAPI_SetBkColor($hDC, $gm_SciTE.BGColor) ; move the text down a bit more _WinAPI_OffsetRect($tRect, 0, 3) _WinAPI_DrawText($hDC, $mTab.Item, $tRect, BitOR($DT_BOTTOM,$DT_CENTER)) ; clear ressources _WinAPI_SelectObject($hDC, $hOldFont) _WinAPI_DeleteObject($hFont) _WinAPI_SelectObject($hDC, $hOldPen) _WinAPI_DeleteObject($hPen) _WinAPI_SelectObject($hDC, $hOldBrush) _WinAPI_DeleteObject($hBrush) _WinAPI_ReleaseDC(0, $hDC) EndFunc Func _SciTE_GetActiveTabInfo() Local $mResult[], $hTab = __GetHwnd_SciTeTabCtrl() If @error Then Return SetError(1) $mResult.hTab = $hTab $mResult.Index = _GUICtrlTab_GetCurFocus($hTab) $mResult.Item = _GUICtrlTab_GetItemText($hTab, $mResult.Index) $mResult.RectItem = _GUICtrlTab_GetItemRectEx($hTab, $mResult.Index) Return $mResult EndFunc Func __GetHwnd_SciTE() Local $hScite = WinGetHandle('[ACTIVE]') If _WinAPI_GetClassName($hScite) = 'SciTEWindow' Then Return $hScite Else Return SetError(1, 0, Null) EndIf EndFunc Func __GetHwnd_SciTeTabCtrl() Local $hScite = __GetHwnd_SciTE() If @error Then Return SetError(1, 0, Null) Local $aChild, $hWndTab = Null $aChild = _WinAPI_EnumChildWindows($hScite) ; only visible If Not @error Then For $i = 1 To $aChild[0][0] If $aChild[$i][1] = "SciTeTabCtrl" Then $hWndTab = $aChild[$i][0] ExitLoop EndIf Next EndIf Return SetError(($hWndTab = Null ? 1 : 0), 0, $hWndTab) EndFunc ; read from INI if exists Func _IniOrDefault($_sINI, $_sKey, $_sDefault, $_sec=Null) Local $sVal = $_sDefault, $sSec = $_sec = Null ? 'scheme' : $_sec If FileExists($_sINI) Then If $sSec = 'scheme' Then $sSec = IniRead($_sINI, 'scheme', 'current', 'default') $sVal = IniRead($_sINI, $sSec, $_sKey, $_sDefault) EndIf Return $sVal EndFunc SciTE_DrawTabItem.au31 point
-
This small library includes only one function, which allows to set resizing for elements created with UDF (_GUICtrl*_Create). It works just the same as standard GUICtrlSetResizing. Also this function compatible/works with standard controls. Example: #include <GUIRichEdit.au3> #include <GUIComboBox.au3> #include 'GUICtrlSetResizingEx.au3' $hForm = GUICreate('GUICtrlSetResizingEx Example 1', 380, 330, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_THICKFRAME, $WS_OVERLAPPEDWINDOW, $WS_TILEDWINDOW, $WS_TABSTOP), $WS_EX_COMPOSITED) $hRichEdit = _GUICtrlRichEdit_Create($hForm, 'Edit1', 5, 5, 250, 250) _GUICtrlSetResizingEx($hRichEdit, BitOR($GUI_DOCKLEFT, $GUI_DOCKRIGHT, $GUI_DOCKTOP)) $hCombo = _GUICtrlComboBox_Create($hForm, 'Item', 5, 280, 250, 50, $CBS_DROPDOWNLIST) _GUICtrlComboBox_SetCurSel($hCombo, 0) _GUICtrlSetResizingEx($hCombo, BitOR($GUI_DOCKLEFT, $GUI_DOCKRIGHT, $GUI_DOCKBOTTOM)) $iButton = GUICtrlCreateButton('Native Button', 270, 5, 100, 25) _GUICtrlSetResizingEx(-1, BitOR($GUI_DOCKRIGHT, $GUI_DOCKTOP, $GUI_DOCKSIZE)) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE GUIDelete($hForm) Exit EndSwitch WEnd GUICtrlSetResizingEx_1.3.zip1 point