Delphi: Absolute

You don’t often come across a piece of Delphi code that uses the keyword “absolute”. A lot of Delphi programmers consider it to fall in that “stay away” category, like “goto”. The keyword, when used correctly can however be very convenient and improve the readability of your code.

The absolute keyword allows you to define a variable that points to the memory location of another variable. This is something you can achieve with pointers as well, but the absolute keyword allows you to do it very cleanly in a single line of code.

Read More

Delphi: Convert set of Char to string WITH ranges

In an application I’m working on, I need to convert a set of characters to a string, but I want it to be short, so I want to keep the ranges intact. Now, there may be a better way of doing this, but I had little luck finding a solution online, so I wrote this piece of code:

If you input [‘a’..’z’, ‘A’..’Z’, ‘0’..’9′, ‘_’, ‘ ‘, ‘.’], it will print out the string: [‘ ‘, ‘.’, ‘0’..’9′, ‘A’..’Z’, ‘_’, ‘a’..’z’]

In case anyone knows a better way of doing this, let me know in the comments.

Read More

Delphi Certification

Embarcadero recently started a Delphi certification service. This allows you to test your Delphi skills and get certified by Embarcadero. The certificate is meant to show employers that you are well educated in the usage of Delphi and all of it’s concepts. If you hold a Delphi XE license, you are able to take the certification test free of charge (unless you have an academic license like me). Otherwise the entry free for the test is $49, which is affordable, while ensuring that people don’t take the test lightly. A master certification test is also available, passing this would identify you as an elite member of the Delphi community. The master test can however only be taken at a licensed Delphi certification center at a fee of $149.

Read More

Delphi: Remove Directory Recursively

If you ended up looking for this, then you probably came to the conclusion that Windows.RemoveDirectory() can not remove a directory that has files/directories in it.

About.com proposes the following solution: http://delphi.about.com/cs/adptips1999/a/bltip1199_2.htm

I can assure you that this solution is valid and works. However, the code as it is proposed there will move the deleted folder into the recycle bin which is something you will want to avoid more often than not. The following code I modified to remove that effect:

Another way of doing this is recursing through all directories and removing all files before you remove the directories as seen here, but I imagine that might be slower as in the method above, the OS takes care of that internally:

Read More

Delphi: Exposing Protected Properties

On occasion you’ll find yourself wanting to access a a protected property from a class in a different unit. If this is a 3rd party unit, you’ll often not want to modify it’s source code. So how do you access it? Sub-classing the class as you might have guessed, however, you can do this in very little code.

Delphi will allow any class to use protected properties from other classes as long as they are in the same unit. We can use this to our advantage. By creating a subclass, we can essentially use this to access protected values in the class we’re sub-classing, it works the same way, because your subclass is in the unit you need it in. All you have to do, is cast the object to the subclass and you’re set to access the protected property.

unit Example;

interface

uses
  Classes;

type
  TStringListEx = class(TStringList);

implementation

function SLChanged(const SL: TStringList): Boolean;
begin
  Result := TStringListEx(SL).Changed;
end;

end.

Read More

Delphi 64-bit Compiler Preview

Ever since Embarcadero has been in charge of Delphi’s development, they have made great strides to bring the language back from the brink of death. From the start they have therefor also been developing a 64-bit compiler for Delphi, which unfortunately has been postponed for quite some time. I can’t really blame them, if the product isn’t finished, there’s no point in releasing it, it would only make matters worse, but now, finally they have started giving Beta testers access to the 64-bit compiler preview.

As usual, also with this new compiler, Embarcadero has dedicated huge efforts towards keeping backwards compatibility as much as possible. This results in the face that most old Delphi code will still compile with this 64-bit compiler. The size of Integers, Int64, and most other datatypes have gone unchanged. However, NativeInt for example has the size of the integer on the system you’re on. Pointers on 64-bit are also 8 bytes, but as long as you always use SizeOf or similar methods that don’t rely on specifying a size of a datatype manually, your code should work in 64-bit. If you have any dependencies on dll libraries or activex components, these will have to be upgraded to 64-bit versions as well of course.

The final edition of the 64-bit compiler should be included in the next release of Delphi, the XE2 release. In XE3 the compiler will also compile code from C++ builder into 64-bit applications and libraries. Alongside the 64-bit compiler, Embarcadero also promises to include a cross-platform compiler in RAD Studio XE2 which can compile 32-bit applications to Mac OSX and possibly Linux. The additions of these new features may finally revitalize the interest of developers in this language as most other mainstream language already have at least in some way the ability to compile to 64-bit platforms and platforms other than MS Windows.

You can sign up to get into the beta program for the 64-bit compiler, if you have a license to RAD Studio XE, Delphi XE or ToolCloud, you may get priority access to the beta.


 

Read More

Delphi XE Starter

A while back in a post I mentioned that Embarcadero had plans to release a new Delphi license for hobbyists and others with a low price so people can get access to a license easier in case they don’t require it for commercial development. Embarcadero has now indeed come through with that promise and is now selling the Delphi XE Starter Edition on their website. There is only a starter edition available for Delphi, none of the other products like RAD Studio or C++ Builder and a license in the US store is priced at $199. Alongside this there are also upgrades available to Delphi Professional and RAD Studio Professional at reduced costs when coming from the Starter Edition.

The most important question regarding this new license is fairly obvious of course. What’s the difference with the Professional Edition? There are a few restrictions put in place. The Starter Edition is fully functional, there shouldn’t be any restrictions there, however, you can use it for commercial development if your yearly revenue stays under $1000. For small companies the usage is also permitted if their total revenue stays under $1000 and have less than or 5 people using the product for development. Once these conditions are no longer met, you are required to upgrade to the Professional edition. The academic licenses for Professional and will remain available.


 

Read More

Delphi: RichEdit Text Background Color

Something I needed in a project recently was to put some makeup into a richedit control. This is pretty easy with the SelAttributes field in the class. However, to my disappointment I found that the TTextAttributes class (SelAttributes) does not contain a field to set the background color of your text even though it is supported by the control. So I set out to find a solution to the problem on Google, but everything I could find required you to externally use the windows api to force this property onto the window.

I didn’t quite like this solution, so I came up with a cleaner one. I created a class helper for the TTextAttributes class. I first had a look at this class and noticed that the way the Color property is set and read does not require much work. Since I “can’t” access any of the class’ private methods I simply copied the few ones I needed to my class helper, being SetAttributes and GetAttributes. However, I couldn’t do the same with the 2 private fields in the class which I needed, so I made a small workaround for this. Note that this workaround will only work as long as VCL is changed. I created a small class with the same private fields. When casting the original object to this class, you can use it to access those private fields. If the name of the fields is changed in VCL, this small workaround has to be updated as well.

Here’s the header code:

uses
  ComCtrls, Graphics, RichEdit;

type
  __TTextAttributes = class
  private
    RichEdit: TCustomRichEdit;
    FType: TAttributeType;
  end;

  TTextAttributesH = class helper for TTextAttributes
  private
    function GetBackColor: TColor;
    procedure SetBackColor(const Value: TColor);
    procedure GetAttributes(var Format: TCharFormat2);
    procedure SetAttributes(var Format: TCharFormat2);
  public
    property BackColor: TColor read GetBackColor write SetBackColor;
  end;

And the body:

{ TTextAttributesH }

procedure TTextAttributesH.GetAttributes(var Format: TCharFormat2);
var
  RichEdit: TCustomRichEdit;
begin
  RichEdit := __TTextAttributes(Self).RichEdit;
  InitFormat(Format);
  if RichEdit.HandleAllocated then
    SendGetStructMessage(RichEdit.Handle, EM_GETCHARFORMAT,
      WPARAM(__TTextAttributes(Self).FType = atSelected), Format, True);
end;

function TTextAttributesH.GetBackColor: TColor;
var
  Format: TCharFormat2;
begin
  GetAttributes(Format);
  with Format do
    if (dwEffects and CFE_AUTOBACKCOLOR) <> 0 then
      Result := clWindow
    else
      Result := crBackColor;
end;

procedure TTextAttributesH.SetAttributes(var Format: TCharFormat2);
var
  Flag: Longint;
  RichEdit: TCustomRichEdit;
begin
  RichEdit := __TTextAttributes(Self).RichEdit;
  if __TTextAttributes(Self).FType = atSelected then 
    Flag := SCF_SELECTION
  else
    Flag := 0;
  if RichEdit.HandleAllocated then
    SendStructMessage(RichEdit.Handle, EM_SETCHARFORMAT, Flag, Format);
end;

procedure TTextAttributesH.SetBackColor(const Value: TColor);
var
  Format: TCharFormat2;
begin
  InitFormat(Format);
  with Format do
  begin
    dwMask := CFM_BACKCOLOR;
    if Value = clWindowText then
      dwEffects := CFE_AUTOBACKCOLOR
    else
      crBackColor := ColorToRGB(Value);
  end;
  SetAttributes(Format);
end;

Note that this only works in versions of Delphi that support class helpers. You can also use this method to add other missing properties.

Read More