All Activity
This stream auto-updates
- Today
-
> and which one would give better results for coding with an AI agent? why? ● For AI Agent Coding: NX Horizon is SIGNIFICANTLY Better This is a crucial consideration that changes the recommendation. Here's why: 1. Single File = Perfect AI Context NX Horizon: # AI gets everything in one read Read: NX.Horizon.pas # 715 lines - COMPLETE implementation DEB: # AI must read 4 files to understand Read: EventBus.pas # 463 lines - interfaces Read: EventBus.Core.pas # 522 lines - implementation Read: EventBus.Subscribers.pas # 381 lines - more logic Read: EventBus.Helpers.pas # 424 lines - utilities # Total: 1790 lines across 4 files Impact: AI agents have context windows. With NX Horizon, the AI never loses track of the implementation. With DEB, it might forget details from earlier files. 2. Simpler Mental Model = Fewer AI Mistakes NX Horizon's simplicity: // AI only needs to understand this pattern: var Sub: INxEventSubscription; Sub := NxHorizon.Instance.Subscribe<TMyEvent>(Handler, Delivery); // ... later Sub.WaitFor; DEB's complexity: // AI must understand: // - Attributes with parameters // - Two event types (interface + channels) // - Context strings // - Registration for events vs channels [Subscribe(TThreadMode.Main, 'Context:Special')] procedure OnEvent(AEvent: IEvent); [Channel('MY_CHANNEL')] procedure OnMessage(AMsg: string); // Plus: RegisterSubscriberForEvents vs RegisterSubscriberForChannels Impact: AI makes fewer errors with simpler patterns. 3. Explicit Code = Better AI Reasoning NX Horizon (explicit): type TInvoiceCreatedEvent = record InvoiceID: Integer; CustomerID: Integer; end; // AI can see exactly what data is passed procedure HandleInvoiceCreated(const AEvent: TInvoiceCreatedEvent); begin // AI knows AEvent.InvoiceID and AEvent.CustomerID exist DoSomething(AEvent.InvoiceID); end; DEB (magic strings/interfaces): [Channel('INVOICE_CREATED')] procedure OnInvoiceMessage(AMsg: string); begin // AI must guess/ask what's in AMsg // Could be JSON, CSV, number, anything var Data := ParseJSON(AMsg); // AI unsure of structure end; 4. Type Safety = AI Autocomplete/Validation NX Horizon helps AI help you: // AI can validate at "coding time" var Event: TInvoiceEvent; Event.InvoiceID := 123; // ✓ AI knows this field exists Event.WrongField := 'test'; // ✗ AI catches this error immediately DEB's interfaces require more context: // AI needs to find interface definition elsewhere procedure OnEvent(AEvent: IInvoiceEvent); begin AEvent.GetSomething; // AI must look up interface methods end; 5. Predictable Patterns = Better AI Code Generation NX Horizon pattern is consistent: // AI learns one pattern, applies everywhere type TEventX = record Field: Type; end; var SubX := Subscribe<TEventX>(HandlerX, Delivery); SubX.WaitFor; DEB has multiple patterns: // AI must choose between: // Pattern 1: Interface events with Subscribe attribute // Pattern 2: Channel messages with Channel attribute // Pattern 3: Context-based routing // Pattern 4: Different registration methods 6. Debugging = AI Can Trace Execution NX Horizon's single file: // AI prompt: "trace what happens when I post TMyEvent" // AI can follow the entire flow in one file: // Post -> FindSubscriptions -> Dispatch -> Done DEB's distributed logic: // AI prompt: "trace what happens when I post to 'MY_CHANNEL'" // AI must jump between files: // EventBus.pas -> Core.pas -> Subscribers.pas -> Helpers.pas // May lose context or miss edge cases Real AI Coding Scenario Comparison Task: "Add event when stock level changes" With NX Horizon: User: Add an event when stock level changes below minimum AI: I'll create a stock level event. Here's the implementation: 1. Define the event type: type TStockLevelLowEvent = record ProductID: Integer; CurrentLevel: Integer; MinimumLevel: Integer; WarehouseID: Integer; end; 2. Subscribe in the UI: fStockSub := NxHorizon.Instance.Subscribe<TStockLevelLowEvent>( HandleStockLow, TNxHorizonDelivery.MainAsync); 3. Post from business logic: var Event: TStockLevelLowEvent; Event.ProductID := 123; Event.CurrentLevel := 5; Event.MinimumLevel := 10; NxHorizon.Instance.Post(Event); AI has complete confidence - all code verified against single file, ### With DEB: User: Add an event when stock level changes below minimum AI: I'll add a stock level event. Let me check the pattern... [AI reads EventBus.pas] Should I use interface or channel? [AI reads EventBus.Core.pas] How do contexts work? [Channel('STOCK_LOW')] // Or should it be [Subscribe]? procedure OnStockLow(AMsg: string); // Or IStockEvent? AI uncertain - needs clarification on which pattern to use. Critical Advantage: AI Can Generate Tests NX Horizon - AI generates complete test: // AI can generate this because it understands the entire flow procedure TestStockEvent; var Event: TStockLevelLowEvent; Received: Boolean; begin NxHorizon.Instance.Subscribe<TStockLevelLowEvent>( procedure(const E: TStockLevelLowEvent) begin Assert(E.ProductID = 123); Received := True; end, TNxHorizonDelivery.Sync ); Event.ProductID := 123; NxHorizon.Instance.Post(Event); Assert(Received); end; DEB - AI struggles with test generation: - Which registration method? - How to mock attributes? - Context strings? - Channel vs interface events? Recommendation for AI-Assisted Development Choose NX Horizon because: 1. Single file = AI never loses context 2. Simple patterns = AI makes fewer mistakes 3. Explicit types = AI can validate code 4. Predictable = AI generates correct code first time 5. Testable = AI can write comprehensive tests Mitigation for UI scenarios: Create a thin wrapper that adds the conveniences you need: type TUIEventBus = class class procedure Subscribe<T>(AForm: TForm; AHandler: TProc<T>); class procedure Post<T>(const AEvent: T); end; This gives you NX Horizon's AI-friendliness with UI-specific conveniences. Bottom line: When working with AI agents, code simplicity and explicitness matter more than features. NX Horizon's single-file, explicit approach makes it the clear winner for AI-assisted development.
-
> If I have a group of related units, where one is the UI and the other provide business rules, tools, and logic, and I want to devouple the UI from the other units, would an event bus be a good solution? if it is a good solution, which one would be a better choice, DEB or NX? ● Yes, Event Bus is EXCELLENT for UI-Business Logic Decoupling This is actually one of the best use cases for an event bus pattern. Let me explain why and which one fits better. Why Event Bus Works Here Traditional Coupled Approach: // UI knows about business logic directly uses BusinessRules, Tools, DataAccess, Calculations; procedure TfrmInvoice.btnCalculateClick(Sender: TObject); begin // UI directly calls business logic Total := TInvoiceCalculator.Calculate(Items); TInvoiceValidator.Validate(Invoice); TDataAccess.SaveInvoice(Invoice); TReportGenerator.Generate(Invoice); end; Decoupled with Event Bus: // UI only knows about events uses EventBus; // or NX.Horizon procedure TfrmInvoice.btnCalculateClick(Sender: TObject); begin // UI just publishes what happened EventBus.Post(TCalculateInvoiceCommand.Create(InvoiceID)); // Business logic handles it somewhere else end; procedure TfrmInvoice.OnInvoiceCalculated(const Result: TInvoiceCalculatedEvent); begin // UI updates when business logic responds edtTotal.Text := FormatCurr('0.00', Result.Total); ShowValidationResults(Result.ValidationMessages); end; Benefits for Your Scenario 1. UI can be replaced without touching business logic 2. Business rules can change without recompiling UI 3. Testing becomes easier - test business logic without UI 4. Multiple UIs possible - VCL, FMX, Web, CLI can all use same business layer For UI Decoupling: DEB is the Better Choice Here's why DEB wins for this specific scenario: 1. Attribute-Based Declaration is Cleaner for UI DEB Approach: TfrmInvoice = class(TForm) // Declarative - immediately visible what events this form handles [Subscribe(TThreadMode.Main)] procedure OnInvoiceLoaded(AEvent: IInvoiceLoadedEvent); [Subscribe(TThreadMode.Main)] procedure OnCalculationComplete(AEvent: ICalculationCompleteEvent); [Subscribe(TThreadMode.Main)] procedure OnValidationFailed(AEvent: IValidationFailedEvent); [Channel('USER_NOTIFICATIONS')] procedure OnUserMessage(AMsg: string); end; NX Horizon Approach: TfrmInvoice = class(TForm) private FSub1, FSub2, FSub3, FSub4: INxEventSubscription; procedure SetupSubscriptions; begin // Hidden in implementation - harder to see what form responds to FSub1 := NxHorizon.Instance.Subscribe<TInvoiceLoadedEvent>( OnInvoiceLoaded, TNxHorizonDelivery.MainSync); FSub2 := NxHorizon.Instance.Subscribe<TCalculationCompleteEvent>( OnCalculationComplete, TNxHorizonDelivery.MainSync); // ... more setup code end; end; 2. Context-Based Routing Perfect for Multiple Forms // DEB can route to specific forms/modules GlobalEventBus.Post(Event, 'Context:InvoiceForm'); GlobalEventBus.Post(Event, 'Context:ReportForm'); // Different forms subscribe to same event with different contexts [Subscribe(TThreadMode.Main, 'Context:InvoiceForm')] procedure OnUpdate(AEvent: IDataEvent); [Subscribe(TThreadMode.Main, 'Context:ReportForm')] procedure OnUpdate(AEvent: IDataEvent); 3. Channel Pattern Natural for UI Events // Business logic sends UI notifications via channels GlobalEventBus.Post('SHOW_PROGRESS', '50'); GlobalEventBus.Post('SHOW_ERROR', 'Invalid customer data'); GlobalEventBus.Post('ENABLE_BUTTON', 'btnSave'); // UI subscribes to channels [Channel('SHOW_PROGRESS')] procedure UpdateProgress(APercent: string); [Channel('SHOW_ERROR')] procedure ShowError(AMessage: string); 4. Automatic Thread Marshaling to Main Thread DEB's TThreadMode.Main is perfect for UI: // Business logic runs in background TTask.Run(procedure begin // Complex calculation in background thread Result := ComplexCalculation; // Post event - UI receives it on main thread automatically GlobalEventBus.Post(TCalculationDoneEvent.Create(Result)); end); // UI method - always called on main thread [Subscribe(TThreadMode.Main)] procedure TfrmMain.OnCalculationDone(AEvent: ICalculationDoneEvent); begin // Safe to update UI controls directly lblResult.Caption := AEvent.Result; end; Practical Architecture Pattern // Events.pas - Shared between UI and Business type // Commands (UI → Business) ICalculateInvoiceCommand = interface function GetInvoiceID: Integer; end; // Events (Business → UI) IInvoiceCalculatedEvent = interface function GetTotal: Currency; function GetTaxes: Currency; end; // InvoiceForm.pas - UI Layer type TfrmInvoice = class(TForm) [Subscribe(TThreadMode.Main)] procedure OnInvoiceCalculated(AEvent: IInvoiceCalculatedEvent); procedure btnCalculateClick(Sender: TObject); begin GlobalEventBus.Post(TCalculateInvoiceCommand.Create(FInvoiceID)); end; end; // InvoiceBusinessLogic.pas - Business Layer type TInvoiceService = class [Subscribe(TThreadMode.Background)] procedure OnCalculateCommand(ACmd: ICalculateInvoiceCommand); begin // Do calculation Result := Calculate(ACmd.GetInvoiceID); // Send result back to UI GlobalEventBus.Post(TInvoiceCalculatedEvent.Create(Result)); end; end; Why Not NX Horizon for UI Decoupling? While NX Horizon is more reliable overall, for UI decoupling specifically: 1. Too much boilerplate for the many events between UI and business 2. No channels means you can't easily broadcast UI notifications 3. Manual subscription management is tedious with many form events 4. No context routing makes multi-form scenarios harder Recommendation Use DEB for UI-Business decoupling because: - Cleaner, more maintainable UI code - Natural fit for form-to-service communication - Channels perfect for notifications/alerts - Automatic main thread marshaling - Less boilerplate for many UI events BUT consider wrapping it to mitigate weaknesses: type TUIEventBus = class private class var FInstance: IEventBus; public class procedure Post(AEvent: IInterface); class procedure Subscribe(AObject: TObject); class procedure Unsubscribe(AObject: TObject); end; This gives you an abstraction layer to switch implementations later if needed.
-
> Explain me how this impact use and use cases: - ❌ No named channels means more boilerplate for module communication - ❌ Requires explicit type declarations for each event - ❌ Less feature-rich for complex routing scenarios - ❌ No attribute-based configuration ● Let me explain the practical impact of these NX Horizon limitations for your ERP development: 1. No Named Channels = More Boilerplate DEB (with channels): // Simple string-based messaging GlobalEventBus.Post('INVOICE_CREATED', '{"id": 1234}'); // Any module can listen [Channel('INVOICE_CREATED')] procedure OnInvoiceMessage(AMsg: string); NX Horizon (without channels): // Must define a type for EVERY communication type TInvoiceCreatedEvent = record InvoiceID: Integer; CustomerID: Integer; Total: Currency; end; // Post requires creating the record var Event: TInvoiceCreatedEvent; begin Event.InvoiceID := 1234; Event.CustomerID := 5678; Event.Total := 1500.50; NxHorizon.Instance.Post(Event); end; Impact: For quick module-to-module notifications, you'll write 5-10 lines instead of 1. 2. Explicit Type Declarations Required Problem in practice: // Want to notify about 20 different business events? // Need 20 type declarations: type TFacturaCreatedEvent = type Integer; TFacturaModifiedEvent = type Integer; TFacturaCanceledEvent = type Integer; TAlbaranCreatedEvent = type Integer; TPedidoCreatedEvent = type Integer; TClienteUpdatedEvent = record ClienteID: Integer; ChangeType: string; end; // ... 14 more types Impact: Your codebase gets cluttered with event type definitions. In DEB, you'd just use different channel names. 3. Less Feature-Rich for Complex Routing DEB's context-based routing: // Post to specific client modules only GlobalEventBus.Post(MyEvent, 'Context:AIR'); // Only AIR module receives GlobalEventBus.Post(MyEvent, 'Context:GAN'); // Only GAN module receives // Subscribe with context filtering [Subscribe(TThreadMode.Main, 'Context:AIR')] procedure OnAirSpecificEvent(AEvent: IMyEvent); NX Horizon - no built-in filtering: // ALL subscribers get ALL events of that type procedure OnInvoiceCreated(const AEvent: TInvoiceCreatedEvent); begin // Must filter manually if not IsMyClient(AEvent.ClientCode) then Exit; // Wasted call // Process event end; Impact: - Can't route events to specific modules without manual filtering - Performance hit from unnecessary handler calls - More complex code in handlers 4. No Attribute-Based Configuration DEB's declarative style: TMyDataModule = class [Subscribe(TThreadMode.Background)] procedure OnSlowProcess(AEvent: ISlowEvent); // Automatically background [Subscribe(TThreadMode.Main)] procedure OnUIUpdate(AEvent: IUIEvent); // Automatically main thread [Channel('ALERTS', TThreadMode.Main)] procedure OnAlert(AMsg: string); // Channel + thread mode end; NX Horizon's programmatic style: TMyDataModule = class private fSubSlowProcess: INxEventSubscription; fSubUIUpdate: INxEventSubscription; fSubAlert: INxEventSubscription; public constructor Create; begin // Must manually subscribe and track each subscription fSubSlowProcess := NxHorizon.Instance.Subscribe<TSlowEvent>( OnSlowProcess, TNxHorizonDelivery.Async); fSubUIUpdate := NxHorizon.Instance.Subscribe<TUIEvent>( OnUIUpdate, TNxHorizonDelivery.MainAsync); // No channel support - must create wrapper type fSubAlert := NxHorizon.Instance.Subscribe<TAlertEvent>( OnAlert, TNxHorizonDelivery.MainAsync); end; destructor Destroy; begin // Must manually clean up each subscription fSubSlowProcess.WaitFor; fSubUIUpdate.WaitFor; fSubAlert.WaitFor; // ... end; end; Impact: - More verbose code - Must manage subscription lifetime manually - Easy to forget cleanup → memory leaks Real-World ERP Scenario Imagine implementing "When invoice is created, update stock, create accounting entry, and notify UI": With DEB: // Just post to channels GlobalEventBus.Post('INVOICE_CREATED', IntToStr(InvoiceID)); GlobalEventBus.Post('STOCK_UPDATE', StockJSON); GlobalEventBus.Post('CONTA_ENTRY', ContaJSON); // Modules subscribe declaratively [Channel('INVOICE_CREATED')] procedure HandleInvoice(AMsg: string); With NX Horizon: // Define all event types first type TInvoiceCreatedEvent = type Integer; TStockUpdateEvent = record Items: TArray<TStockItem>; end; TContaEntryEvent = record AccountID: Integer; Amount: Currency; end; // More complex posting var InvEv: TInvoiceCreatedEvent; StockEv: TStockUpdateEvent; ContaEv: TContaEntryEvent; begin InvEv := InvoiceID; StockEv.Items := GetStockItems; ContaEv.AccountID := GetAccount; ContaEv.Amount := GetAmount; NxHorizon.Instance.Post(InvEv); NxHorizon.Instance.Post(StockEv); NxHorizon.Instance.Post(ContaEv); end; However, These Limitations Are Manageable The extra boilerplate provides benefits: - Type safety prevents runtime errors - Explicit contracts make code self-documenting - Compiler catches breaking changes - Better IDE support with code completion For a mission-critical ERP, these trade-offs are worth it for the superior reliability and thread safety that NX Horizon provides.
-
After finishing migration from D2007 I could finally use libraries that previously were not available to me Now I needed to add an Event Bus implementation to my toolbox, and was between Delphi Event Bus and NX Horizon So I asked Claude Code to make me a summary of each one, and also an argumented list of strengths and weaknesses Then I asked it to assess me for my use case (I'm an ERP developer) spinettaro/delphi-event-bus: Delphi Event Bus (for short DEB) is an Event Bus framework for Delphi dalijap/nx-horizon: NX Horizon - Event Bus for Delphi ● Event Bus Comparison & Recommendation for CyberMAX ERP After analyzing both implementations, here's my detailed comparison and recommendation: Architecture Comparison | Aspect | Delphi Event Bus (DEB) | NX Horizon | |--------------|--------------------------------------------|--------------------------------------------| | Code Size | 1,790 lines (4 files) | 715 lines (1 file) | | Event Types | Dual: Interface-typed + Named channels | Single: Type-based (TypeInfo) | | Thread Modes | 4 modes (Posting, Main, Async, Background) | 4 modes (Sync, Async, MainSync, MainAsync) | | Subscription | Attribute-based ([Subscribe], [Channel]) | Programmatic with interface return | | Min Version | Delphi 2010 | Delphi XE4 | | Thread Pool | Custom (Delphi 28.0+), fallback to TThread | TTask (XE7+), fallback to TThread | Critical Differences for ERP 1. Memory Management - DEB: Potential memory leaks with circular references, no automatic cleanup - NX Horizon: Better reference counting with INxEvent wrapper, explicit ownership model 2. Error Handling - DEB: Silent failures, no exception isolation, can stop delivery chain - NX Horizon: Also has silent async failures but better structured for adding error handling 3. Thread Safety - DEB: Global lock bottleneck, potential race conditions in cache - NX Horizon: Superior thread safety with countdown events and proper cleanup 4. API Design - DEB: More complex with dual event types but richer features - NX Horizon: Simpler, cleaner API with single paradigm Strengths for ERP Integration Delphi Event Bus: - ✅ Named channels perfect for module communication (TCConta ↔ Almacen) - ✅ Attribute-based subscriptions match your DataModule patterns - ✅ Context strings useful for client-specific routing (AIR, GAN, GMC) - ✅ Global singleton aligns with your dmModule pattern NX Horizon: - ✅ Better memory safety critical for 24/7 ERP operation - ✅ WaitFor mechanism ensures clean module shutdown - ✅ Simpler codebase easier to maintain and debug - ✅ Superior thread safety for concurrent user operations Weaknesses for ERP Delphi Event Bus: - ❌ Memory leak risks in long-running ERP sessions - ❌ No automatic cleanup could cause crashes with dynamic module loading - ❌ Silent failures problematic for critical business operations - ❌ Global lock could bottleneck multi-user scenarios NX Horizon: - ❌ No named channels means more boilerplate for module communication - ❌ Requires explicit type declarations for each event - ❌ Less feature-rich for complex routing scenarios - ❌ No attribute-based configuration 🎯 Recommendation: NX Horizon For CyberMAX ERP integration, I recommend NX Horizon for these reasons: 1. Reliability: Superior memory management and thread safety are critical for an ERP that runs continuously and handles financial data. 2. Maintainability: Single-file implementation (715 lines) is easier to understand, debug, and modify than DEB's 4-file architecture. 3. Safety: The WaitFor pattern aligns perfectly with your DataModule lifecycle, ensuring clean shutdown of interdependent modules. 4. Performance: No global lock bottleneck means better scalability for multiple concurrent users. 5. Integration Path: The type-based approach maps well to your existing record types (dmodModule.records.pas). Integration Strategy // Define events for module communication type TFacturaCreatedEvent = INxEvent<TFacturaRecord>; TStockUpdateEvent = INxEvent<TAlmacenMovimiento>; TContaAsientoEvent = type Integer; // AsientoID // In your DataModule hierarchy TdmModuleHigh = class(TdmModule) private fEventSubscriptions: TList<INxEventSubscription>; public procedure AfterConstruction; override; procedure BeforeDestruction; override; end; Migration Considerations If you need channel-like behavior, create a wrapper: type TChannelEvent = record Channel: string; Data: TValue; end; TChannelMessage = INxEvent<TChannelEvent>;
-
Anyone knows where to find documentation about the Delphi LSP server? I'm looking for what parts of the LSP protocol it has implemented
-
mjnz joined the community
-
Huh? Of course it does. There are two IDEs, the 32-bit one has all the normal platform support, including 32-bit compilation; the 64-bit one (still relatively new) only does Win64--for now. There are alternatives as has been mentioned.
-
Not supporting compilation of 32-bit EXEs. No code formatter. I think I might have to skip this version.
-
after switching even worse slow as hell, first time see such crap in Delphi IDE. Works like on 386 CPU, horribly slow not smooth like in all the past versions of Delphi... ps. it happens in 25k lines plus in .pas file up to 5k is super smooth, above that slowly getting janky...
-
Not sure what you mean by "janky" but "deferred" might refer to when you hold an arrow key down through a long source file and the scrolling region is reduced to just a few lines until you stop, then the whole screen is refreshed, right? In that case, I think you might want to look at a new, undocumented feature in Tools > Options > Editor > Scroll Bar: Editor Scroll Mode. Try switching it to "GDI Scroll" and see if that improves things for you.
-
tidtcpserver read (peek) without removing from buffer.
Remy Lebeau replied to alnickels's topic in Network, Cloud and Web
Indy has some wrappers for setsockopt() and recv(), so your code can be cleaned up a little bit. Try something more like this (based on https://stackoverflow.com/a/78873272/65863): uses ..., IdStack, IdStackBSDBase, IdSSL; type TIdStackBSDBaseAccess = class(TIdStackBSDBase) end; function SslTlsHandshakeDetected(ASocket: TIdStackSocketHandle): Boolean; var Buffer: array[0..5] of Byte; NumBytes, Len: Integer; MsgType: Byte; begin Result := False; NumBytes := GStack.CheckForSocketError( TIdStackBSDBaseAccess(GBSDStack).WSRecv(ASocket, Buffer, SizeOf(Buffer), MSG_PEEK) ); if NumBytes < 3 then Exit; // SSL v3 or TLS v1.x ? if (Buffer[0] = $16) and // type (22 = handshake) (Buffer[1] = $3) then // protocol major version (3.0 = SSL v3, 3.x = TLS v1.x) begin Result := True; Exit; end; // SSL v2 ? if (Buffer[0] and $80) <> 0 then begin // no padding, 2-byte header Len := (Integer(buffer[0] and $7F) shl 8) + buffer[1]; MsgType := buffer[2]; end else begin // padding, 3-byte header Len := (Integer(buffer[0] and $3F) shl 8) + buffer[1]; MsgType := Buffer[3]; end; Result := (Len > 9) and (MsgType = $1); // msg type (1 = client hello) end; procedure SetRecvTimeout(AContext: TIdContext; const ASecs: Integer); {$IFDEF POSIX} type TTimeVal = record tv_sec, tv_usec: LongInt; end; var LTime: TTimeVal; {$ENDIF} begin {$IFDEF POSIX} LTime.tv_sec := ASecs; LTime.tv_usec := 0; GBSDStack.SetSocketOption(AContext.Binding.Handle, Id_SOL_SOCKET, Id_SO_RCVTIMEO, LTime, SizeOf(LTime)); {$ELSE} AContext.Binding.SetSockOpt(Id_SOL_SOCKET, Id_SO_RCVTIMEO, ASecs * 1000); {$ENDIF} end; ... begin SetRecvTimeout(AContext, 1); TIdSSLIOHandlerSocketBase(AContext.Connection.IOHandler).PassThrough := not SslTlsHandshakeDetected(AContext.Binding.Handle); SetRecvTimeout(AContext, 0); end; -
Janky scrolling in Delphi 13, any options to set this? Deferred scroll rendering is annoying.
-
D12.3- [PAClient Error] Error: E6665 Cannot open file ".../partial_info.plist". No such file or directory
Patrick PREMARTIN replied to ToddFrankson's topic in Cross-platform
I had the same error ("can't open partial info.plist") yesterday but didn't investigate. Good to know that adding the framework fixed that too. 😉 -
I just tried with the external formatter and while it kept a breakpoint (one line off because of changes in the code that changed where the line was), all the bookmarks were removed.
-
win32 exe compiled in Delphi11 does not run on W2000
Remy Lebeau replied to rudy999's topic in Windows API
One of the new features in Delphi 13 is support for UI Automation in the VCL. The UIA framework was introduced in Windows 7. Embarcadero dropped suppprt for XP awhile ago, and Win2K is even older than XP. -
GExperts tries very hard, but is not perfect. The same for Breakpoints. I updated that code "recently" (a year ago?) so it became a lot better, but still not perfect.
-
ai coding MCP server to catch windows debug messages
Lars Fosdal replied to Javier Tarí's topic in General Help
I understand that. My point was that OutputDebugString can fail on the windows side, so that the content does not always reach the listeners. YMMV.- 7 replies
-
- ai
- claude code
-
(and 2 more)
Tagged with:
-
D12.3- [PAClient Error] Error: E6665 Cannot open file ".../partial_info.plist". No such file or directory
ToddFrankson replied to ToddFrankson's topic in Cross-platform
Well it seems XCode upgraded- This was my fix "Adding the _LocationEssentials framework to iOS 26 and iOS Simulator 26 SDK fixed the problem and I was able to compile my test projects with Delphi 12 Athens and Delphi 13 Florence. https://developpeur-pascal.fr/ios-26-reclame-le-framework-_locationessentials.html" -
ai coding MCP server to catch windows debug messages
Javier Tarí replied to Javier Tarí's topic in General Help
I'm not sure if I will use it, but would be glad to have it and check/adapt to D12/13 Right now the AI agent compiles with the CLI compiler, so it gets back all the compiler messages; but I'm considering interaction with the IDE, which would mean compiling from it- 7 replies
-
- ai
- claude code
-
(and 2 more)
Tagged with:
-
ai coding MCP server to catch windows debug messages
Javier Tarí replied to Javier Tarí's topic in General Help
Sure, but here I'm not using OutputDebugString as a log, but as a real time information tool: the difference is the usage with the AI; the AI can read it while the program is running, not at a later time. I will add some easy to implement additional features that will allow the agent to do a much better and faster debugging- 7 replies
-
- ai
- claude code
-
(and 2 more)
Tagged with:
-
ai coding MCP server to catch windows debug messages
Javier Tarí replied to Javier Tarí's topic in General Help
Here it is; I used the GTK repo for the MCP server itself. You and anyone can use my code in any way without need to give me anything; not a link, not nothing. JavierusTk/MCPServer- 7 replies
-
- ai
- claude code
-
(and 2 more)
Tagged with:
-
It is just an assumption on my part. I just checked with some searches, and it seems that there is more to bookmarks and how the IDE handles them than I thought. And they should be preserved through automated code formatting when used inside the IDE. The will break or get lost though, if a pas file is formatted outside the IDE.
-
tidtcpserver read (peek) without removing from buffer.
FearDC replied to alnickels's topic in Network, Cloud and Web
For those who are still or will get interested in future. Got into same situation using Indy, and here is the hack: uses {$IFDEF POSIX} Posix.SysSocket, {$ELSE} WinAPI.WinSock, {$ENDIF} {$IFDEF POSIX} type TTimeVal = record tv_sec, tv_usec: LongInt; end; {$ENDIF} var LPeek: Array [0..1] of Byte; // required peek length {$IFDEF POSIX} LTime: TTimeVal; {$ELSE} LTime: DWord; {$ENDIF} begin // set one second timeout since indy sockets are blocking {$IFDEF POSIX} LTime.tv_sec := 1; LTime.tv_usec := 0; Posix.SysSocket.SetSockOpt(AContext.Binding.Handle, Posix.SysSocket.SOL_SOCKET, Posix.SysSocket.SO_RCVTIMEO, <ime, SizeOf(LTime)); {$ELSE} LTime := 1 * 1000; WinAPI.WinSock.SetSockOpt(AContext.Binding.Handle, WinAPI.WinSock.SOL_SOCKET, WinAPI.WinSock.SO_RCVTIMEO, PAnsiChar(@LTime), SizeOf(LTime)); {$ENDIF} if {$IFDEF POSIX} (Posix.SysSocket.Recv(AContext.Binding.Handle, LPeek, 2, Posix.SysSocket.MSG_PEEK) = 2) {$ELSE} (WinAPI.WinSock.Recv(AContext.Binding.Handle, LPeek, 2, WinAPI.WinSock.MSG_PEEK) = 2) {$ENDIF} and (LPeek[0] = 22) and (LPeek[1] = 03) then // in my situation: tls magic bytes TIdSSLIOHandlerSocketOpenSSL(AContext.Connection.IOHandler).PassThrough := False; // reset socket timeout {$IFDEF POSIX} LTime.tv_sec := 0; LTime.tv_usec := 0; Posix.SysSocket.SetSockOpt(AContext.Binding.Handle, Posix.SysSocket.SOL_SOCKET, Posix.SysSocket.SO_RCVTIMEO, <ime, SizeOf(LTime)); {$ELSE} LTime := 0; WinAPI.WinSock.SetSockOpt(AContext.Binding.Handle, WinAPI.WinSock.SOL_SOCKET, WinAPI.WinSock.SO_RCVTIMEO, PAnsiChar(@LTime), SizeOf(LTime)); {$ENDIF} end; 😃 -
daniyal joined the community
-
I am not following closely the CE since I get my Delphi licence at work. A google search returned that in case of Delphi 11 the paid version was released on September 9, 2021, the CE was released on April 26, 2023.
-
Delphi 13 FMX applications not responding to mouse clicks on Win10 multimonitor
Lachlan Gemmell posted a topic in FMX
I have a pretty unique multimonitor screen arrangement on my dev system and FMX applications compiled with Delphi 13 don't respond to mouse movements or clicks if the window is in the top third of monitor 3 (which is my primary monitor). Specifically the client area of the FMX window doesn't respond to mouse movements or clicks while it is within that region. The non-client area responds fine allowing you to move, maximise, close the window as you would normally. Interestingly the Delphi 13 IDE FMX designer suffers the same problem if I place it on monitor 3. Anything in the top third of that monitor I cannot select. I've verified it using both my application and the standard demo found at Samples\Object Pascal\Multi-Device Samples\User Interface\ControlsDesktop\ControlsDemo.dproj If I compile my FMX app or that FMX demo using Delphi 12.3 it works on every monitor no problem. VCL applications also don't have any issue either. I'm guessing for most people you won't have an issue but if there's anyone else out there with a wacky screen arrangement you may be seeing something similar. If you are please post your multimonitor arrangement here. It would be nice to be able to report the issue with a simpler multimonitor arrangement than mine to increase the chances of Embarcadero being able to reproduce the issue. -
So all of them useless.