Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation since 06/19/25 in Posts

  1. There are many components/libraries available for running processes and capturing their output. But, I got frustrated with their design and functionality, mostly for the following reasons: Fixation with and premature conversion to strings. Processes produce and consume bytes. Blocking reading of process output, resulting to inefficiencies (tight loops with Sleep, or separate threads for reading the output or providing input to the process) Incomplete features and/or over-bloated So, I have made my own pascal-process single unit library. Main features: Asynchronous reading of process output Separate stdout and stderr reading which can optionally be merged Ability to consume output as it is produced or else let it accumulate and read the final result Ability to provide input to the running process before or while the process is running. Ability to terminate the running process. Synchronous and asynchronous execution of processes. Interfaced-based facilitating memory management. MIT licence Usage: You do not need to install the library. Just download or clone the repo and add the source subdirectory to the Library path. Then add PascalProcess to your uses clause. If you just want to get the output of a process you can use the class functions of TPProcess. TPProcess = class(TInterfacedObject, IPProcess) class function Execute(const ACommandLine: string; const ACurrentDir: string = ''): TBytes; overload; class procedure Execute(const ACommandLine: string; const ACurrentDir: string; out Output, ErrOutput: TBytes) overload; end; This is an example: var Output: TBytes; begin Output := TPProcess.Execute('cmd /c echo Hi'); Writeln(TEncoding.ANSI.GetString(Output)); end; For more demanding cases you can use the IPProcess interface. Example: type TUtils = class class procedure OnRead(Sender: TObject; const Bytes: TBytes); end; class procedure TUtils.OnRead(Sender: TObject; const Bytes: TBytes); begin Writeln(TEncoding.ANSI.GetString(Bytes)); end; procedure Test2; // Processes ouput as it gets produced // The main thread terminates the process var Process: IPProcess; begin Process := TPProcess.Create('cmd /c dir c:\ /s'); Process.OnRead := TUtils.OnRead; WriteLn('Press Enter to start the process. Press Enter again to terminate'); ReadLn; Process.Execute; ReadLn; Process.Terminate; end; See here the definition of IPProcess. Limitations: Currently the library is Windows only. The intention is to support other platforms (help wanted).
  2. How upgrading from Delphi 7 to Delphi 12 eliminated 15 monthly support tickets and unlocked Linux deployment In May 2024, we were contacted by a European leader in natural gas measurement systems. Their software was partly built in Delphi 7 and partly in C#. It had become difficult to maintain. The company wanted to migrate to Delphi 12, modernize the UI, and enable Linux deployment, without breaking existing functionality. Our team faced and handled the following challenges: The project relied on Delphi 7. That version lacked full Unicode support. The framework used ANSI strings by default, and this created critical limitations for modern global applications. The legacy app only ran on 32-bit Windows, using outdated Win32 APIs and hardcoded paths (C:\Data\). This prevented deployment on Linux cloud servers (AWS/Ubuntu). The app was built on obsolete BDE components and unsupported libraries. Here's what we did: ✅ Migrated from Delphi 7 to Delphi 12 ✅ Replaced BDE and Indy 9 with FireDAC and Indy 10 ✅ Refactored code for cross-platform compatibility ✅ Delivered a modernized UI with preserved workflow familiarity We achieved: - 15 support tickets per month were reduced to zero - Windows-only application is now cross-platform - Overall, the application is more prepared for future challenges A few months later, the client returned for an estimate to migrate other Delphi projects to a web-based platform. If you want to see the full story, with the challenges and solutions broken down, follow the link https://www.softacom.com/cases/modernizing-industrial-software-with-delphi-12/
  3. TOML is a "config file format for humans", that has gained a lot of traction in the python and rust communities among others. It is basically the INI file format on steroids. It compares quite well to alternative formats such as JSON, YAML and XML. Compared to JSON is way more readable and compact. Since I could not find any Delphi library for processing TOML, I have created my own: toml-delphi. Features: TOML v1.0.0 compliant. Passes all 734 (valid/invalid) official validation tests. Fast. Single stream tokenizer and lexer that doesn't use regex. Converts TOML documents to Delphi's RTL's TJSONObject, thus allowing for easy traversal, manipulation and query of the generated documents. Includes TTOMLWriter for converting TJSONObjects back to TOML. Provides for easy (de)serialization of Delphi objects and records from/to TOML. This is the interface of the main unit: TJSONObjectHelper = class helper for TJSONObject function ToTOML(MultilineStrings: Boolean = False; Indent: Integer = 4): string; procedure StreamTOML(Stream: TStream; MultilineStrings: Boolean = False; Indent: Integer = 4); procedure SaveTOMLtoFile(const FileName: string; MultilineStrings: Boolean = False; Indent: Integer = 4); class function FromTOML(const Contents: string): TJSONObject; overload; class function FromTOML(Contents: TBytes): TJSONObject; overload; class function FromTOML(Stream: TStream): TJSONObject; overload; class function FromTOMLFile(const FileName: string): TJSONObject; end; ETOMLSerializer = class(Exception); TTOMLSerializer = class class function Serialize<T>(const AValue: T): string; overload; class function Deserialize<T>(const ATOML: string): T; overload; end; Example usage: You can convert TOML source to TJSONObject using one of the FromTOML functions. For example to parse a TOML file you use: var JsonObject := TJSONObject.FromTOMLFile(FileName); //or for parsing a TOML string: var JsonObject := TJSONObject.FromTOML(TOMLstring); To convert a TJSONObject to TOML you use one of the methods ToTOML, StreamTOML or SaveTOMLToFile. For example: TOMLString := JsonObject.ToTOML; // or JsonObject.SaveTOMLToFile(FileName); Example serialization: type TTestRec = record IntValue: Integer; FloatValue: double; StringValue: string; DateValue: TDateTime; ArrayValue: TArray<string>; end; procedure TestSerializer; var Rec: TTestRec; TOMLString: string; begin Rec.IntValue := 123; Rec.FloatValue := 3.14; Rec.StringValue := 'abc'; Rec.DateValue := Now; Rec.ArrayValue := ['A', 'B', 'C']; Writeln('Serialized record:'); WriteLn('=================='); TOMLString := TTOMLSerializer.Serialize(Rec); Writeln(TOMLString); Writeln('Record deserialized and serialized again:'); Writeln('========================================='); Rec := TTOMLSerializer.Deserialize<TTestRec>(TOMLString); TOMLString := TTOMLSerializer.Serialize(Rec); Writeln(TOMLString); end; Output: Serialized record: ================== IntValue = 123 FloatValue = 3.14 StringValue = "abc" DateValue = "2025-06-18T05:37:02.110+03:00" ArrayValue = [ "A", "B", "C" ] Record deserialized and serialized again: ========================================= IntValue = 123 FloatValue = 3.14 StringValue = "abc" DateValue = "2025-06-18T05:37:02.110+03:00" ArrayValue = [ "A", "B", "C" ] I hope you find it useful.
  4. pyscripter

    TOML delphi parser, writer and serializer

    @dummzeuch With the permission of the original author the license has now been changed to the MIT one.
  5. Hi everyone, I wanted to share the main updates in version 1.1.0 of DelphiGenAI (OpenAI wrapper for Delphi) here—mainly to offer what I can to the community, and maybe get some feedback if anyone feels like weighing in on my approach. Main Updates Compatibility with the Latest OpenAI Features (including Remote MCP & Code interpreter) Ready-to-Use Templates Two archives (TestGenAI_VCL.zip and TestGenAI_FMX.zip) let you copy and paste any snippet from the documentation and test it out, with no complicated setup. Variety of Code Snippets For each feature: synchronous, asynchronous (event/callback), and asynchronous with async/await. The idea is to allow everyone to compare the approaches and pick the one that fits them best. Documentation That’s Directly Usable All markdown examples can be tested as-is within the supplied templates. A Gradual Learning Path The aim: make it easier to learn about AI in Delphi, whatever your starting level, and to keep things as accessible as possible. About This Approach I’m not an experienced “Delphi old-timer” and I don’t know the community very well yet; that’s why I chose to offer several approaches (synchronous, asynchronous, and async/await) for each example. But maybe that’s not really necessary—maybe some would prefer strictly asynchronous, or even just synchronous? I’d be interested in your thoughts or experiences on this (no pressure—just curious, and trying to do what's most helpful). Also Tried on Other Wrappers I’ve used the same principle in a Delphi wrapper for Deepseek. Depending on the feedback I get here, I’ll decide whether to take this approach with a few other wrappers I’ve put up on Github. Thanks in advance for reading, and best wishes to all.
  6. msohn

    Delphi 13 beta

    Are you kidding me? You, Sir, are a TeamB legend and as such I would have assumed you're an MVP now, with - AFAIK - much earlier access to the betas. Heck, I learned a ton from all of your posts going all the way back to when we were still hanging out on nntp://borland.* with the likes of Neil J. Rubenking and the other TeamB members (or maybe even earlier back, then CompuServe was a thing, but I'm not sure whether my memory serves me right on this one). I sincerely hope you're able to enjoy your time as a pensioner now. You've been an inspiration to me in more than just one way. So thank you a lot. FWIW I didn't receive a beta invite as a regular subscription user, but I'm actually not surprised by that - I mean how is Calvin Tang going to handle beta invitation requests if everyone with an active subscription is invited?
  7. Renate Schaaf

    Bitmaps to Video for Mediafoundation

    I've just uploaded an update to my project https://github.com/rmesch/Bitmaps2Video-for-Media-Foundation What it does: Contains a VCL-class which encodes a series of bitmaps and video-clips together with an audio-file to video. The result is an .mp4-file with H264 or H265 compression together with AAC-audio. It uses windows mediafoundation, which is usually contained in windows. Hardware-encoding is supported, if your graphics-card can do it. Requires: Headers for mediafoundation from FactoryXCode: https://github.com/FactoryXCode/MfPack Windows 10 or higher Encoder (MF-Transform) for H264/H265, usually come with the graphics-driver Delphi XE7 or higher, if I haven't messed it up again, I've only got the CE and Delphi2006 (Win32 and Win64 should be working, but Win64 recently crashes for me with "The session was disconnected".) The demo-project shows some uses: Record a series of canvas-drawings to video Make a slideshow from image-files (.bmp,.jpg,.png,.gif) with music (.wav, .mp3, .wmv, ...) and 2 kinds of transitions Insert a videoclip into a slideshow (anything that windows can decode should work) Transcode a video-file including the first audio-stream. Improvements: I think I now better understand how to feed frames to the encoder. With the right settings it makes stutter-free videos with good audio-video-synchronization. It's now usable for me in my "big" project, and I no longer need to rely on ffmpeg - dlls. More info in changes.txt. Just try it, if you're interested, I'd be glad. Renate
  8. Small example to access Github's contributions of a given user and display them using TeeChart. https://github.com/Steema/TeeChart-VCL-GitHub-Contributions This demo is made with VCL but almost identical code works in Firemonkey.
  9. Cristian Peța

    Extreme slow-down in Windows FMX app UI since upgrading to 12.1

    I updated the report https://embt.atlassian.net/servicedesk/customer/portal/1/RSS-3711
  10. Anders Melander

    What .PAS file does a form use?

    I'm working on a project like that; New units are named consistently after strict rules so we can easily locate the relevant unit. Old units are named after whatever the developer had time to type (and apparently he was always in a rush). So I introduced a "magic" key that when pressed at run-time displays the name of the active form/frame. It's basically just a TApplicationEvents.OnShortCut on the main form: procedure TFormAnynymizedToProtectTheGuilty.ApplicationEventsShortCut(var Message: TWMKey; var Handled: Boolean); begin {$ifdef DEBUG} if (Menus.ShortCutFromMessage(Message) = ShortCut(VK_F1, [ssAlt])) then begin if (Screen.ActiveCustomForm <> nil) then begin var Msg := ''; // Find frames in the form var Control := Screen.ActiveControl; while (Control <> nil) and (Control <> Screen.ActiveCustomForm) do begin if (Control is TFrame) then Msg := Msg + Format('Embedded frame: %s in %s.pas', [Control.ClassName, Control.UnitName]) + #13 else if (Control is TForm) then Msg := Msg + Format('Embedded form: %s in %s.pas', [Control.ClassName, Control.UnitName]) + #13; Control := Control.Parent; end; Msg := Msg + Format('Active form: %s in %s.pas', [Screen.ActiveCustomForm.ClassName, Screen.ActiveCustomForm.UnitName]); TaskMessageDlg('YOU ARE IN A MAZE OF TWISTY LITTLE PASSAGES, ALL ALIKE.', Msg, mtInformation, [mbOK], 0); end; Handled := True; end; {$endif DEBUG} end;
  11. Attila Kovacs

    Anyone using Clever Components?

    Of course.
  12. Dave Nottage

    Delphi 13 beta

    Part of the NDA you agreed to when you signed up was to not publicly mention that you are participating in the beta, nor any details about it, so you have already broken your NDA.
  13. rvk

    RichEdit with MSSQL

    RTF Roulette: The Hidden Dangers of Storing Rich Text in VARCHAR Fields
  14. Anders Melander

    Bitmaps to Video for Mediafoundation

    "Not thread-safe" in this case doesn't mean crash and burn. It just means that if one thread modifies the global FormatSettings then it will affect all other threads also using it. Hardly a problem - even if you did output floating point values in the exception message.
  15. Tom Chamberlain

    RichEdit with MSSQL

    I use a TRichViewEdit which has other methods but this should work for a regular TRichEdit as well, do not treat it like a string stream, it's a blob stream. To save the RichEdit var BlobStream: TFDBlobStream; ... ... dbQuery = Select statement for the record that you want to update/create ... dbQuery.Open; try ... ... dbQuery.Append; if you are creating a new record ... ... dbQuery.Edit; if you are editing one ... BlobStream := TFDBlobStream.Create(dbQuery.FieldByName('BlobFieldName') as TBlobField, bmWrite); try YourRichEdit.Lines.SaveToStream(BlobStream); finally BlobStream.Free; end; dbQuery.Post; except on e: exception do MessageDlg(e.Message, mtError, [mbOK], 0); end; dbQuery.Close; To load the RichEdit var BlobStream: TFDBlobStream; ... ... dbQuery = Select statement for the record that you want to read/load ... dbQuery.Open; BlobStream := TFDBlobStream.Create(dbQuery.FieldByName('BlobFieldName') as TBlobField, bmRead); try if not dbQuery.FieldByName('BlobFieldName').IsNull then begin YourRichEdit.Lines.LoadFromStream(BlobStream) ... ... Not sure if there is anything RichEdit needs to update/format the display ... end; finally BlobStream.Free; end; dbQuery.Close;
  16. Patrick PREMARTIN

    Extreme slow-down in Windows FMX app UI since upgrading to 12.1

    Thanks @Cristian Peța I've updated my sample project on https://embt.atlassian.net/servicedesk/customer/portal/1/RSS-3711 Hope they found a way to optimize this for 13.
  17. Remy Lebeau

    TLS Issues and TLS3 message comming from Iindy

    No, it does not support OpenSSL 3.x or TLS 1.3 at this time. But, you can use a 3rd party SSLIOHandler that does, such as TaurusTLS (https://github.com/JPeterMugaas/taurustls). Security requirements change all the time. They have to update their systems every so often to keep up. There is much more to HTTP/S than just URLs. Yes. Yes, it does, at least on the client side, and has for 8 years now.
  18. pyscripter

    Python Output

    For now, there are very serious limitations you need to consider when using emNewInterpreterOwnGIL to achieve true parallelism. See for instance the limitations in What’s new in Python 3.14 — Python 3.14.0b3 documentation. Even the innocent looking print command is not thread-safe. And almost nothing can be share between the interpreters. Also there are limitations about what you can import, and P4D modules are not yet considered safe for use with emNewInterpreterOwnGIL. This is changing with the forthcoming python 3.14. It will include a new module concurrent.interpreters that exposes the interpreters with their own GIL to pure python code. There will also be an addition of ways to communicate between the interpreters using queues. See PEP 734. So for example you could store your output to such a queue and print it when everything is finished. But all the above is cutting edge and unless you really need it you should avoid it, If you decide to use it then make sure you fully understand the limitations and implications. I will try to make P4D modules compatible with emNewInterpreterOwnGIL and that would at least give you the option to say add output to a Delphi string list (or something similar) protected with a global lock on the Delphi side. Note that all the above are not related to the free-threading version of Python, which in itself is another story altogether.
  19. Patrick PREMARTIN

    Extreme slow-down in Windows FMX app UI since upgrading to 12.1

    I open the issue https://embt.atlassian.net/servicedesk/customer/portal/1/RSS-3711 You can follow it by enabling the notifications after login on this URL (quality.embarcadero.com). The difference between TThread.Queue() and TThread.ForceQueue() happens in the main thread : in the first case the code is executed, in the second it's delayed to next message processing iteration. Unfortunately, the behavior is not the same on Mac and Windows and in this project the form is only refreshed on macOS, for Windows it's done at the end.
  20. dummzeuch

    Define conditional symbol in .dpr

    You cannot define a symbol in the .dpr file to be available in the units (it will be available in the .dpr file itself though). You must put it into the .dproj file (Project -> Options). Alternatively you can define it in an include file and include that file in all units that require the symbol. That latter approach is used by most libraries because a library cannot add anything to the project options.
  21. himitsu

    Bugs on WINMD, who can clarify ?

    Source: https://embt.atlassian.net/servicedesk/customer/portal/1/RSS-1577 https://quality.embarcadero.com/browse/RSP-44096 https://embt.atlassian.net/servicedesk/customer/portal/1/RSS-1754 https://www.delphipraxis.net/214473-warnung-vor-winmd.html ......................
  22. Vincent Parrett

    Intercepting UuidCreate function

    Intercepting functions for unit testing is a terrible idea. A better option would be to create abstractions and a concrete implementation (ie actually calls UuidCreate), that abstraction can be easily mocked using Delphi Mocks or Spring4D for uinit tests. The same applies to code that relies on things like Now or NowUTC - e.g - https://github.com/VSoftTechnologies/VSoft.System.TimeProvider
  23. Kas Ob.

    Bitmaps to Video for Mediafoundation

    I didn't contribute anything, and very much thank you for offering, but don't worry about this. One more thing, about the whole duration thing, but to explain i want to go back in time to many decades back, when the standard of highest audio quality chose 44100hz as CD quality and best quality, this is strange number at first, when you know how they came up with it, things get clearer, read this https://en.wikipedia.org/wiki/44,100_Hz#Recording_on_video_equipment So, to interleave the audio and video because things was very different back then and storing or buffering the audio was very expensive and complicated using simple circuits available back then, they needed a number to make sure to divide and support 50fps and 60fps with 3 sample per line, so they can interleave the samples with the lines data for video. Fast forward decades later, and we don't have the only PAL and NTSC system, we have so many combination of FPS with sizes, but still most used standard fps are 23.976 and 29.97 (among less used 24, 25, 29.97, 30, 50, 60..), strange ? that is question have to do with old systems, the internet have so many resources answering this question, yet web broadcasting and multiplexing streams changed things a lot, so we can't depend on these only, while most likely you don't see 44100 like it was back then. Anyway, in the past they changed the audio duration based on video to be compliant, but for modern times and better sample rate which at least 48k, also technology that allow or relief the need to output directly, but use the buffer ahead, the whole thing still need syncing, and to make sure the audio-video are synced then they should follow a rule, the audio should be aligned into sample per second and the video should should accommodate this unlike what was happening in the past, So even the video duration should be multiple of audio sample duration, consider this if you need your encoding %100 synced or the best it can be, in other word correct the video duration too, while audio sample rate is high number you have more flexible fps per second, the difference could be between 40 and 40.00002, yet if your video is 40.00002 i never saw i player show it as 40.00002 but always 40, this difference will prevent desyncing. Hope that was clear and thank you again for the work on this and for the offering,
  24. Tommi Prami

    Running tests in Parallel (or sub test in side one test)

    Yellow, again... Did Quick tests with PPL, seems that tested code it self did not work wery well when runniing in parallel. Do'h Heve to to think of this later... Code should be about thread safe, but did not cope, or at least I did not saw anything that was obviously not thhread safee and protected few spots with Critical section. -Tee-
×