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

How and when are variables referenced in Delphi’s anonymous methods captured? – Stack Overflow

Posted by jpluimers on 2018/09/04

Just found some notes from 2013 for my research list that are still relevant:

Note that if you are using Smart Pointers, use the ones that Spring4D implemented in 2015 named Shared/IShared<T>/TShared<T>, see [WayBack] Spring4D – Pascal Today and [WayBack2] Smart Pointers will be in Spring4D 1.2.

–jeroen

Posted in Delphi, Delphi 2009, Delphi 2010, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Development, Software Development | Leave a Comment »

The Delphi VCL comes to Oxygene

Posted by jpluimers on 2018/09/03

Interesting approach, which makes one more “cross platform VCL” from outside the Embarcadero pipeline [WayBack] The Delphi VCL comes to Oxygene:

Developers switching from Delphi to Oxygene are loving our “Delphi RTL” compatibility library, as it helps them move their code over to new platforms without having to embrace all the new APIs at once. With the new Elements 10 builds we shipped in the past couple of weeks,

CrossVCL (by KSDev, the former FMX architects) already brings VCL to Linux through the Embarcadero compilers; VCL for Oxygene brings it – through the Oxygene compilers – to WebAssembly first and later to Cocoa and WPF.

I wonder how Windows VCL compatible both approaches are.

Via [WayBackhttps://blogs.remobjects.com/2018/08/30/the-delphi-vcl-comes-to-oxygene/ – Ondrej Kelle – Google+

–jeroen

Posted in Delphi, Development, Oxygene, Pascal, Software Development | 2 Comments »

Delphi: delete temporary file after response dispatched – Stack Overflow

Posted by jpluimers on 2018/08/30

A while ago, Marjan Venema was in need for [Archive.isDelphi SOAP: delete temporary file after response dispatched – Stack Overflow.

The solution there is a truly temporary file: a file stream that when the handle closes will have Windows delete the file by setting the correct flags.

The construct is functionally identical to the JclFileUtils.TJclTempFileStream [Archive.is].

It passes these [Archive.isfile attribute constant flags to the [Archive.isCreateFileW Windows API function:

  • FILE_ATTRIBUTE_TEMPORARY
  • FILE_FLAG_DELETE_ON_CLOSE

I was glad she asked, though I wanted a temporary file to last after debugging, so I wrote code like this because internally the same FileGetTempName method is used by the JCL:

var
// ...
  TempPath: string;
  TempStream: TFileStream;
  TempStreamWriter: TStreamWriter;
begin
// ...
  TempPath := FileGetTempName('Prefix');
  TempStream := TFile.Open(TempPath, TFileMode.fmOpenOrCreate, TFileAccess.faReadWrite, TFileShare.fsRead);
  try
    TempStreamWriter := TStreamWriter.Create(TempStream);
    try
      TempStreamWriter.WriteLine('Debug starts:');
      MyStringList.SaveToStream(TempStream);
      TempStreamWriter.WriteLine();
// ...
      TempStreamWriter.WriteLine('Debug finishes.');
    finally
      TempStreamWriter.Free();
    end;
  finally
    TempStream.Free();
  end;

–jeroen

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

How to read data from old delphi application Paradox databases without BDE?

Posted by jpluimers on 2018/08/30

Interesting question that raise some good tips: [WayBack] How to read data from old delphi application Paradox databases without BDE? I search for freeware or open source solution. – Jacek Laskowski – Google+

–jeroen

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

DUnitX: now has a WillRaiseAttribute to ease defining tests around code that should throw exceptions

Posted by jpluimers on 2018/08/29

I stumbled over this commit message in [WayBack] “extended the TestAttribute with “Expected” property (#181)” which isn’t phrased correctly, but adds a very nice feature.

The feature is about WillRaiseAttribute:

constructor WillRaiseAttribute.Create(AExpectedException: ExceptClass; const AInheritance: TExceptionInheritance);

This allows tests like these:

    [WillRaise(EOutOfMemory)]
    procedure FailMe;

    [WillRaise(EHeapException, exDescendant)]
    procedure FailMeToo;

    [WillRaise(Exception, exDescendant)]
    procedure FailAny;

    [WillRaise(EOutOfMemory)]
    [Ignore('I am not behaving as I should')]
    procedure IgnoreMeCauseImWrong;

–jeroen

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

Enum values in their own namespaces/scopes: Scoped Enums (Delphi)

Posted by jpluimers on 2018/08/29

A while ago, I needed several enum types in the same unit with overlapping enumeration values.

Putting each in an encompassing type wasn’t possible and I didn’t want to put each in their own unit.

Luckily, Delphi 2009 introduced the “scoped enum” feature effectively promoting the enumeration type into a scope or namespace.

It is only available at the source code level, as – at least up until Delphi 10.1 Berlin – it is not part of the compiler settings in the project options (see screenshot below).

Since the below was hard to find combined with the word “namespace” I’ve quoted it in full (note an earlier version of the post had a typo here as it was copied from the Delphi 2009 documentation which had SCOPEDEUNMS wrong):

Type
Switch
Syntax
{$SCOPEDENUMS ON}, or {$SCOPEDENUMS OFF}
Default
{$SCOPEDENUMS OFF}
Scope
Local

Remarks

The $SCOPEDENUMS directive enables or disables the use of scoped enumerations in Delphi code. More specifically, $SCOPEDENUMS affects only definitions of new enumerations, and only controls the addition of the enumeration’s value symbols to the global scope.

In the {$SCOPEDENUMS ON} state, enumerations are scoped, and enum values are not added to the global scope. To specify a member of a scoped enum, you must include the type of the enum. For example:

type
  TFoo = (A, B, Foo);
  {$SCOPEDENUMS ON}
  TBar = (A, B, Bar);
  {$SCOPEDENUMS OFF}

begin
  WriteLn(Integer(Foo)); 
  WriteLn(Integer(A)); // TFoo.A
  WriteLn(Integer(TBar.B));
  WriteLn(Integer(TBar.Bar));
  WriteLn(Integer(Bar)); // Error
end;

Note that this is also valid:

 Writeln(Integer(TFoo.A));

Even though TFoo was not declared with $SCOPEDENUMS ON, the A value can still be explicitly resolved using the enumeration name.

Read the rest of this entry »

Posted in Delphi, Development, Software Development | 4 Comments »

Embarcadero community RSS links

Posted by jpluimers on 2018/08/28

As G+ refused to put this in a comment at [WayBack] Does anybody know whether the Embarcadero blogs have got individual RSS feeds? And what’s the URL of the RSS feed for all blogs? … – Thomas Mueller (dummzeuch) – Google+:

No RSS logo is visible for me on the blog pages, but inspecting the source reveals the 404 link below; deducting from that I got 200 results:

What doesn’t work for RSS (CC +Marco Cantù) as you get 404:

  • events
  • individual questions
  • individual blog posts

Failure examples:

–jeroen

Read the rest of this entry »

Posted in Delphi, Development, Software Development | 4 Comments »

Delphi: create or append to a TFileStream

Posted by jpluimers on 2018/08/23

It looks like the Delphi [WayBackTFileStream.Create does not have an overload that allows you to create or append. Luckily, [Archive.is] TFile.Open allows you to do this when passing the correct [Archive.isTFileMode enumeration value:

TempStream := TFile.Open(TempPath, TFileMode.fmOpenOrCreate, TFileAccess.faReadWrite, TFileShare.fsRead);

I still wonder why that never made it into a TFileStream.Create overload, or why these overloads fail to use enumerations or sets of modes.

–jeroen

Posted in Delphi, Development, Software Development | 6 Comments »

Is there a reason why third party component vendors still ship dfm in binary files …

Posted by jpluimers on 2018/08/23

I knew it was backward compatibility, but TeeChart author David Berneda knew exactly what version:

One old issue with the XE5 osx compiler, some forms in text format raised a “Bad file format” exception, fix was leave them binary

–jeroen

Source: [WayBackIs there a reason why third party component vendors still ship dfm in binary files? – Google+, Stefan Glienke

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

Property/event differences between Delphi forms and frames

Posted by jpluimers on 2018/08/22

From a while back, but still interesting especially because there some differences similar to base/inherited designer objects: [WayBackvcl – How to do bulk -transformation of form to frame- in Delphi? – Stack Overflow:

Observe the differences of a Form and a Frame in your project.

First the project.dpr source:

program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit3 in 'Unit3.pas' {Frame3: TFrame};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Differences:

  1. Frame as a more elaborated comment to tell the IDE which designer it should use
  2. Form can be autocreate

Dfm files:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 348
  ClientWidth = 643
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
end

and

object Frame3: TFrame3
  Left = 0
  Top = 0
  Width = 320
  Height = 240
  TabOrder = 0
end

Frame does not have these properties:

  • Caption
  • ClientHeight
  • ClientWidth
  • Color
  • Font.Charset
  • Font.Color
  • Font.Height
  • Font.Name
  • Font.Style
  • OldCreateOrder
  • PixelsPerInch
  • TextHeight

Sidenote: Frame does not have these events:

  • OnCreate
  • OnDestroy

A Frame has not global variable like this:

var
  Form1: TForm1;

And a Frame descends from TFrame, whereas a form descends from TForm.

Note: with Frame/Form inheritence, your steps become a bit longer.

–jeroen

Some of these are similar to the differences you see here:

–jeroen

PS: Idea: make a wizard or conversion tool for this.

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