The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,854 other subscribers

Archive for the ‘Delphi’ Category

FastMM PushAllocationGroup

Posted by jpluimers on 2020/10/29

Few people seem to know about the FastMM PushAllocationGroup method.

This search returned almost nothing: fastmm PushAllocationGroup -site:github.com -site:sourceforge.net -site:stackoverflow.com – Google Search.

These results were convoluted:

These posts were interesting though, but most of them did not get any deeper into the topic than “look at the FastMM source”:

There were the only post giving a bit more insight:

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, FastMM, Software Development | Leave a Comment »

Spring4D Mock – Delphi Unit Testing : Writing a simple spy for the CUT – Stack Overflow

Posted by jpluimers on 2020/10/28

Reminder to self: write a longer article on Delphi mocking as Spring4D mocking is much better than Delphi Mocks, especially because of code-completion reasons.

Spring4D has a Mock record that can return a Mock<T> on which you can verify using methods like Received.

See:

I got some code that I need to dig up from an old project with many more Spring4D Mock examples.

Note that:

For now, these are a start [WayBack] Delphi Unit Testing : Writing a simple spy for the CUT – Stack Overflow:

Sounds like a use case for a mock (I am using the term mock here because most frameworks refer to their various kinds of test doubles as mock)

In the following example I am using DUnit but it should not make any difference for DUnitX. I am also using the mocking feature from Spring4D 1.2 (I did not check if Delphi Mocks supports this)

unit MyClass;

interface

type
  TMyClass = class
  private
    fCounter: Integer;
  protected
    procedure MyProcedure; virtual;
  public
    property Counter: Integer read fCounter;
  end;

implementation

procedure TMyClass.MyProcedure;
begin
  Inc(fCounter);
end;

end.

program Tests;

uses
  TestFramework,
  TestInsight.DUnit,
  Spring.Mocking,
  MyClass in 'MyClass.pas';

type
  TMyClass = class(MyClass.TMyClass)
  public
    // just to make it accessible for the test
    procedure MyProcedure; override;
  end;

  TMyTest = class(TTestCase)
  published
    procedure Test1;
  end;

procedure TMyClass.MyProcedure;
begin
  inherited;
end;

procedure TMyTest.Test1;
var
  // the mock is getting auto initialized on its first use
  // and defaults to TMockBehavior.Dynamic which means it lets all calls happen
  m: Mock<TMyClass>;
  o: TMyClass;
begin
  // set this to true to actually call the "real" method
  m.CallBase := True;
  // do something with o
  o := m;
  o.MyProcedure;

  // check if the expected call actually did happen
  m.Received(Times.Once).MyProcedure;

  // to prove that it actually did call the "real" method
  CheckEquals(1, o.Counter);
end;

begin
  RegisterTest(TMyTest.Suite);
  RunRegisteredTests();
end.

Keep in mind though that this only works for virtual methods.

  • In case you need to test a method from a base class which cannot be affected by the $RTTI directive, you can use a little trick and redefine it in subclass in public section as override; abstract; this will cause the RTTI to be generated. – Honza RFeb 5 ’16 at 8:02

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development, Spring4D | Leave a Comment »

Optional sort by name in `LogMemoryManagerStateToFile` · Issue #64 · pleriche/FastMM4 · GitHub

Posted by jpluimers on 2020/10/27

If not done yet, try to improve this: [WayBack] Optional sort by name in LogMemoryManagerStateToFile · Issue #64 · pleriche/FastMM4 · GitHub

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

delphi – Can I use an Edit Mask to format output? (not just validate input) – Stack Overflow

Posted by jpluimers on 2020/10/27

From a while ago, and – being on the back-end side mostly – I sometimes forget: [WayBack] delphi – Can I use an Edit Mask to format output? (not just validate input) – Stack Overflow

You can use the TField.OnGetText event or TNumericField.DisplayFormat property to modify how the text is being displayed.

Since you have a TStringField holding numbers, you have two choices:

  • use a TNumericField and the DisplayFormat property
  • use the OnGetText event and do your own string formatting

Edit:

Sam used this approach:

I implemented OnSetText and OnGetText event handlers. I already had the Edit Mask 9999 9999 9999 9999;1;_ so the OnSetText was just

TStringField(Sender).Value := Trim(Text);

and OnGetText was just

sValue := TStringField(Sender).Value;  
Text := Format('%s %s %s %s', [Copy(sValue, 1, 4), Copy(sValue, 5, 4), Copy(sValue, 9, 4), Copy(sValue, 13, 4)]);

It works fine. Thanks.

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

My toolkit – Roald’s blog

Posted by jpluimers on 2020/10/22

Always interesting to see what others put on their Windows development systems, for instance: [WayBack] My toolkit – Roald’s blog

Everytime I (re)install my development computer I need to think about all the tools I need and use on a regular basis. For that reason, and maybe to inspire others, here’s my list of essentia…

–jeroen

Posted in .NET, Delphi, Development, Software Development, Windows Development | Leave a Comment »

delphi – How to convert a null terminated string to string? – Stack Overflow

Posted by jpluimers on 2020/10/22

An old trick that I tend to forget: [WayBack] delphi – How to convert a null terminated string to string? – Stack Overflow:

You can assign a null-terminated PChar directly to a String:

function GetFileName(DiskName: TFileNameIO): string;
begin
 Result := PChar(@DiskName);
end;

It can work even on string literals and constants, where you can leave out the @, like in:

var
  S: string;
begin
  S := PChar(FastMM4Messages.LogFileExtension;

Probably time to update the unit I mention in ISO 8601 Date, Time and DateTime in Delphi (was: Simple example to show DateTime.Now in ISO 8601 format on ideone.com | Online C# Compiler & Debugging Tool).

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

Automated testing Windows applications using Katalon and WinAppDriver

Posted by jpluimers on 2020/10/21

[WayBack] Top 45 Best Automation Testing Tools Ultimate List • Test Automation Made Easy: Tools, Tips & Training Awesomeness A few notes, partially related to Enable your device for development – UWP app developer | Microsoft Docs.

One research project I had a while ago, was to see how it was possible to use a generic testing tool like Katalon Studio (that can test many platforms), for testing Windows applications.

Katalon uses a Selenium interface that normally is used for web applications through the [WayBack] WebDriver protocol (formerly [WayBack] JsonWireProtocol) that continues to be updated: [WayBack] draft upcoming WebDriver protocol, which is more generic than just web applications:

Read the rest of this entry »

Posted in .NET, Conference Topics, Conferences, Delphi, Development, Event, Software Development, Windows Development, WinForms, WPF | Leave a Comment »

Delphi: get timestamp as ISO8601 string for use in filenames

Posted by jpluimers on 2020/10/21

On Windows, filenames do not like some characters (including : and +), so this is a quick way to get a timestamp into ISO8601 format that is compatible with filenames.

TimeStamp := Now();
StartIso8601String := DateToISO8601(TimeStamp, False).Replace('-', '').Replace(':', '') // https://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators

It Depends on the [WayBackSystem.DateUtils unit which had the [WayBackDateToISO8601 function [Archive.isadded in Delphi XE6.

A poor man’s solution (that skips timezones altogether) is this one:

FormatDateTime('yyyymmdd''T''hhnnss''.''zzz', TimeStamp); // note quoted T and ., as otherwise they will be expanded.

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

Class methods in Record vs Class in Delphi 2010 – Stack Overflow

Posted by jpluimers on 2020/10/20

A still relevant part for [WayBack] Class methods in Record vs Class in Delphi 2010+ – Stack Overflow is the distinction between class methods on both:

  • on classes they can be either regular (no extra keyword), static or virtual.
  • on records they can only be static, as there is no inheritance on records
    • this also holds for any helpers that are not class helpers (and presumably if they are ever created: interface helpers)

While class methods inside classes can be used in the same way, they can in addition have another goal: they can be virtual. Called from a class variable this can lead to different implementations depending on the current content of that variable. This is not possible for records. As a consequence class methods in records are always static.

Thanks Uwe Raabe for this insight!

One odd thing on class methods in classes, is that when they need to be static when they are the read or write backing of a class property.

When a class method is static, any calls from it to virtual (or dynamic) methods will not be handled as such: there is no class VMT for it (as because they are static, they do not have a self parameter).

–jeroen

PS: I realised later that part of the above was already in E2398 Class methods in record types must be static (Delphi) – RAD Studio

Posted in Delphi, Development, Software Development | Leave a Comment »

Delphi and conditional compilation

Posted by jpluimers on 2020/10/15

There are various ways for Delphi code to verify what features are available.

Historically, testing for the existence of VER### defines with $IFDEF or $IFNDEF is the oldest means, and as of Delphi 6, you can also test for the existence and values of identifiers is $IF defined, $IF not defined and, especially for CompilerVersion and RTLVersion .

My versioned PowerShell script List-Delphi-Installed-Packages.ps1 tries to keep an up to date list of versions and features starting with BDS 1 (which was C# Builder) and BDS 2 (which was Delphi 8 with VER160). One day I will make it Pascal based in stead of BDS based.

The JEDI Code Library has kept a versioned JEDI.INC up to date since Delphi 1.0.

Binding those to specific features can be a tough thing when you depend on version numbers, but less hard when you rely on feature names.

Every couple of years, people start proposing units to replace include files, usually with an argument like this:

If you forget to include it into your source code, all your IFDEFS will fail and in the worst case your workaround won’t be active (the best case is that the compiler runs into an error so you will notice the missing include).

The problem is that for such a unit to work:

  1. you have to always use it (debunking the above argument)
  2. you will need to have the very latest version, even if you use old compilers (so you can use code written for any Delphi version)
    • See the quoted below “Do you expect that the old versions will get an update to know the new constants RTLVersion_Atlantis = 99.0; too?” below
  3. you need a central place where that version is available (like JEDI.INC)
  4. it will only work with booleans
    • See the quote below “Which is also backwards compatible because the compiler (at least in XE and up, haven’t checked any older versions) just evaluates a non existing value as False.”
  5. it requires $IF, which is a pain in the ass
    • See the quote below “Using $IF is a major pita because of $IFEND or $ENDIF depending on compiler version and $LEGACYIFEND setting.”

The only good thing is what Rudy Velthuis commented:

checking for a $DEFINE like DELPHI_RIO_UP can go wrong. If you have a typo, it will simply not be recognized as defined and compile the wrong code. Checking for {$IF CompilerVersion >= some_constant} will fail to compile if some_constant is not defined

A few people tried:

JEDI.INC

You might think that JEDI.INC was only introduced in 2003, but it is in fact much older as the JEDI Code Library had its own version control system (initially called FreeVCS) before first switching to SVN and later to GIT.

So these are only part of the history:

VER### got introduced as VER40 in Turbo Pascal 4

The product naming mess now completely has disconnected people from binding it to their Delphi version.

It helps knowing that VER### is the compiler version starting with Turbo Pascal 1, and remembering that Delphi 1 had VER80, and the three digits only started with Delphi 3 which introduced VER100.

Turbo Pascal 1 through 3 did not have any VER## defined, despite some sites

The first ever VER## conditional define was VER40 was introduced in Turbo Pascal 4, as you can see in Full text of “borland :: turbo pascal :: Turbo Pascal Version 4.0 Owners Manual 1987” (or PDF via borland :: turbo pascal :: Turbo Pascal Version 4.0 Owners Manual 1987 : Free Download, Borrow, and Streaming : Internet Archive)

Related:

JEDI History:

–jeroen

Read the rest of this entry »

Posted in Delphi, Development, Software Development, Turbo Pascal | Leave a Comment »