Wednesday, November 22, 2006

Office 2007 GUI License

Office 2007 introduces a complete new GUI interface. One of the eyecatchers is the so called Office 2007 ribbon.
Today devexpress announced the availability of the Ribbon control for both the .NET users as the VCL users (currently in Beta). For VCL users there is also (among others) the Toolbarpager control from TMS Software.
According to Julian Bucknall's blogpost the ribbon can only be used if you obtain a license from Microsoft. (A vendor's license does not cover a user license)

Quote from Julian's blogpost:
To summarize, if you want to use a ribbon in your applications (whether you decide to use either our .NET or our VCL components or, horror, someone else's :) ), you will have to sign the Office UI licensing agreement with Microsoft. This no-cost license is a royalty-free agreement between yourselves and Microsoft that enables you to take advantage of the intellectual property (IP) that they've embodied in the new Office 2007 UI (including copyrights, trademarks, and patents). Part of this license is a remarkable document: the Office UI Design Guidelines that describe, in almost excruciating detail, how the ribbon and its associated controls must work and must look in an application in order to satisfy the license.

Microsoft has invested a lot of money in creating the ribbon, so in a way it is generous that they allow us to use it at no cost, although I personally find it a bit strange to license a GUI (Just a bunch of pixels on the screen, isn't it?) and earn nothing with it. What is the deal? What is the catch?
Can't figure out Microsoft's intention with this except that all ribbons should work according their guidelines.
But how will Microsoft prevent a from scratch build ribbon with little different functions and ways?

More information can be found here:
Jensen Harris blogpost : Licensing the Office 2007 user interface
The announcement by Microsoft.
The Microsoft office UI guidelines preview. (PDF 1,4 MB)

Sunday, November 19, 2006

Third party components

One of the great things about Delphi is the fact that there are a lot of awesome third-party components out there. Commercial, Open sourced and freeware, you name it, there are good quality components plenty in each category. And as a tradition they (mostly) come all with sourcecode.

The benefits of third-party components are obvious but depending on the component set. There are components that give your application a modern look, while others solve a particular programming problem like communication protocols.
But it all comes down to the fact that using third-party components gives you the benefit of "dealing with the meat, instead of beans".
Besides that, if your vendor adds some nice new feature to a component, you can add that feature to your application by simply upgrading your components.

A disadvantage of third-party components is the fact that you become, sort of, dependent on the vendor.
Upgrading to a new Delphi version means upgrading the components. In other words you can only upgrade if you have all your components upgraded. So a lazy vendor can frustrate your upgrade plans.

What if a vendor goes out of business?
As said most components come with sourcecode, so in the worst case you can maintain the code yourself, although that was not the deal of course.

These are some consideration we made before using/buying third party components:

  1. Standardize your development. Use prefererd components for specific tasks. (For example try to use, as default, one componentset for all your GUI work. Don't mix them if not necessary)
  2. Use only components if they come with source code. This eliminates your dependency. (A positive side effect is that you can learn a lot from the source code)
  3. Buy 'long term licenses' like SA or subscriptions, so that you get updates for your components.

Our 3-rd-party favorites are:

  1. Devexpress VCL Components. This set is our default for GUI work.
  2. TMS Software Components. Besides a large component set, they have a few specific components for scripting and instrumentation.
  3. ReportBuilder from Digital-Metaphors. An outstanding reporting solution with an awesome end-user solution, right out of the box.
  4. AVLock Gold, a share ware component that helps you to turn your application into a trial version with only a few lines of code.

Conclusion:
Third party components are great. Buy/use them only if they come with source code. And last, but not least use them wise!

What are your favorites? 

Wednesday, November 15, 2006

CodeGear := Borland as DeveloperToolGroup;

This is the moment, well last night (here in the Netherlands) was the moment. The Borland Developers Tool Group (DTG) becomes Codegear. See the original press release.

Have not yet read all the details, but it seems it is a separate company yet owned by Borland which will be independend by the end of next year.
For a (long) list of blogpost and comments see www.delphifeeds.com

Go CodeGear!

Tuesday, November 07, 2006

Microsoft urges Delphi developers to .NET

According to Tim Anderson's blogpost Microsoft has a special session at the Tech-Ed in Barcelona targeting Delphi developers.

Quote from Microsoft session:
Even if you are not considering .NET now, at some point you will have to move to .NET with new code, or to port existing code. Staying with Win32 may be viable in the short term, but not the long term.

Well, I am not sure what to think of this. There might be some point in time (who knows?) that you will have to move to .NET, however there are no signs on the wall that Win32 is being abounded real soon.
Delphi developers can still make awesome Win32 applications, which have plenty of opportunity to be ported to .NET at some time in the future with minimum effort. (I have blogged about the possibility's here ).

Delphi is all about being able to choose.

Monday, November 06, 2006

How to persist a TPersistent?

In a recent project the end-user should be able to do some settings of a specific control. The control, an InstrumentMeter, has a lot of properties, and only some properties, like color, scale etc. had to be customizable by the end-user.

A very common way to let a user edit properties is to use a RTTI property inspector. The user can then edit properties in a Delphi way. I use the Devexpress RTTI inspector, but there are many alternatives outthere. The RTTI inspector object has a property to link the 'to be inspected control' called InspectedControl of type TPersistent.
Because users may only edit some of the properties I could not set the control there, because all the published properties would become editable.

So I decided to make a wrapper class for the control, which published only the necessary properties and 'links' them to the InstrumentMeter control.
(You can inherit a control and publish only those properties that you want to, but this works only inside of Delphi) 

I decided to inherit this class from TPersistent, so that I could set it in my RTTI Inspector.
The class looks somewhat like this:

type
TInstrument = class(TPersistent)
private
public

  //the InstrumentControl  
  property InstrumentControl : TInstrumentControl;
published
  //All enduser props
  property Kleur: TColor read FColor write SetColor(const Value : TColor);
  property ...
end;


Properties set by the user (for instance Kleur) must be saved to a database. I could of course extend a table with fields for all the properties, but having several types of instruments this would give a lot of extra fields.

Why not persist the TInstrument object?
Yeah great idea, stream the object into a blobfield of the database. This can be done easily with a TComponent class, but how do you do this with a TPersistent class?

A TComponent class could be streamed with the TStream WriteComponent method like this:

MyStream.WriteComponent(AComponent);

This stream then, could be saved into a Blobfield and later on read with the TStream ReadComponent method.

I realize that I should inherit from TComponent so that I would not have a problem streaming, but hey let's persist on the TPersistent for now.

How to save a TPersistent to a stream?
As far as I know now, this is not possible.
The only way to do this, as far as I know, is to use a DummyComponent (TComponent) with a property holding the TPersistent object, and then streaming both in the database. That works fine!

The code looks like this:

type
  TDummyObject = class(TComponent)
  private
    FPersistent: TPersistent;
  public
    //Property for holding my Persistent object
   property Persistent: TPersistent read FPersistent write FPersistent;
end;

procedure SavePersistentToStream(APersistent: TPersistent; AStream: TStream);
var
  DummyObject: TDummyObject;
begin
  DummyObject:= TDummyObject.Create(nil);
  try
    DummyObject.Persistent := APersistent;
    //write the component into the stream
    Stream.WriteComponent(DummyObject);
  finally
    DummyObject.Free;
  end;
end;

procedure LoadPersistentFromStream(APersistent: TPersistent; AStream: TStream);
var
  DummyObject: TDummyObject;
begin
  DummyObject:= TDummyObject.Create(nil);
  try
    DummyObject.Persistent := APersistent;
    AStream.ReadComponent(DummyObject);
  finally
    DummyObject.Free;
  end;
end;

Writing this I decided to inherit from TComponent anyway (why not?) but the question remains, are there other ways to persist a TPersistent?

Friday, November 03, 2006

Two weeks of Delphi

We have had the 24 Hours of Delphi, The Delphi Hour weekly podcast, and now we also get two weeks of Delphi!

Two weeks long every day one hour live Delphi and C++ Webinars!
This webinars are highly interactive, you can contact the presenters by e-mail, skype etc.

Starting 6 nov. - 17 november.
For details check out the Borland Developer Network.

Thursday, November 02, 2006

The bug by accident #2

OK, you think you found a bug, you report it very carefully in Quality Central and write something about in a blogpost, all because of the fact that the bug was caused accidentally.

After that you expect some confirmation of people who encounter the same problem. It happens that no one else so far, including some coworkers can reproduce this bug.
Huh, time to investigate some more. For those who did not read the blogpost, the bug happens when you type, or paste, the string =: in a class definition. Memory is freaking out upto 1,9GB.

Investigate
Looking more carefully to the Windows Taskbar it appeared that 1,9GB is used by Windows, but only 15MB by BDS.exe. No other processes use even more memory then BDS, where did approx. 1GB memory go???
As someone suggested I did stop the Error Insight feature but had no luck, the bug is still there.

The solution
After turning off most of the BDS features the problem still persisted, and I asked myself why to put so much effort in a bug, which only happens by accident.
Anyway I found the part that causes the problem : Castalia 4 BE.
After turning off the 'Enable Delphi parser'  option the bug was gone.

Conclusion
This bug is caused by Castalia in combination with BDS. QC Report updated. (Pooh it isn't me :-) )
Can someone please confirm this? (After confirmation I will drop an email to Castalia about this problem)
What is causing the huge amount of memory while no process owns it?

Well all this trouble for a bug which was not meant to be a bug...

The bug by accident

Today I encounterd, by accident, a 'bug' in Borland Developer Studio using the Delphi personality. I do quote the bug here, because actually it is not a bug, but on the other hand it is a bug. (How about confusion)

Accidently I pasted a string in de class definition of a form. The pasted string happened to be part of a query with a parameter in it.

"WHERE somefield =: SomValue "

After this BDS increased its memory usage upto 1,9GB!
This is definitly a bug, but what is the chance that you encounter this bug?
Actually almost zero. I mean who types a '=:' in a class definition? Well ahum I do.

I assumed this bug has something to do with Error insight, so I reported it in Quality Central where you can find in under QC36020.

Main issue here: Is a bug a bug until he (or she) is discovered?

Go try it yourself!

Steps to reproduce:
1. Start BDS2006
2. Create a new VCL application
3. Type =: in, for example, the private section of the TForm class definition