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,839 other subscribers

Archive for the ‘Conference Topics’ Category

Delphi: a pattern for a generic factory, this one for components, but can be uses for anything having a base class like a TThread descendant.

Posted by jpluimers on 2018/05/16

Generics and constraints in Delphi is still a bit of pain.

A while ago, I needed a factory for threads. It was more convoluted than I meant it to be, so I had a short chat with Stefan Glienke.

He came up with an example similar to the one below. I tore it apart so you can on each line see what the compiler dislikes.

This fails, but was kind of how I wanted it to be:

type
   TFactory = record
     class function Manufacture<T: TBaseClass, constructor>(parameter definitions): T;
   end;

class function Manufacture<T: TBaseClass, constructor>(parameter definitions): T;
begin
  Result := T.Create(parameter values);
end;

Which means I need to update Delphi Constraints in Generics – RAD Studio XE documentation wiki

The factory:

type
  TComponentFactory = class
    class function CreateComponent<T: TComponent>(AOwner: TComponent): T; static;
  end;

class function TComponentFactory.CreateComponent<T>(AOwner: TComponent): T;
var
  ComponentClass: TComponentClass;
  Component: TComponent;
begin
  ComponentClass := T;
  Component := ComponentClass.Create(AOwner); // you can't do `T.Create(AOwner)`
  Result := T(Component); // you can't do `Result := ComponentClass.Create(AOwner);`
end;

The usage:

var
  Component: TButton;
  Owner: TComponent;
begin
  Owner := Application.MainForm;
  Component := TComponentFactory<TButton>.CreateComponent(Owner);
  Component.Parent := Owner;
end;

Full source example is at: After a discussion with Stefan Glienke: a pattern for a factory, this one for components, but can be uses for anything having a base class like a TThread descendant.

In the mean time, Spring4D has added the [Archive.is] Spring4D: TActivator record with many CreateInstance methods that allow you to create instances of classes for which you just have type information.

–jeroen

This fails:

type
   TFactory = record
     class function Manufacture<T: TBaseClass, constructor>(parameter definitions): T;
   end;

class function Manufacture<T: TBaseClass, constructor>(parameter definitions): T;
begin
  Result := T.Create(parameter values);
end;

view raw

readme.md

hosted with ❤ by GitHub


type
TComponentFactory = class
class function CreateComponent<T: TComponent>(AOwner: TComponent): T; static;
end;
class function TComponentFactory.CreateComponent<T>(AOwner: TComponent): T;
var
ComponentClass: TComponentClass;
Component: TComponent;
begin
ComponentClass := T;
Component := ComponentClass.Create(AOwner); // you can't do `T.Create(AOwner)`
Result := T(Component); // you can't do `Result := ComponentClass.Create(AOwner);`
end;


var
Component: TButton;
Owner: TComponent;
begin
Owner := Application.MainForm;
Component := TComponentFactory<TButton>.CreateComponent(Owner);
Component.Parent := Owner;
end;

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

Delphi WSDL default importer settings

Posted by jpluimers on 2018/05/15

Note to self (as the WSDL importer has trouble with WSDL files that include XSD files having xsd:group definitions), the default settings of the importer in the UI:

-Oa -Od -Oe -Of -Oh -Oi -Oj -Oo -Op -Ot -Ou -Ov -Ox

This matches the output from the WSDLImp.exe default settings as well (larger screenshots below):

I suspect the reason is that the command-line importer does, but the wizard does not, show an exception during processing:

*Error*: D:\Playground\iECK DT2.0 services v2.1.1\xsd\ECK-DT2-CatalogServiceSchema-v2.1.1.xsd
> Access violation at address 0059DBA4 in module 'WSDLImp.exe'. Read of address 00000000
Done : D:\Playground\iECK DT2.0 services v2.1.1\wsdl\ECK-DT2-CatalogService-v2.1.1.wsdl>0
Writing: D:\Playground\iECK_ImportWSDL\ECK_DT2_CatalogService_v2.pas

Hopefully more on that later.

Both the IDE expert and console based WSDLimp will write the output .pas file and the output file of both tools has the same content.

–jeroen

Read the rest of this entry »

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

Procedural Programming: It’s Back? It Never Went Away – Kevlin Henney [ACCU 2018] – YouTube

Posted by jpluimers on 2018/05/09

If you haven’t been in the software development arena for the last 50 years, then watch this and learn all “modern” stuff has been around for ages:

Most if it comes from the era of Algol, make, AWK and the famous Structured Programming book (which is not about procedures, but about control flow).

So watch Procedural Programming: It’s Back? It Never Went Away – Kevlin Henney [ACCU 2018] – YouTube

Slide deck: Sideshare: Procedural Programming: It’s Back? It Never Went Away – Kevlin Henney [ACCU 2018]

Then read [WayBack] ISBN 9780122005503 – Structured Programming (A.P.I.C. studies in data processing, no. 8)

Via: [WayBack] Kevlin Henney – Google+

–jeroen

Read the rest of this entry »

Posted in Agile, Conference Topics, Conferences, Development, Event, Paradigms, Software Development | Leave a Comment »

Delphi .dproj file changed or not changed? Normalize it! | The Art of Delphi Programming

Posted by jpluimers on 2018/05/02

Cool tool that integrates into the Delphi IDE: [WayBackDproj changed or not changed? Normalize it! | The Art of Delphi Programming

Via: [WayBack] Introducing DprojNormalizer: http://www.uweraabe.de/Blog/2017/01/18/dproj-changed-or-not-changed/ – Uwe Raabe – Google+

Note there is also RadCLI that requires Python and does it via the command-line:[WayBackjoshkel/RadCli: Command-line utilities for RAD Studio / Delphi / C++Builder

DprojNormalizer supports Delphi XE7 and up.

Updates at [WayBack] Downloads | The Art of Delphi Programming: DprojNormalizer

Note that it requires an elevation to Administrator for installing. If you run Delphi as a normal user, then afterwards you need to register the package yourself, for instance with a batch file like this:

reg add "HKEY_CURRENT_USER\Software\Embarcadero\BDS\18.0\Known Packages" /v "C:\Program Files (x86)\DprojNormalizer\DprojNormalizer240.bpl" /t REG_SZ /d "Dproj Normalizer" /f
reg add "HKEY_CURRENT_USER\Software\Embarcadero\BDS\19.0\Known Packages" /v "C:\Program Files (x86)\DprojNormalizer\DprojNormalizer250.bpl" /t REG_SZ /d "Dproj Normalizer" /f

Adjust your BDS and DllSuffix in the BPL file names using the table at Delphi version info table: C# Builder, Delphi 8 through 10.2 Tokyo and Appbuilder.

If you want to temporarily disable it:

reg add "HKEY_CURRENT_USER\Software\Embarcadero\BDS\18.0\Disabled Packages" /v "C:\Program Files (x86)\DprojNormalizer\DprojNormalizer240.bpl" /t REG_SZ /d "Dproj Normalizer" /f
reg add "HKEY_CURRENT_USER\Software\Embarcadero\BDS\19.0\Disabled Packages" /v "C:\Program Files (x86)\DprojNormalizer\DprojNormalizer250.bpl" /t REG_SZ /d "Dproj Normalizer" /f

If you want to re-enable it: remove the values under Disabled Packages.

–jeroen

 

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | 1 Comment »

Do not use non-ASCII characters as identifiers – not all your tools support them well enough

Posted by jpluimers on 2018/04/05

For a very long time I’ve discouraged people from using non-ASCII characters in identifiers. It still holds.

In the past, transliterations messed things up. Even with increased support for Unicode, tools still screw non-ASCII characters up.

Delphi is not alone in this (the most important one is the DFM view as text support), see this report: [RSP-16767] Viewing a form as text fails with non ascii control or event names – Embarcadero Technologies (you need an account for this, but the report is visible for anyone):

Viewing a form as text fails with non ascii control or event names Comment

Steps:

  1. create a new VCL forms application
  2. drop a label onto the form
  3. change the name of that label to lblÜberfall (note the U-umlaut)
  4. switch to view as text
  • exp: DFM content shown as text
  • act: first line is shown incorrectly (see screenhsot)

–jeroen

Source: [RSP-16767] Viewing a form as text fails with non ascii control or event names – Embarcadero Technologies

via: [WayBack] Code of the day – – Thomas Mueller (dummzeuch) – Google+:

function TNameGenerator.StrasseToStrasse(const _Strasse: string): string;
begin
Result := _Strasse;
end;

Strasse := StrasseToStrasse(_Strasse);

Read the rest of this entry »

Posted in ASCII, Conference Topics, Conferences, Delphi, Delphi 10 Seattle, Delphi 10.1 Berlin (BigBen), Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Delphi XE6, Delphi XE7, Delphi XE8, Development, Encoding, Event, Mojibake, Software Development | Leave a Comment »

As Delphi generics are not supported for free functions, wrap them in a record container.

Posted by jpluimers on 2018/01/31

Of the things not possible with generics in Delphi, I already wrote about Impossible: Property using Generics in Delphi.

Now it’s time to write about simulating a free function with generics as this is impossible:

function CreateManaged<T>(const value: T): IManaged<T>;

Usually I create a static record method for these, as records do not have VMT overhead, less RTTI overhead and I’ve been used to see records as helpers for other types long before helpers initially were introduced in Delphi 8 to extend classes..

Spring4D has an excellent example of such a record workaround in the Managed.New<T> commit:

type
  Managed = record
  public
    class function New<T>(const value: T): IManaged<T>; static;
  end;

...

class function Managed.New<T>(const value: T): IManaged<T>;
begin
  Result := TManaged<T>.Create(value);
end;

It basically is a factory for classes implementing the IManaged interface.

In the mean time, Managed has been renamed to Shared but the above code shows my point.

–jeroen

Reference: [WayBackClass Helpers documented in Delphi 2007, introduced in Delphi 8

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | 5 Comments »

Record helpers can do wonders for code clarity.

Posted by jpluimers on 2018/01/04

A few people recently discovered the beauty of record helpers:

Record helpers can help any value type (which includes enumerated types) so you can add functions to enumerations.

Class helpers can help class types.

There are no interface helpers and likely won’t be there for a long while.

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Power User, Software Development | 2 Comments »

Delphi: it is better to use ifndef rather than ifdef to keep the IDE working properly…

Posted by jpluimers on 2017/12/28

[WayBackDear diary, today I learned that it is better to use ifndef rather than ifdef if I want the IDE to keep working properly. I had a uses clause with an i… – Stefan Glienke – Google+

I promised to remind myself, so here it is (:

–jeroen

 

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

Valid reasons for having Delphi AnsiString on Mobile platform…not only for Internet but for Shaders also. //…

Posted by jpluimers on 2017/12/27

It’s too bad that you need workarounds to get ByteStrings working on mobile devices as there are APIs there (like shaders) that work best with them.

There was a nice discussion on this last year at [WayBack] I miss AnsiString on Mobile…not only for Internet but for Shaders also.// FMX.Context.GLES.pasconstGLESHeaderHigh: array [0..24] of byte =(Byte(‘p), … – Paul TOTH – Google+ based in this code example in the FMX library undocumented unit FMX.Context.GLES:

// FMX.Context.GLES.pas

const
  GLESHeaderHigh: array [0..24] of byte =
    (Byte('p'), Byte('r'), Byte('e'), Byte('c'), Byte('i'), Byte('s'), Byte('i'), Byte('o'), Byte('n'), Byte(' '),
     Byte('h'), Byte('i'), Byte('g'), Byte('h'), Byte('p'), Byte(' '), Byte(' '), Byte(' '), Byte('f'), Byte('l'),
     Byte('o'), Byte('a'), Byte('t'), Byte(';'), Byte(#13));

There are more than 500 places in the Delphi library sources that uses this construct and even more that do other fiddling (like [WayBackTEncoding.GetBytes) to get from strings to bytes.

I wonder if by now we still need the workarounds that Andreas Hausladen provides:

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Encoding, Event, Software Development | 6 Comments »

Another case against FreeAndNil

Posted by jpluimers on 2017/12/21

I started this post as “A case against FreeAndNil” but soon found out about [WayBack/Archive.isA case against FreeAndNil – Community Blogs – Embarcadero Community.

Recently I was refactoring a bunch of code that was classed based to become interface based.

The old code had a lot of references to classes like this:

FMyField: TMyClass;

The compiler had detected those as compiler errors so now they were like this:

FMyField: IMyInterface;

But the compiler would still happily compile code (for instance in destructors) containing:

FreeAndNil(FMyField);

The only way that FreeAndNil can be implemented is with an untyped var parameter:

Read the rest of this entry »

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | 14 Comments »