Wednesday 10 December 2008

CodeRage 3

CodeRage 3 seems to have gone pretty well judging by those who were involved with it. I'm pleased, it's good that CodeGear/Embarcadero does this because it shows that they're focusing their mind on the developers (and possibly trying to showcase for potential new customers).

There will always be an argument between real vs virtual conferences and I don't want to restart that one off again. Real ones cost money for both the host and the delegate, but you get face-to-face contact and a feeling of something good happening. Virtual conferences are free (at least to us, the attendee), allow us to attend without having to travel to different countries. For me, I simply couldn't travel to the States every year to attend a CodeGear conference (no matter how much I wanted to) so it's a viable alternative.

For me though, it seems to have had some backwards steps this year. Firstly, and I'm not the first to bring this up, the registration process was much more awkward. And I think that's being kind.

Last year, I had a good timetable of talks and rooms, and could register for each session individually. I knew what was coming, when it was and how to see it.

This year, the agenda was vague. "Day 1 Morning, Room 1". And the registration details were for the whole morning, not just for individual sessions. This made it harder to know when I should be attending the session I wanted to see.

So I thought I'd register for all sessions, that way I'm covered. I downloaded the iCalendar file from the registration page and it practically block-booked me out for the entire week. Totally ridiculous. I ended up having to go through all the calendar entries and put them into one per day, amending the notes so that I had all the registration details for all the rooms at all parts of the day. In the end, it was next to useless.

To the point where I stopped bothering trying to attend. Partly because I'm flat out at work and the conference came second best. Not CodeGear's fault, this is the downside of the virtual conference - it's too easy to get distracted. But partly because I ended up thinking "I'll just download the sessions later and watch them when I want".

I've been trying for 2 days to download just one session from the CodeRage downloads page, but every attempt fails with an error about the connection with the server being reset.
So close, 82%!

Last year I'm sure these were available to download by FTP which is much more reliable.

I rarely but in a bad word about CG but I'm disappointed with the organisation of the event this year, although once (if) I finally get the sessions downloaded, I'm sure I won't be disappointed by the quality of the speakers.

Tuesday 5 August 2008

Delphi 2009 Sneak Peek Videos

I've just watched Nick Hodges go through some of the VCL enhancements for Delphi 2009, and two things struck me.

Firstly, I can't understand why the PasswordChar feature on TEdit was being demonstrated; I was running Delphi 6 side-by-side with the video, and was changing this property with the same results. So why is this being advertised as a VCL enhancement when, if I recall correctly, it's been there since Delphi 1.

The other thing is how many of these new controls are similar to the Raize Controls, especially the TButton with images from an imagelist (TRzBitBtn), the TButtonEdit with 2 buttons in the edit control (TRzButtonEdit) and the group bar (TRzGroupBar).

That said, it's nice to have these as standard components, and if I do move to Delphi 2009 then I'd have to think twice about renewing my Raize Components.

Tuesday 3 June 2008

Code: Speed vs Aesthetics

In our drive to produce the fastest, most optimised code out there, sometimes we can leave ourselves with a sprawl of code that no one else is going to be able to follow - or quite possibly you may not be able to follow a few months down the line, even though you wrote it!

I'm not talking about real down-to-the-core assembler or machine code here, just general high-level code that you might look at and think "I could rewrite that so it was a little bit faster", but ultimately leave it much less readable and maintainable for the future.

Take, for example, a reasonably new feature that Digital Metaphors added to its ReportBuilder product a while back: SQLBuilder. As I mentioned back in June last year:

Once you have built up your query (using either the standard Query Wizard or Designer, or your own custom Query Wizard or Designer), you can then access the query as an object. And each part of that query is an object too, so you have the Criteria object and the Join object, etc. You can access this at run-time so you can amend the query to suit your needs just before the report runs


This has always been available using the QueryDataView object, with which you can add and remove tables, fields, joins, etc, in Delphi code without actually touching the underlying query. No need to know which flavour of SQL you're using, or having to find the ORDER BY line to insert a new WHERE criteria above it. Anyway, I'm repeating myself. The point is, you can do this using this object and it's simple but takes a little effort to get to the objects:


function TmyJoinBuilder.GetQueryDataView(aReport: TppReport; var aDataView: TdaQueryDataView): Boolean;
var
lDataModule: TdaDataModule;
begin
aDataView := nil;

{get the datamodule}
lDataModule := daGetDataModule(aReport);

{get the query dataview}
if (lDataModule <> nil) then
if (lDataModule.DataViewCount > 0) then
aDataView := TdaQueryDataView(lDataModule.DataViews[0]);

Result := (aDataView <> nil);
end;


This just to get the QueryDataView object. When SQLBuilder was added, this became a little easier:

lSQLBuilder := TdaSQLBuilder.Create(aReport);


and the code to add a new table and join to the query went from this:


procedure TmyJoinBuilder.Add(aReport: TppReport; const aTableName1, aTableName2, aFieldName1, aFieldName2: String; aJoinType: TdaJoinOperatorType);
var
i: Integer;
lQueryDataView: TdaQueryDataView;
lSQL: TdaSQL;
lMainTable: TdaTable;
lNewTable: TdaTable;
begin
{get the query dataview for this report}
GetQueryDataView(aReport, lQueryDataView);

{get the TdaSQL object}
lSQL := lQueryDataView.SQL;

{get the main table}
lMainTable := GetTable(lSQL, aTableName1);

if (lMainTable <> nil) then
begin
lNewTable := GetTable(lSQL, aTableName2);
if (lNewTable = nil) then
begin
lNewTable := lSQL.AddTable(aTableName2);
end;

{add the table join}
if not (DoesJoinExist(lMainTable, lNewTable, aFieldName1, aFieldName2, aJoinType)) then
begin
lNewTable.AddTableJoin(lMainTable, aFieldName1, aFieldName2, aJoinType);

{call out of sync to ensure the sql result is refreshed}
lQueryDataView.OutOfSync;
end;
end;
end;


to this:


lSQLBuilder.SelectTables.AddJoin(lNewTable, lMainTable, 'Field_name', '=', 'Join_to_field_name');


Now I know that what ReportBuilder is doing is actually wrapping all of the long code into one method call for me, and possibly doing a little bit more than I am doing as well in order to be robust. But the readability and maintainability of my code has now increased beyond what speed impact there might be. (For the record, I haven't noticed any, but we're not doing lightning fast mathematical wizardry here in which every millisecond counts).

Sometimes you even know that doing it the short way means some lower-level code is called multiple times. But isn't the end result more pleasing than the speed offset?

Thursday 24 January 2008

Real-world tools #6: Raize Components

Despite the claims that I don't like to have reams of different component packs installed in Delphi, there is often a case that a particular component set just has that killer component that demands its use. I've been aware of Raize Components for years but never made the leap of using them because I'd committed myself to TMS and JEDI, and that was enough for me.

Late last year, I attended a UK Developer's Group workshop with Ray Konopka, on UI design. It was an excellent couple of days and Ray, as I've seen him do in conference presentations, managed to not so subtley slip in references in Raize Components and CodeSite. And now I can see why... I was about the only one in the room that wasn't using Raize Components, and now I am converted.

So why take the decision to add yet another component set? Well, it was a trade-off for me. If Raize Components could do everything that I was using from an existing component pack, then I'd go with it. So I trialled it and two things stood out for me.

1. The TRzBitBtn supports XP/Vista themes where appropriate and uses the ImageList for its image property, not the Glyph property. This meant that I could use it to replace the TJvImgBtn from the JVCL, which frankly was the only component I was using from it regularly.

In fact, almost every component supports XP/Vista themes, and almost everything has the ability to use system colours, Office colours or custom gradients. The results are stunning. TMS offer this with their AdvOffice components too but I've had issues with it on Delphi 6 and Bruno told me in an email that they were looking to drop support for Delphi 6, and so they weren't going to be resolved for me. (But rest assured, the Styler mechanism in TMS is absolutely brilliant and a doddle to set up).

2. Almost every visual Raize control has a Transparent property. This is exactly what I have been looking for, for some time now, as we move into form design with gradient colours. Having a transparent panel, page control, group box, radio group box, etc, means that I can use gradient colours on a form and still have groups & panels.

Once I'd seen those two I was convinced, but it got better. The RzToolBar & RzPageControl replacements are so far superior to the standard VCL controls (and solve all the bugs I was having with those controls, which are just wrappers of the Windows Common Controls); the design-time editors that are installed as part of the Raize Component pack are so helpful that when you use an IDE that doesn't have them, you're left frustrated; and the edit boxes with the buttons actually as part of them mean that I no longer have to have a separate edit box and BitBtn next to it.

I could go on and there are similar components out there in other component packs, but what makes the difference is the standard way they look and behave, and the superb documentation that is lacking from almost all other third-party packs out there.

So JEDI has almost gone for me. With all due respect to the JEDI developers, who put in so much time and good, hard work, but there's just too many components for me to handle, and they're all a little bit different because of the nature of the open-source community. I say almost gone, because there are a few components that are actually irreplaceable, like the TJvWizard. Once you've used it, you'll never go back to a form with a PageControl on it.

What I also like about the Raize Components is that they are simple to upgrade. When a new release comes out, I don't even have to uninstall packages or worry about losing settings; the installer just works, updates my files and allows me to fire up Delphi and move on. Which takes the headache out of getting the latest version.

Ray takes what he talks about in his UI Design talk and implements it into a quality product, that adheres to his design principles and offers you controls that behave as you'd expect them to. And as Ray himself says, that's rule #1 of good UI design: it behaves as the user expects it to.