Leaderboard
Popular Content
Showing content with the highest reputation on 06/18/25 in Posts
-
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.
-
Using search, search all files in the project for the reporter component name and the unusual file name will be it.
-
Error when installing custom package - Module not found
GabrielMoraru replied to JKNew's topic in Delphi IDE and APIs
@Pat Heuvel- Thanks. I tried the (relatively) new version from github and it works! -
Retrieving outlook contact emails
Die Holländer replied to Connie McBride's topic in Algorithms, Data Structures and Class Design
I found some old code to retrieve the list of a group, like "Global Address List" The code here is based on to put the addresses in a TreeView. I checked the code and it is still running OK but I noticed that I don't see the e-mail addresses anymore but instead it reports a string like: "/o=ExchangeLabs/ou=....." Maybe this is because of the exchange server configuration in my environment. see: how-to-get-email-address-from-o-exchangelabs-ou-exchange-administrative-group You have to play with it to see if you get the proper info you want. Maybe you can post the final answer here if you find the proper addresses.. Note that the code has a filter to only show two groups: If (CurGroupName='All Groups') or (CurGroupName='Global Address List') Then... //Uses Outlook2000; Procedure TMailTrans.CreateGALTreeForSendMailItem(aTreeView : TTreeView); Var pProp : PSPropValue; MP : IMAPIProp; strAddress : String; i, j, Check: Integer; myAddressList: AddressList; myAddressLists: AddressLists; myAddressEntries: AddressEntries; myAddressEntry: AddressEntry; CurNode, ChildNode, DetailNode :TTreeNode; CurGroupName : String; begin If NmSpace=NIL Then Begin OutlookApplication1.Connect; NmSpace:=OutlookApplication1.GetNamespace('MAPI'); NmSpace.Logon('', '', False, False); End; myAddressLists := IUnknown(NmSpace.AddressLists) as AddressLists; aTreeView.Items.BeginUpdate; aTreeView.Items.Clear; for i := 1 to myAddressLists.Count do begin CurGroupName:=myAddressLists.Item(i).Name; If (CurGroupName='All Groups') or (CurGroupName='Global Address List') Then Begin CurNode:=aTreeView.Items.Add(Nil,myAddressLists.Item(i).Name); CurNode.ImageIndex:=2; CurNode.SelectedIndex:=2; myAddressList := myAddressLists.Item(i); if Assigned(myAddressList.AddressEntries) then Begin myAddressEntries := myAddressList.AddressEntries; for j := 1 to myAddressEntries.Count do begin strAddress:='Unknown'; myAddressEntry := myAddressEntries.Item(j); if Assigned(myAddressEntry) then Begin if myAddressEntry.MAPIOBJECT<>NIL then Begin if Assigned(myAddressEntry.MAPIOBJECT) then Begin { Check:=IUnknown(myAddressEntry.MAPIOBJECT).QueryInterface(IMailUser,MP); If Check=0 then MP:=IUnknown(myAddressEntry.MAPIOBJECT) as IMailUser else MP:= IUnknown(myAddressEntry.MAPIOBJECT) as IDistList; if S_OK = HrGetOneProp(MP, $39FE001E, pProp) then begin strAddress:=String(pProp.Value.lpszA); MAPIFreeBuffer(pProp); end; // else strAddress:=myAddressEntry.Address; } strAddress:=myAddressEntry.Address; ChildNode:=aTreeView.Items.AddChild( CurNode, myAddressEntry.Name); ChildNode.ImageIndex:=7; ChildNode.SelectedIndex:=7; DetailNode:=aTreeView.Items.AddChild( ChildNode, strAddress); DetailNode.ImageIndex:=6; DetailNode.SelectedIndex:=6; End; End; { DetailNode:=aTreeView.Items.AddChild( ChildNode, myAddressEntry.Address); DetailNode.ImageIndex:=6; DetailNode.SelectedIndex:=6; } End; End; End; end; //Application.Processmessages; end; aTreeView.Items.EndUpdate; end; -
My only problem with that is the license: GPL simply makes it useless for me. But since it's based on another GPL library you probably didn't have a choice.
-
Prg execution time problem in Delphi11.2 IDE and command line of a DLL function
Kas Ob. replied to lucarnet's topic in Delphi IDE and APIs
Spent more than 4 hours on this, not because i already witnessed this many times, but just i wanted to refresh my frustration with this pile of sh** called Delphi 64bit debugger, Here i want to make few things clear 1) The Delphi debugger 32bit and 64bit does have parts are the least can be called masterpiece, so it is not useless in whole, but the smart people worked on it, either left and the debugger stuck with different people, who have least knowledge about the existing code should be or those who wrote that beautiful debugger loop, have no idea on what to do as next step. 2) I have XE8 so it might be different from modern IDEs, as Embarcadero in the last decade have the phrase "lets make Delphi great again" rephrased a little, and from readin they are focusing on LSP and making it great again, good luck with that ! considering they are just adding process and memory allocation, it is the exact thing that will be impossible to squeeze performance from, on the contrary it will be worse with every step in that direction. Now back to the subject, and most likely i will rant again about the debugger, @lucarnet you said it takes 2.5 minutes under debugging while it takes 1-2 seconds without a debugger, my CPU is Sandy Bridge i5-2500 from more that decade and half, the these times is strangely close, yes it takes between 2.5-5 minutes and i am talking about just loading the model, not even loading the recognizer. Out of intrigue i looked at this VOSK library and using their documentation i download the binaries with pyhon pip, so far so good, browsed the demos and liked this one https://github.com/alphacep/vosk-api/blob/master/c/test_vosk.c so translated the needed headers, and easier than that there is none const VOSK_LIBNAME = 'libvosk.dll'; type PVoskModel = Pointer; PVoskRecognizer = Pointer; function vosk_model_new(const model_path: PAnsiChar): PVoskModel; external VOSK_LIBNAME name 'vosk_model_new'; procedure vosk_model_free(model: PVoskModel); external VOSK_LIBNAME name 'vosk_model_free'; function vosk_recognizer_new(model: PVoskModel; sample_rate: Double): PVoskRecognizer; external VOSK_LIBNAME name 'vosk_recognizer_new'; procedure vosk_recognizer_free(rec: PVoskRecognizer); external VOSK_LIBNAME name 'vosk_recognizer_free'; function vosk_recognizer_accept_waveform(rec: PVoskRecognizer; const data: Pointer; len: Integer): Integer; external VOSK_LIBNAME name 'vosk_recognizer_accept_waveform'; function vosk_recognizer_result(rec: PVoskRecognizer): PAnsiChar; external VOSK_LIBNAME name 'vosk_recognizer_result'; function vosk_recognizer_partial_result(rec: PVoskRecognizer): PAnsiChar; external VOSK_LIBNAME name 'vosk_recognizer_partial_result'; function vosk_recognizer_final_result(rec: PVoskRecognizer): PAnsiChar; external VOSK_LIBNAME name 'vosk_recognizer_final_result'; great, now i need a model and wave file, so https://alphacephei.com/vosk/models and grabbed the first and smallest model 40mb from https://github.com/alphacep/vosk-api/tree/master/python/example grabbed the wave file 256kb so far so good build i the same demo and low and behold modelPath := 'vosk-model-small-en-us'; model := vosk_model_new(PAnsiChar(modelPath)); if model = nil then begin Log('Error loadin model'); Exit; end; This model loading takes minutes under debugger while takes something less then 3 minutes a little, and without the debugger it literally takes 400ms (milliseconds) it is 0.4 second ! So i am confirming your problem with debugger, later on this will write something. Now to your other problem, loading the model and recognizer doesn't even create a single background thread, as vosk_recognizer_accept_waveform kept failing and hugging the CPU, i couldn't make it work, but also didn't create threads ! So the threads in the log of yours is coming from your own miss using something somewhere, may be in handling wave file or microphone, fix these as these threads will only make the debugger even slower. Also the demo is somehow wrong in assuming and feeding 3200 bytes and didn't read the header right way to check for sample rate and channels every thing else, but it should work i guess, yet it didn't work on my device. Recommendation, Delphi debugger is useless and i am talking specifically about 64bit, it is wrong and doing wrong on so many levels 1) The demo and this library do allocate 4-5 chunks of memory each are 128mb, and will add more chunks for the recognizer and will increase but there is no memory leak, just huge amount of memory is needed, and it is expected. 2) The debugger utilize for unknown reason, well may be there was valid reasons 20 years ago, to have two processes to perform the debugging, but i can't justify having a sentinel process calling DebugBreak, WHY ? who knows. 3) Now comes the fun part, the debugger must be 64bit while the IDE 32bit so an IPC is due, great, so lets take one and never look back, so they choose TCP, TCP (WTF), even on loopback it is TCP packets, no shared memory ?! no no shared memory ! 4) Now the debugger perform ReadProcessMemory as like every debugger out there, but wait we mist do it differently, see since the dawn of computers half century ago there was pages and they are 4kb and on Windows an address is valid if the page is valid, so lets perform the reading on 512byte ! 5) 512bytes is somehow still better than 1 byte, so lets perform reading on 1 byte, we must not gave up, and in case we wrote the breakpoint by using WriteProcessMemory at single byte which is fine and justified, lets do all the breaks points to make sure and even the API is success, success means it does wrote the memory, we must be sure and read them all again , !! 6) OK we have the memory read in small chunks we need to ship them to the IDE and the IDE debugger, lets send them in 1,8,12,16 bytes, genius !, so hundred of thousands of send over TCP in the smallest way possible, notice TCP require ACK, so switching to UDP will enhance the throughput, we are against that, and still no shared memory ! 7) how to handle sockets in Turbo Pascal way over dialup modem, every IOCTLSocket (the successful ones) should be followed be WSAGetLastError for no freaking reason, and lets mix Select with WSAAsyncSelect to create an abomination, just to make sure, while the IDE and its UI will block for every packet, so the IDE should freeze showing it is busy, great ideas and great design. .. So many things to be angry about, as i can't be unbiased here, but the IPC between IDE and real debugging process is wrong and outdated, it can work and debug a 10 lines project, not a real life semi-heavy application. Now i am angry 😪 @lucarnet there is no way to debug such heavy memory usage application using very, yes very outdated debugger, the Delphi debugger, you should fix the threads creation as i mentioned above, as it is has nothing to do with VOSK library, and skip debugging on Delphi, use logging instead, i am guessing here, those thread are coming form your different library you are using to handle microphone or wave file reading. And good luck ! Ps: looking at the assembly generated for 64bit it is a sight to see NOP there between the instruction serving literally nothing, and even one of them was ducking up the alignment in the freaking loop, wow just wow. -
TECNativeMap is a 100% Delphi mapping component that uses neither browser nor javascript, and is available on all Delphi-supported platforms. Compatible since Delphi 7 for VCL and XE3 for Firemonkey. Download the trial version for Delphi 12
-
You can try running Delphi in DPI-unaware mode. It's blurry, but from what I've tested, it's the least problematic.
-
No library developer would test things like this. I mean why stop at FMX/VCL? What about database frameworks. Does it have dependencies on any of them? Does it work in a Windows service? Should there be a test for that? It's simple to see by inspecting the uses clause, so the developer just does not need to do any of that.
-
About the compiler (not) finding the DFM files
Uwe Raabe replied to GabrielMoraru's topic in Delphi IDE and APIs
Not quite, that setting is stored as BRCC_IncludePath. DCC_ResourcePath is indeed the correct way to provide the paths to look for the DFM resources. Unfortunately there is no UI to edit that. Manually editing the dproj file adding a node like <DCC_ResourcePath>..\lib\Source;$(DCC_ResourcePath)</DCC_ResourcePath> under the appropriate PropertyGroup will make the DFM files located in ..\lib\source to be found without exposing the PAS files in that folder.- 16 replies
-
Virtual class methods and properties
Stefan Glienke replied to pyscripter's topic in RTL and Delphi Object Pascal
It appears that Marco lacks the technical understanding to evaluate this issue. I left a comment. -
How do I close a modal form without ModalResult being set to mrCancel ?
Brandon Staggs replied to dormky's topic in VCL
You keep demonstrating for us that you do not even understand the API. Your original question would have been answered by just looking at the documentation for ShowModal, or by examining the source code to see how the modal loop is implemented. You wouldn't bother to do that, and you feel qualified to make pronouncements on the overall design quality. Maybe let it go. -
How do I close a modal form without ModalResult being set to mrCancel ?
Anders Melander replied to dormky's topic in VCL
Huh? var Msg: TMsg; while (PeekMessage(Msg, 0, WM_SETCURSOR, WM_SETCURSOR, PM_REMOVE)) do begin if (Msg.message = WM_QUIT) then begin PostQuitMessage(Msg.wParam); exit; end; DispatchMessage(Msg); end; -
ANN: StyleControls VCL v. 5.76 + new demo with Lottie Animations just released!
Almediadev Support replied to Almediadev Support's topic in Delphi Third-Party
To improve rendering performance, set StorePaintBuffer to True on parent controls from the package. By default it is True in some controls, in some False. -
How do I close a modal form without ModalResult being set to mrCancel ?
Lajos Juhász replied to dormky's topic in VCL
Delphi in order to survive must ASAP include the method to close a modalForm or we will die. As a Quick Fix they should include the class helper for all the existing versions: type TFormHelper = class helper for TCustomForm public procedure EndDialog(PModulResult: TModalResult); end; { TFormHelper } procedure TFormHelper.EndDialog(PModulResult: TModalResult); begin modalResult:=PModulResult; end; I can only hope that somebody from Embarcadero will read this thread and will push these changes directly to the TForm not to require a class helper for such an important issue to be fixed. (For years I was using the modalResult to close modal forms without a single issue. This thread made me realize that Delphi is dying because it does not have such a method.) -
Hi the Delphi Praxis community, I'm happy to announce to you that since now the SVGMagic component library is open-source and free for commercial and non-commercial use, under the MIT license. Please find the source code here: https://github.com/Jeanmilost/SVGMagic And the website was migrated here: https://jeanmilost.github.io/svgmagic.web/
-
Uwe, OK, more clarity :-). When I run my project, one of the buttons runs an Ace Report with a "sctRepCustList.Run" command. This runs the report which is on a form. I don't get to see the form, just the report output. It isn't like I have the report form open in the IDE where I would know know exactly what it is called and what name I save it with. Mark, A global search in all files doesn't show anything other than the form where I run the Ace Report from.