Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 06/19/25 in all areas

  1. 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;
  2. 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.
  3. bazzer747

    What .PAS file does a form use?

    Arrgghh! Found it. It was on a form which contained two Ace Reports, the one I wanted was minimised on the form, the other was maximised so hid the report I was after when I opened the form. The .pas name equated to the maximised report so when I was looking before that one came up in searches. It would pay me to put one report per form to avoid this confusion in the future. I had followed many of your suggestions, so thankyou all very much for helping through this.
  4. Dalija Prasnikar

    Introducing My Delphi TFuture PPL For Thread Safe UI

    The whole point of Delphi Future implementation is to be a blocking call. Now, we can discuss whether this kind of design is useful or not and in which circumstances. However, your improved Future is mostly useless. Instead of creating a future and then resolving it in additional task (you are involving two threads here) you should just run the code in the task and that is it. Simply use TTask.Run( procedure begin var LValue := (...); TThread.Queue(nil, procedure begin LogReply('Result: ' + LValue.ToString); // update UI on main thread that service the TTask end); end); No need to overcomplicate things.
  5. Roger Cigol

    components ?!

    The delphi components are all available from the component pallet. This is reasonably well organised into groups which give a good indication of the type of functions provided by each set. Best way to learn is to create an empty form and put the component on it. This brings up all the properties (again most are self explanatory (at least for the commonly used components)). If you go to the corresponding source code and click so the cursor is in the component name and then use F1 this will bring up "help" documentation. For more (better?) help - you can search for the component in the DocWiki https://docwiki.embarcadero.com/RADStudio/Athens/en/Main_Page By the way - you did post your "Delphi" related question in the C++ section of the forum - perhaps not the best place to reach other delphi developers (although all the VCL components can be used with C++ too).
×