Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 04/15/25 in all areas

  1. Angus Robertson

    TWSocket,,,

    I've just got this working with new types Socket_Address = record { V9.5 used to store an IPv4 or IPv6 address } Sockaddr: PSockAddrIn6; SockaddrLength: Integer; end; TSocketAddress = Socket_Address; CSADDR_INFO = record { V9.5 used to connection IP information } LocalAddr: TSocketAddress; { family, address and port } RemoteAddr: TSocketAddress; iSocketType: Integer; { SOCK_STREAM or SOCK_DGRAM } iProtocol: Integer; { IPPROTO_TCP or IPPROTO_UDP } Buffer: array[0..64] of Byte; { space for PSockAddrIn6 records } end; TCSAddrInfo = CSADDR_INFO; Need to ensure it handles all ways of connecting, and update a sample to show the result, hopefully later today. Angus
  2. Hello, if you haven't noticed yet: with 12.3 Embarcadero also released a new additional tool for subscription owners via GetIt package manager (Tools/GetIt package manager). It is called "The Android SDK manager GUI" and can be used to update Android SDK/NDK etc. in a graphical way. It is a replacement for the graphical SDK manager the Android SDK once contained, which cot replaced by a cumbersome batch file (yes, the batch file is good for automation, but otherwise cumbersome). The SDK manager GUI can also export the selected configuration and import it on another PC, great for easy synchronisation of development machines. What the tool doesn't do is to update the paths in the IDE and it is unfortunately not added to the menu in the IDE.
  3. Angus Robertson

    TWSocket,,,

    I'm sure you are correct, but a few spare bytes in a buffer might provide future proofing. I'm surprised Socket_Address has not been used for other APIs, Microsoft has so many of these similar but not quite the same structures. Fortunately, ICS has a simple function to convert PSockAddrIn6 into a string. Angus
  4. The original Github repo (https://github.com/rvelthuis/DelphiBigNumbers) has a pdf by Rudy explaining the library. And it says this :
  5. Kas Ob.

    TWSocket,,,

    I forgot to mention important thing about that structure and its size. You can't and must not put it on the stack !, it will overflow and destroy/corrupt the stack, so it must be on the heap and must be zeroed before usage as best practice, because there is two addresses (pointing to two structures) will be filled by that API and it will put them right after the initial structure and fix the addresses.
  6. Kas Ob.

    TWSocket,,,

    Here a fully working example, modified from a code for different thing, yet it shows successful use of SO_BSP_STATE unit uReadSocketInfo; interface uses Windows, Winsock2; function WSAInitialize(MajorVersion, MinorVerion: Integer): Boolean; function WSADeInitialize: Boolean; function CheckTCPPortNB(const IP: string; Port: Integer; out TimeMS: Integer): Boolean; var CHECKPOINT_TIMEOUT_MS: integer = 1000; implementation procedure GetSocketInformation(s: TSocket); var pSockAddresssI: PCSADDR_INFO; Res, WsaLError, OptLen: Integer; begin OptLen := SizeOf(CSADDR_INFO) + 128; // yes the original size is 24, but more is needed and will fail on 24 // for IPv4 an extra of 32 bytes is enough instead of 128 pSockAddresssI := GetMemory(OptLen); try Res := getsockopt(s, SOL_SOCKET, SO_BSP_STATE, PAnsiChar(pSockAddresssI), OptLen); if Res = SOCKET_ERROR then WsaLError := WSAGetLastError else Writeln('Socket information :'); finally FreeMemory(pSockAddresssI); end; end; function CheckTCPPortNB(const IP: string; Port: Integer; out TimeMS: Integer): Boolean; var s: TSocket; Addr: TSockAddrIn; SAddr: TSockAddr absolute Addr; QPF, QPC1: Int64; NonBlockMode: DWORD; Res: Integer; FDW, FDE: fd_set; TimeVal: TTimeVal; function GetElapsedTime: Integer; var QPC2: Int64; begin QueryPerformanceCounter(QPC2); Result := (QPC2 - QPC1) div (QPF div 1000); end; begin Result := False; TimeMS := 0; s := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if s = INVALID_SOCKET then Exit; NonBlockMode := 1; ioctlsocket(s, Integer(FIONBIO), NonBlockMode); Addr.sin_family := AF_INET; Addr.sin_addr.S_addr := inet_addr(PAnsiChar(AnsiString(IP))); Addr.sin_port := htons(Port); QueryPerformanceFrequency(QPF); QueryPerformanceCounter(QPC1); Res := connect(s, SAddr, SizeOf(SAddr)); if (Res = SOCKET_ERROR) and (WSAGetLastError = WSAEWOULDBLOCK) then begin TimeVal.tv_sec := 0; // 1 sec = 1000000 usec TimeVal.tv_usec := 1000; // 1 ms = 1000 usec repeat FDW.fd_count := 1; FDW.fd_array[0] := s; FDE.fd_count := 1; FDE.fd_array[0] := s; TimeMS := GetElapsedTime; Res := select(1, nil, @FDW, @FDE, @TimeVal); until (Res > 0) or (TimeMS >= CHECKPOINT_TIMEOUT_MS); end; Result := (FDW.fd_count = 1) and (FDE.fd_count = 0); /// we have connected socket with full valid information if Result then begin GetSocketInformation(s); end; /// TimeMS := GetElapsedTime; if s <> INVALID_SOCKET then closesocket(s); end; function WSAInitialize(MajorVersion, MinorVerion: Integer): Boolean; var WSA: TWsaData; begin Result := WSAStartup(MakeWord(MajorVersion, MinorVerion), WSA) = 0; if Result then begin Result := (Byte(WSA.wVersion shr 8) = MinorVerion) and (Byte(WSA.wVersion) = MajorVersion); if not Result then begin Result := False; WSADeInitialize; end; end; end; function WSADeInitialize: Boolean; begin Result := WSACleanup = 0; end; initialization WSAInitialize(2, 2); finalization //WSADeInitialize; end. a small project to use it program SocketInformation; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, uReadSocketInfo in 'uReadSocketInfo.pas'; var Time : Integer; begin try CheckTCPPortNB('142.251.36.46', 80, Time); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; Readln; end. Put a break point with debugger on the getsockopt and you will get 32 bytes additional bytes (on top the 24 bytes, the structure size) is needed for IPv4 so i suspect more is needed for IPv6, this is undocumented behavior.
  7. Angus Robertson

    TWSocket,,,

    Sorry, no time to debug this at the moment. Angus
  8. It apparently is: It does not happen on my laptop with a single HD screen. Nor on my desktop when I turn off the 4K monitor or alternatively the HD monitor. And after starting Delphi once with only the HD monitor connected, it no longer happens with both monitors. Sounds like an easily reproducible problem, doesn't it?
  9. pyscripter

    New ChatLLM application.

    A new version 1.2.0 of ChatLLM has been released: New Features: Much improved rendering of responses on a par with the Web Chat interfaces of the LLM providers. Syntax highlighting of code (300 languages are now supported thanks to Prism). Support for DeepSeek models Support for reasoning models such as OpenAI's o1-mini and DeeepSeek's deepseek-reasoner. Exposed the temperature LLM parameter. Screenshots: Settings: User interface: Reasoning with deepseek-reasoner: And by the way DeepSeek is so much better than Gemini on Delphi coding.
  10. Better Translation Manager https://bitbucket.org/anders_melander/better-translation-manager The Better Translation Manager (BTM) is a replacement for the Delphi Translation Manager a.k.a. the Integrated Translation Environment (ITE) and External Translation Manager (ETM). Why is it better? Well, for one thing, it's free but more important; It actually works - unlike the ITE/ETM. Why? The standard Translation Manager that ships with Delphi today was originally an individual product known as the Borland Translation Suite. With Delphi 5 it became a part of the enterprise edition. The Borland Translation Suite showed great promise but unfortunately it never evolved from its roots as an external tool and has always been hampered by severe bugs that made it completely unusable in practice. As a result nobody uses it. This can be witnessed by the plethora of homegrown and commercial alternatives. The great benefit of the standard translation system is that it just works (this is the system itself I'm talking about, not the tools. The tools suck). Apart from the requirement that you must use resourcestrings you don't need to do anything special when writing your code. At run time you just place the compiled resource modules in the same folder as your application and the Delphi Run Time Library automatically takes care of loading and using the translations based on the current Windows user interface language. Anyway, since Embarcadero has now finally admitted that they are never going to fix the Delphi Translation Manager and instead recommend that we find alternative solutions, I decided that it was time I solved this little problem once and for all. The core functionality of the Better Translation Manager was written in two weeks during my summer vacation in Italy 2019. Amazing what you can do with a little pasta! Features Does not require any changes to the source code of the application being translated. Works with the existing standard Delphi localization system. Translates resourcestrings and all strings in forms regardless of any 3rd party components used. Works on compiled application. Source code is never used. Generates localized binary resource modules (resource DLLs). Does not use an external compiler. Can import existing translations from compiled application and resource modules or from XLIFF localization source files (dfn, rcn files). Read and save TMX and TBX translation memory files. Import Translation Memory from TMX (Translation Memory eXchange), TBX (TermBase eXchange), Microsoft Glossary and CSV. Machine Translation using Translation Memory, Microsoft Translation Service or Microsoft Terminology Service. Forms, Components, Types and Values that should be ignored can be specified in a Stop List. Translations are Spell Checked. Validation Rules to catch common translation mistakes. Supports Right To Left (RTL) editing based on translation language. Translation project is stored in a single XML file. Command line interface for use in automated build systems. Fast! Refreshing a large project typically takes less than a second vs. many minutes with the ITE/ETM. Supports all Unicode versions of Delphi (i.e. Delphi 9 and later). Resource modules contain the version resource of the source application. What it doesn't do There's one task that BTM, by design, doesn't attempt to solve: Localizing the placement and size of controls. Since it has been my experience that it is a far better idea to design the user interface in such a way that the layout automatically accommodates changes in font- and text size and shorter/longer texts due to translation, I decided from the start that I would not be supporting localization of size and position of controls. This also relieved me of having to create a run time form designer, supporting 3rd party controls visually (something that nobody so far has managed to find a foolproof solution to) and deciding what individual properties constitutes size/position values. Instead I just localize all string values - and only string values. But wait... There's More! Yup, you not only get this little wonder for free. You get the full source code too. Grab it at the repository linked at top. More details at the repository. Enjoy / Anders Melander
  11. I’ve noticed a weird bug in all Delphi versions since 12.0 when building an iOS app against SDK 18 (running on an iOS 18 device). If you have a TMemo set to ControlType=Platform, it can’t be scrolled! We’ve just updated our app for D12.2 built against SDK 18.2 and had users complaining. If we build against SDK 17 (as our app used to be) it scrolls fine. Unfortunately, Apple are mandating all apps must be built against SDK 18 from 24th April so we need to find a solution. Ive checked Delphi 12.3 and it’s still broken in there too. The memo has to use platform control type to support Arabic users and their existing notes data (R2L isn’t supported in the styled memo). I’ve logged a QP issue for this but wonder if anyone could suggest any other workarounds or options? We need a fix pretty quickly! https://embt.atlassian.net/servicedesk/customer/portal/1/RSS-3318 Thanks
×